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

如何判断Shapely点是否属于NetworkX生成的亚琛步行最短路径

问题

我需要判断一个Shapely Point是否属于通过NetworkX的shortest_path()函数获取的德国亚琛市步行最短路径。路径起点为Node 7192074686,终点为Node 32885719。2022年,在Jülicher Straße / Lombardenstraße / Dennewartstraße的人行横道(POINT (10.77901 53.90290),WSG84坐标系)发生一起事故。

当前我的思路是查找该点的最近节点,再计算其与nx.shortest_path()返回的路径中各节点的距离,但由于节点并非完全匹配,需要设置阈值,这带来两个问题:

  • a) 阈值该如何设定?这取决于网络中节点的密度;
  • b) 路径中的多个节点可能对应同一事故点。

现有获取网络并计算最短路径的代码:

import networkx as nx
import osmnx as ox

# 获取原始路网
network = ox.graph_from_place("Aachen, Germany", network_type="walk")

# 设置起点和终点节点
start_node = 7192074686
end_node = 32885719

# 计算最短路径
path_nodes = nx.shortest_path(G=network, source=start_node, end=end_node, weight="length")
解决方案

核心思路:直接检查点是否在路径的道路边线上

比起匹配节点,直接判断事故点是否落在路径的道路边线(而非节点)上更贴合实际场景——事故发生在人行横道,属于道路路段,不一定正好对应路网节点。以下是具体实现步骤:

1. 提取路径对应的道路边线几何

先将路径节点列表转换为路径包含的边,再提取每条边的Shapely几何对象:

import shapely.geometry as sg

# 从路径节点生成连续的边对
path_edges = list(zip(path_nodes[:-1], path_nodes[1:]))

# 提取每条边的几何并转为Shapely LineString
path_line_strings = []
for u, v in path_edges:
    # 兼容OSMnx路网的双向边情况
    if (u, v) in network.edges:
        edge_data = network.edges[u, v, 0]
    else:
        edge_data = network.edges[v, u, 0]
    geom = sg.shape(edge_data['geometry'])
    path_line_strings.append(geom)

2. 带缓冲阈值判断点是否在路径上

考虑到GPS数据存在误差,我们可以给道路边线加一个小缓冲(根据精度调整),再判断事故点是否在缓冲区内:

# 定义事故点(WSG84坐标系)
accident_point = sg.Point(10.77901, 53.90290)

# 转换为UTM坐标系(解决经纬度无法直接用米做缓冲的问题)
utm_crs = ox.utils_geo.project_geometry(accident_point, crs="EPSG:4326").crs
accident_point_utm = accident_point.transform(utm_crs)
path_line_strings_utm = [line.transform(utm_crs) for line in path_line_strings]

# 设置缓冲距离(民用GPS精度一般1-3米,这里取0.5米)
buffer_distance = 0.5

# 遍历路径边线检查
is_on_path = False
for line in path_line_strings_utm:
    if line.buffer(buffer_distance).contains(accident_point_utm):
        is_on_path = True
        print("事故点在路径上")
        break

if not is_on_path:
    print("事故点不在路径上")

解决你提出的两个问题

  • 阈值设定:缓冲距离根据GPS数据精度确定,民用GPS设0.5-2米即可,高精度RTK数据可缩小到0.1米,无需依赖节点密度。
  • 多节点对应同一点:直接判断点与道路边线的关系,无需考虑路径节点数量,只要点在某段路径边的缓冲区内,就判定为在路径上。

高效备选方案:匹配最近边

如果路径较长,遍历所有边效率低,可先找到事故点的最近边,再检查该边是否属于路径:

# 获取事故点的最近边及距离
nearest_edge, dist_to_edge = ox.get_nearest_edge(network, accident_point, return_dist=True)
nearest_u, nearest_v, _ = nearest_edge

# 检查最近边是否在路径边列表中(兼容双向边)
edge_in_path = ((nearest_u, nearest_v) in path_edges) or ((nearest_v, nearest_u) in path_edges)

# 结合距离阈值判断
if edge_in_path and dist_to_edge < 0.5:
    print("事故点在路径上")
else:
    print("事故点不在路径上")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:10:14