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

如何用OSMnx正确投影GPS坐标?解决投影后节点匹配问题

OSMnx投影路网后匹配GPS点到最近节点的解决方案

问题描述

我正在用osmnx对法国安纳西(Annecy)建模,测试开发最短路径算法。为了获取正确的距离,必须使用ox.project_graph对路网图进行投影,但投影后无法找到城市边界内任意GPS点对应的最近节点。

核心疑问:有没有单独投影单个坐标点的方法?

问题根源:原始图的坐标是经纬度(WGS84,EPSG:4326),投影后的图坐标数值完全不同,但找不到单独转换GPS点坐标的方法,导致用原始经纬度去投影后的图里找最近节点时出错,得到错误的路径结果。


原始未投影图的最短路径代码(正常运行)

import osmnx as ox
import networkx as nx

graphe_ville = ox.graph.graph_from_bbox(45.949160, 45.868544, 6.176136, 6.071052, network_type='drive', simplify=True, truncate_by_edge=False, clean_periphery =True)

graphe_ville = ox.add_edge_speeds(graphe_ville)
graphe_ville = ox.add_edge_travel_times(graphe_ville)


x_start, y_start = (6.148903, 45.909408)
x_arrival, y_arrival  = (6.127705, 45.905936)

Start = ox.distance.nearest_nodes(graphe_ville, x_start, y_start)
Arrival = ox.distance.nearest_nodes(graphe_ville, x_arrival, y_arrival)

path = nx.dijkstra_path(graphe_ville,Start,Arrival)

fig, ax = ox.plot_graph_route(graphe_ville, path, route_linewidth=4,node_size=1, figsize=(7,7), bgcolor='#FFFFFF', node_color='#111111')

运行效果:
原始图


投影后获取正确距离的代码

import osmnx as ox
import networkx as nx

city_graph = ox.graph.graph_from_bbox(45.949160, 45.868544, 6.176136, 6.071052, network_type='drive', simplify=True, truncate_by_edge=False, clean_periphery =True)
city_graph = ox.project_graph(city_graph) # 获取正确距离
city_graph = ox.consolidate_intersections(city_graph, rebuild_graph=True, tolerance=15, dead_ends=True) # 简化节点(如环岛)

city_graph = ox.add_edge_speeds(city_graph)
city_graph = ox.add_edge_travel_times(city_graph)

fig, ax = ox.plot_graph(city_graph, figsize=(7,7), bgcolor='#FFFFFF', node_color='#111111')

运行效果:
简化图


投影后错误计算路径的代码及问题

在上述投影代码后添加以下代码计算同两点路径,会得到错误的路径结果:

x_start, y_start = (6.148903, 45.909408)
x_arrival, y_arrival  = (6.127705, 45.905936)

Start = ox.distance.nearest_nodes(graphe_ville, x_start, y_start)
Arrival = ox.distance.nearest_nodes(graphe_ville, x_arrival, y_arrival)

path = nx.dijkstra_path(graphe_ville,Start,Arrival)

fig, ax = ox.plot_graph_route(graphe_ville, path, route_linewidth=4,node_size=1, figsize=(7,7), bgcolor='#FFFFFF', node_color='#111111')

错误效果:
错误结果


解决方案

要解决这个问题,关键是把GPS经纬度点转换为和投影后路网一致的坐标系,具体步骤如下:

1. 获取投影坐标系信息

投影后的路网图会自带坐标系参数,通过city_graph.graph['crs']即可获取对应的pyproj.CRS对象。

2. 转换GPS点坐标到投影坐标系

使用pyproj的Transformer类,将WGS84经纬度转换为投影坐标系的坐标,再用转换后的坐标查找最近节点。完整示例代码如下:

import osmnx as ox
import networkx as nx
from pyproj import Transformer

# 加载并投影路网
city_graph = ox.graph.graph_from_bbox(45.949160, 45.868544, 6.176136, 6.071052, network_type='drive', simplify=True, truncate_by_edge=False, clean_periphery =True)
city_graph = ox.project_graph(city_graph)
city_graph = ox.consolidate_intersections(city_graph, rebuild_graph=True, tolerance=15, dead_ends=True)
city_graph = ox.add_edge_speeds(city_graph)
city_graph = ox.add_edge_travel_times(city_graph)

# 创建坐标系转换器:WGS84经纬度 -> 投影坐标系
crs_proj = city_graph.graph['crs']
crs_wgs84 = 'EPSG:4326'  # GPS经纬度对应的标准坐标系
transformer = Transformer.from_crs(crs_wgs84, crs_proj, always_xy=True)

# 转换目标GPS点坐标
x_start_wgs84, y_start_wgs84 = (6.148903, 45.909408)
x_arrival_wgs84, y_arrival_wgs84 = (6.127705, 45.905936)

x_start_proj, y_start_proj = transformer.transform(x_start_wgs84, y_start_wgs84)
x_arrival_proj, y_arrival_proj = transformer.transform(x_arrival_wgs84, y_arrival_wgs84)

# 查找投影路网中的最近节点
Start = ox.distance.nearest_nodes(city_graph, x_start_proj, y_start_proj)
Arrival = ox.distance.nearest_nodes(city_graph, x_arrival_proj, y_arrival_proj)

# 计算最短路径并绘图
path = nx.dijkstra_path(city_graph, Start, Arrival)
fig, ax = ox.plot_graph_route(city_graph, path, route_linewidth=4, node_size=1, figsize=(7,7), bgcolor='#FFFFFF', node_color='#111111')

关键注意事项

  • 必须设置always_xy=True,因为OSMnx始终使用x(经度)、y(纬度)的坐标顺序,和pyproj的默认顺序一致,避免坐标错位。
  • 查找最近节点时,务必使用投影后的图city_graph,而非原始未投影的图。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 12:37:56