I have a geodataframe of edges that are returned from OSMNX:
import osmnx as ox
# Getting graph for specific road
cf = '["highway"!~"motorway"]["ref"~"TF-563"]'
G = ox.graph_from_place('Tenerife, Spain', network_type='walk', simplify=False, custom_filter=cf)
# Adding length weights
G = ox.distance.add_edge_lengths(G)
# Getting nodes and edges of graph
nodes, edges = ox.convert.graph_to_gdfs(G, nodes=True)
This gives a geometry column where each row contains a Linestring. What I want is to have a one long Linestring that is ordered correctly, so I could make a plot that resembles ``` edges.plot()`` where all the linestrings plot contiguously.`
I use the following to create a multilinestring:
multi_line = geometry.MultiLineString(list(edges['geometry']))
But when I plot it things look a mess, which I assume is because the order of the linestrings in the edges
geodataframe are not ordered and therefore the linestrings are connecting randomly.
m = folium.Map(location=[28.105040, -16.610664], zoom_start=15)
# Extract coordinates from MultiLineString
def get_coordinates(multi_line):
all_coords = []
for line in multi_line.geoms:
all_coords.extend(list(line.coords))
return all_coords
# Get the coordinates
coordinates = get_coordinates(multi_line)
# Add the coordinates as PolyLines
folium.PolyLine([(coord[1], coord[0]) for coord in coordinates], color="blue").add_to(m)
m
Does anyone know if there's a way to order the geometry of edges returned by OSMNX, or is there another reason why I'm seeing this issue?
Unless you really need one single PolyLine
, one option would be to reindex
the edges :
extremities = [n for n, d in G.in_degree() if d == 1] # must be exactly 2 !
route = [(u,v) for u,v,*_ in list(nx.all_simple_edge_paths(G, *extremities))[0]]
# this requires geopandas>=1.0.0
single_ls = (
edges.droplevel(2).reindex(route)
.dissolve().geometry.line_merge().squeeze()
)
# otherwise, use from shapely.ops import linemerge
# single_ls = (
# linemerge(
# edges.droplevel(2).reindex(route)
# .dissolve().geometry.squeeze()
# )
# )
m = folium.Map(location=[28.105040, -16.610664], zoom_start=15)
folium.PolyLine(
[(coord[1], coord[0]) for coord in single_ls.coords],
color="blue",
).add_to(m)
Otherwise, you can simply explore
both nodes/edges:
m = edges.explore(
style_kwds=dict(weight=5, color="black"),
location=[28.11114, -16.61616],
zoom_start=16,
)
m = nodes.explore(
m=m,
marker_type="circle_marker",
marker_kwds=dict(radius=5),
style_kwds=dict(fillColor="cyan", color="black"),
)
Output (m
) :