You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对OSMNX返回的Edges GeoDataFrame中LineString几何要素排序

问题:按顺序合并OSMNX道路边为连续LineString

场景与问题

通过OSMNX获取特定道路的边GeoDataFrame后,直接合并为MultiLineString再用folium绘图时出现混乱,核心原因是edges中的LineString顺序无序,导致拼接时连接逻辑随机。

原始获取数据代码:

import osmnx as ox

# 获取特定道路的图
cf = '["highway"!~"motorway"]["ref"~"TF-563"]'
G = ox.graph_from_place('Tenerife, Spain', network_type='walk', simplify=False, custom_filter=cf)

# 添加长度权重
G = ox.distance.add_edge_lengths(G)

# 获取图的节点和边
nodes, edges = ox.convert.graph_to_gdfs(G, nodes=True)

解决方案:利用图的节点连接关系排序边

OSMNX的图结构中,每条边都包含起点(u)和终点(v)字段,我们可以通过节点的连通关系,将边按道路的实际走向排序,再合并为连续的LineString:

import networkx as nx
from shapely.ops import linemerge

# 找到道路的端点(度数为1的节点,适用于非环状道路)
start_node = [n for n in G.nodes if G.degree(n) == 1][0]
# 获取从端点出发的最长路径,对应整条道路的节点顺序
path = nx.dag_longest_path(G.reverse(), source=start_node)

# 根据路径节点对匹配并排序边的几何要素
ordered_geoms = []
for u, v in zip(path[:-1], path[1:]):
    # 优先匹配u->v方向的边
    edge_mask = (edges['u'] == u) & (edges['v'] == v)
    if edge_mask.any():
        geom = edges.loc[edge_mask, 'geometry'].iloc[0]
    else:
        # 若为反向边,匹配后反转坐标保证走向一致
        edge_mask = (edges['u'] == v) & (edges['v'] == u)
        geom = edges.loc[edge_mask, 'geometry'].iloc[0].reverse()
    ordered_geoms.append(geom)

# 合并排序后的LineString为连续的单条线
merged_line = linemerge(ordered_geoms)

用folium绘制连续道路

使用合并后的LineString绘图,即可得到和edges.plot()一致的连续效果:

import folium

m = folium.Map(location=[28.105040, -16.610664], zoom_start=15)
# 转换坐标为folium需要的(lat, lon)格式
coords = [(coord[1], coord[0]) for coord in merged_line.coords]
folium.PolyLine(coords, color="blue").add_to(m)
m

注意事项

  • 若道路是环状(无度数为1的节点),可随机选择一个节点作为起点,调整路径获取逻辑
  • shapely.ops.linemerge会自动处理相邻LineString的衔接,比手动拼接坐标更可靠

内容的提问来源于stack exchange,提问作者Ellio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 15:03:12