OSMnx中ox.shortest_path返回None的问题排查与方案咨询
问题描述
使用OSMnx计算两点间最短路径时,ox.shortest_path()无法获取路径并返回None
坐标信息:origin_lat=42.482, origin_lon=-70.910, dest_lat=42.472, dest_lon=-70.957
查询的两点距离适中,且两地间存在清晰路网,OSM网页端可正常规划路径。
咨询问题
- 该问题的根本原因是什么?
- 如何预防此类问题发生?
- 若部分场景无法避免,有哪些备用/替代方案保证代码输出合理路径/距离?
最小复现示例
from shapely.geometry import Polygon import osmnx as ox region_bounds = [ [42.49897315546415, -70.97752844338558], [42.497310679689555, -70.89216747227316], [42.45989329011355, -70.90617955621047], [42.457041524105065, -70.97768950182164], ] region_bounds.append(region_bounds[-1]) region_polygon = Polygon([bounds[::-1] for bounds in region_bounds]) mode = "drive" G = ox.graph_from_polygon(polygon=region_polygon, network_type=mode) G = ox.add_edge_speeds(G) G = ox.add_edge_travel_times(G) origin_lat = 42.482 origin_lon = -70.910 dest_lat = 42.472 dest_lon = -70.957 origin_nodes = ox.distance.nearest_nodes(G, origin_lon, origin_lat) dest_nodes = ox.distance.nearest_nodes(G, dest_lon, dest_lat) routes = ox.shortest_path(G, origin_nodes, dest_nodes) print(origin_nodes, dest_nodes, routes)
输出结果为68758830 65236189 None,说明ox.distance.nearest_nodes找到有效起点和终点节点,但ox.shortest_path执行失败。
预期行为
调整起点坐标为:
origin_lat = 42.452 origin_lon = -70.910 dest_lat = 42.472 dest_lon = -70.957
代码可正常返回有效路径:
68754328 65236189 [68754328, 68752028, 68757205, 68766524, 68769796, 68777219, 68761577, 68759405, 68766786, 68747897, 68755811, 68764727, 68765868, 68755029, 2041487395, 2041487385, 68758705, 68771074, 68751303, 68770735, 68747441, 65186124, 65232064, 65258971, 65258184, 65198797, 65243553, 2041154812, 65261211, 65218821, 65210373, 65208978, 65255290, 65231546, 65190866, 65226679, 65193542, 65239462, 65225225, 2041270157, 65257919, 65186045, 2041270160, 65262590, 2041270186, 65252676, 65232296, 65242158, 65261501, 65221801, 65251183, 65190759, 65218681, 65222417, 2043144587, 65250858, 2043144592, 65247406, 65224701, 65231219, 65202428, 65242218, 65235268, 65197313, 65240735, 65207550, 2045575158, 65227845, 65229809, 65190291, 65217006, 2045610191, 9966458026, 65195913, 65214016, 65241686, 65240704, 65202519, 65201239, 65242936, 65233288, 65186829, 65199167, 65239099, 65242030, 65237992, 65236189]
问题解答
1. 根本原因
- 路网连通性断裂:提取的多边形区域内,起点节点
68758830和终点节点65236189分属两个不连通的子图。可能是道路属性(单行道、封闭路段)或OSM数据标记问题导致路段不连通,也可能是多边形边界截断了关键连通道路。 - 提取范围局限性:OSM网页端使用的是全局完整路网,而你定义的多边形区域过小,刚好漏掉了连接两个节点的必要路段,导致本地路网不连通。
2. 预防方案
- 扩大提取区域:给原多边形边界增加适当缓冲(比如经纬度各扩展0.01~0.02),确保覆盖起点到终点之间所有可能的连通道路,避免截断关键路段。
- 保留最大连通子图:提取路网后,使用
G = ox.get_largest_component(G, strongly=True)(针对驾车这类有向路网)只保留最大的连通子图,剔除孤立的小区域节点。 - 提前验证连通性:调用
shortest_path前,用nx.has_path(G, origin_nodes, dest_nodes)判断两个节点是否连通,提前发现问题并处理。
3. 备用/替代方案
- 切换更大范围路网:改用
ox.graph_from_bbox或ox.graph_from_place提取更大范围的路网,确保覆盖完整路径。 - 多模式路径备选:如果驾车路网不连通,尝试切换网络类型为
"bike"或"walk",这类路网连通性通常更好,可作为备用路径方案。 - 直线距离保底:当无法找到路径时,计算两点间的球面距离(Haversine公式)作为保底输出,避免返回
None,示例代码:
from math import radians, sin, cos, sqrt, atan2 def haversine(lat1, lon1, lat2, lon2): R = 6371.0 # 地球半径,单位公里 lat1_rad = radians(lat1) lon1_rad = radians(lon1) lat2_rad = radians(lat2) lon2_rad = radians(lon2) dlon = lon2_rad - lon1_rad dlat = lat2_rad - lat1_rad a = sin(dlat / 2)**2 + cos(lat1_rad) * cos(lat2_rad) * sin(dlon / 2)**2 c = 2 * atan2(sqrt(a), sqrt(1 - a)) return R * c # 无路径时返回直线距离 if not routes: dist = haversine(origin_lat, origin_lon, dest_lat, dest_lon) print(f"无有效驾车路径,两点直线距离为{dist:.2f}公里")
- 调整路径权重参数:调用
ox.shortest_path时指定weight="length",尝试基于距离而非旅行时间计算路径,排查是否是权重计算导致的问题。
内容的提问来源于stack exchange,提问作者xushen0118
相关产品推荐
相关产品推荐

