2
votes

I want to generate a NetworKX graph with weighted edges so the weight of each edge will be its distance * driving speed on this road(if it exists) or if the driving speed is unknown, 100*distance for highways and 60*distance for city roads.

I couldn't find a post similar to my needs except this one but there has to be a way to do it automatically.

My goal is to find the path with the shortest time(with Dijkstra) of driving between point A to B and this is what I did until now:

l1 = (A_lat,A_lon)
G = ox.graph_from_point(l1,distance= 100)
l1_node_id = ox.get_nearest_node(G,l1)   # Find closest node ID    

l2 = (B_lat,B_lon)
G = ox.graph_from_point(l2,distance = 100)
l2_node_id = ox.get_nearest_node(G,l2)   # Find closest node ID

dist = vincenty(l1, l2).meters    # The distance between l1 and l2


p1 = ((l1[0] + l2[0])/2,(l1[1]+l2[1])/2)    #The mid point between l1 and l2
dist = vincenty(l1, l2).meters              #The distance between l1 and l2
G = ox.graph_from_point(p1,distance = dist)
path = nx.shortest_path(G, l1_node_id, l2_node_id)   #Find the shortest path for cutoff

for path in nx.all_simple_paths(G, source=l1_node_id, target=l2_node_id,cutoff = len(path)):
    #Here I want to checke if "path" is the shortest path but right now it is without weight

In the documentation they wrote weight should be a string but how can I do it?

TIA

2
It looks like you've named your weight attribute "distance". So you should use weight = 'distance'. That is you should use whatever you've named your attribute.Joel
In what function I did it? and I want the weight attribute will be distance * driving speed, so something has to be added for this attributeRoy Ancri
I guess you are using time of travel as weight. In that case, distance/speed is what you need.swatchai
Yes, that is what I looked forRoy Ancri

2 Answers

2
votes

Functionality to calculate edge travel times is available as of OSMnx v0.13.0. You can then use these edge travel time attributes to solve network shortest paths by travel time rather than distance. By default it imputes speed on edges missing maxspeed data from OSM, then calculates travel time as a function of length and speed. But you can pass in your own custom speeds for different road types:

import networkx as nx
import osmnx as ox
ox.config(use_cache=True, log_console=True)

G = ox.graph_from_place('Piedmont, CA, USA', network_type='drive')

# Impute speeds on edges missing data.
G = ox.add_edge_speeds(G)

# Or assign speeds to edges missing data based on dict values.
# For edges with highway type not in dict, impute speeds.
hwy_speeds = {'motorway': 100,
              'trunk': 100,
              'residential': 60,
              'tertiary': 60} #etc
G = ox.add_edge_speeds(G, hwy_speeds)

# Calculate shortest path by travel time.
G = ox.add_edge_travel_times(G)
orig, dest = list(G)[0], list(G)[-1]
route = nx.shortest_path(G, orig, dest, weight='travel_time')
1
votes
fast=['motorway','trunk','primary','secondary','motorway_link','trunk_link','primary_link','secondary_link','escape','track']
slow = ['tertiary', 'residential','tertiary_link','living_street']
other = ['unclassified','road','service']

def find_speed(row):
    if row['highway'] in fast:
        return 100/3.6
    elif row['highway'] in slow:
        return 50/3.6
    elif row['highway'] in other:
        return 70/3.6
    else:
        return 5/3.6


nodes, edges = ox.graph_to_gdfs(G)
edges = edges.assign(speed=edges.apply(find_speed, axis=1))
edges['wgt'] = edges['length']/edges['speed']

UG = ox.gdfs_to_graph(nodes, edges)


for path in nx.all_shortest_paths(UG, source=l1_node_id, target=l2_node_id,weight = 'wgt'):