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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 06:34:56