2

I'm a noob when it comes to networkx module. I have a line feature as a geodataframe that looks like this:

figure1

Using momepy, I can convert this geodataframe to a network on network x:

G = momepy.gdf_to_nx(my_line, approach="primal",length='mm_len')

This converts the geodataframe to a network that looks like this, with the blue points as the nodes created by momepy: https://i.sstatic.net/7Smb9.png

My aim is to find the pair of nodes that are furthest away from one another.

I can do this by this code:

apl = dict(nx.all_pairs_dijkstra_path(G))
bpl = [tuple((v, s, k)) for s, d in apl.items() for k, v in d.items() if v == max(d.values())]
bpl.sort(key=lambda tup: tup[0], reverse=False) 
length, start, fin = bpl[0]

However this works out the distances based on how many nodes the path goes through, not the actual length of the path. so returning 'length' just gets a list of coordinates. However I have no idea how to store the length of the path in the network. I want the data of the graph to be something like this:

figure1

So that when I run the Dijkstra it will return the top left node and the bottom node and say the distance between them is 21m, this is the longest. Any ideas?

3
  • It is a pure network problem and not a geospatial problem. You need to use all_pairs_dijkstra_path_length
    – gene
    Commented Jan 24 at 11:24
  • but how do I add a length feature to the graph itself? Do I define it as a weight? Because as I said if I run dijkstra it returns a list of coordinates, not a length. When you create a networkx graph manually with add_edges_from etc. you can add in attributes but I can't see an option for that when doing momepy.gdf_to_nx Commented Jan 24 at 11:39
  • Take a look at my answer
    – gene
    Commented Jan 24 at 12:29

1 Answer 1

1

The geometry and the properties of the GeoDataFrame are still present in the graph, you can see them in using data=True (and the length is 'mm_len') (see How to calculate edge length in Networkx)

With one of my shapefile

G = momepy.gdf_to_nx(df, approach="primal",length='mm_len')
G.edges()
MultiEdgeDataView([((166362.43059958215, 116180.34149187146), (166547.61246095796, 117903.66656916466)), ((165402.50829775655, 117317.8872117514), (166925.53462703104, 116758.56240596325)), ((165829.56034541913, 116044.28951208515), (166691.22288406573, 117121.3676853934)), ((165500.76806093557, 117627.78338793133), (165549.89794252507, 116887.0559424281))])
# but
G.edges(data=True)
MultiEdgeDataView([((166362.43059958215, 116180.34149187146), (166547.61246095796, 117903.66656916466), {'geometry': <shapely.geometry.linestring.LineString object at 0x1a352982e8>, 'mm_len': 2966.689088302621}), ((165402.50829775655, 117317.8872117514), (166925.53462703104, 116758.56240596325), {'geometry': <shapely.geometry.linestring.LineString object at 0x1a352988d0>, 'mm_len': 1622.6709776373805}), ((165829.56034541913, 116044.28951208515), (166691.22288406573, 117121.3676853934), {'geometry': <shapely.geometry.linestring.LineString object at 0x1a35298390>, 'mm_len': 1379.3330714239971}), ((165500.76806093557, 117627.78338793133), (165549.89794252507, 116887.0559424281), {'geometry': <shapely.geometry.linestring.LineString object at 0x1a35298828>, 'mm_len': 883.3292113713896})]

First edge of the graph:

first = list(G.edges(data=True))[0]

The two first elements of the resulting list are the nodes coordinates and the third is a is a dictionary

print(first[2]['mm_len'])
2966.689088302621

Therefore you can use

list(nx.all_pairs_dijkstra_path_length(G,weight='mm_len'))

For the first path

list(nx.all_pairs_dijkstra_path_length(G,weight='mm_len'))[0]
((166362.43059958215, 116180.34149187146), {(166362.43059958215, 116180.34149187146): 0, (166547.61246095796, 117903.66656916466): 2966.689088302621})
 #and the length is
 l = [x for x in list(nx.all_pairs_dijkstra_path_length(G,weight='mm_len'))[1][1].values()]
 print(l[1])
 2966.689088302621

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.