timegeocodingdriveosmnx

Python OSMNX: How to get more realistic speeds on edges?


I am trying to do some research based on driving time (e.g., how much time people are willing to drive from their residence for certain services...) However, the drive times that come out of osmnx are much faster than what is realistic. I think it is because it is defaulting to the maxspeed for each edge and not taking into account the stopping and starting that happens with intersections, etc. I was wondering if there is a way to assign a new speed to the edges where it adjusts for how long the edge is. So for city driving, even though the speed limit might be 30 mph, the average speed is much slower because of all the stopping and starting from of all the nodes/intersections that people have to go through.

So in short, can I apply custom speeds (a formula that uses maxspeed and edge length as inputs) that vary by the length of the edge? Or is there a better way to go about this?

When I compare this to google, the distance is pretty close but the time is way off (6 min vs 10-11 min in my example below).

Example:

import numpy as np
import osmnx as ox
import networkx as nx

G = ox.graph_from_address(
    "50 North Temple, Salt Lake City, UT 84150",
    dist=10000,
    network_type="drive",
    truncate_by_edge=True,
) 

G = ox.add_edge_speeds(G)
G = ox.add_edge_travel_times(G)
origin = (40.741630,-111.862470)
destination = (40.768860,-111.837560)
origin_node = ox.distance.nearest_nodes(G, origin[1], origin[0])
destination_node = ox.distance.nearest_nodes(G, destination[1], destination[0])
route = ox.shortest_path(G, origin_node, destination_node,weight="travel_time")
route_length = int(sum(ox.utils_graph.route_to_gdf(G, route, "length")["length"]))
route_time = int(sum(ox.utils_graph.route_to_gdf(G, route, "travel_time")["travel_time"]))
print("Route is", route_length/1609.34, "miles and takes", route_time/60, "minutes.")
fig, ax = ox.plot_graph_route(G, route, route_color="c", node_size=0)

Solution

  • I have a similar app and I loop through the nodes of a calculated route, adding a time penalty for each stop sign and traffic light that is encountered along the route.

            route = nx.shortest_path(G, start_node, destination_node, weight=weight) # Returns a list of nodes comprising the route, weighted according to the parameter weight
    
        # Experimental code to add delays for traffic signals and stop signs
        traffic_signal_count = stop_sign_count = 0
        traffic_signal_delay = stop_sign_delay = 0
    
        # Loop through all the nodes of the route counting
        # the traffic signals and stop signs encountered
    
        for nodeid in route:
    
            node = G.nodes[nodeid]
            if 'highway' in node:
                nodehighway = node['highway']
                if nodehighway == 'traffic_signals':
                    traffic_signal_count += 1
                elif nodehighway == 'stop':
                    stop_sign_count += 1
                else:
                    pass
    
        # TODO: Make the delay factor configurable
        traffic_signal_delay = traffic_signal_count * 10   # 10 second delay
        stop_sign_delay = stop_sign_count * 20
    
        route_travel_time += ( traffic_signal_delay + stop_sign_delay )
    

    I have been considering submitting an enhancement request to OSMNX to add this as a configurable option as a suitable place in OSMNX.