使用 OSMNX Nearest_edges 的结果不正确
Posted
技术标签:
【中文标题】使用 OSMNX Nearest_edges 的结果不正确【英文标题】:Incorrect results using OSMNX nearest_edges 【发布时间】:2021-12-18 23:44:12 【问题描述】:我正在编写一些代码,以根据所行驶给定路径的 GPS 数据从 OSM 获取道路中心线数据。我正在使用 OSMNX 与 OSM 数据交互,但在使用最近边缘将 GPS 数据从我的路径匹配到 OSM 数据时得到奇怪的结果。
这是输入路径(数据间距 enter image description here
这是使用nearest_edges 匹配后的路径: enter image description here
这是我用来生成这些结果的代码:
#!/usr/bin/python3
import osmnx as ox
import csv
import utm
from shapely.geometry import Point
import os
import simplekml
# get data from file
path = "C:\\Users\\nj5wdf\\OneDrive - Aptiv\\Projects\\Prodrive\\Curvature_Python\\tests\\"
filename = "map_provider_test_data.csv"
filename = os.path.join(path, filename)
with open(filename, 'r') as file:
# create csv reader object
data = list(csv.reader(file))
lat = []
lon = []
for row in data:
lat.append(float(row[0]))
lon.append(float(row[1]))
buffer = 0.002
north_lat = max(lat) + buffer
south_lat = min(lat) - buffer
east_lon = max(lon) + buffer
west_lon = min(lon) - buffer
# generate graph of all road networks within the bounding box
graph = ox.graph_from_bbox(
north_lat, south_lat, east_lon, west_lon,
network_type="drive",
simplify=True,
truncate_by_edge=True,
clean_periphery=True)
# convert input lat / lon to UTM
x = []
y = []
for _lat, _lon in zip(lat, lon):
_y, _x, _, _ = utm.from_latlon(_lat, _lon)
x.append(_x)
y.append(_y)
# get nearest edges
nodes, streets = ox.graph_to_gdfs(graph)
graph_proj = ox.project_graph(graph)
nearest = ox.nearest_edges(graph_proj, lon, lat)
# remove redundant edges from result
last_near = nearest[0]
reduced_nearest = []
for near in nearest:
if (near not in reduced_nearest) and (near[1] != last_near[0]):
reduced_nearest.append(near)
last_near = near
# get centerline points from nearest edges
centerline_points = []
for edge in reduced_nearest:
street_gdf = streets.loc[edge]['geometry']
lat_list = list(street_gdf.xy[1])
lon_list = list(street_gdf.xy[0])
[centerline_points.append(Point(_lat, _lon)) for _lat, _lon in zip(lat_list, lon_list)]
# instantiate simpleKml
kml = simplekml.Kml()
coords = zip(lon_list, lat_list)
# plot line
ls = kml.newlinestring(name="matched")
ls.coords = coords
ls.style.linestyle.width = 2
ls.style.linestyle.color = simplekml.Color.red
ls.altitudemode = simplekml.AltitudeMode.relativetoground
# save points to file
output_filename = "tests/map_provider_matched.kml"
kml.save(output_filename)
这是我正在使用的测试数据:test_data
关于如何获得更好性能的任何想法?我尝试使用不同的最近邻函数,但它的性能比 ox.nearest_edges 更差。
【问题讨论】:
你能提供一个完整但最小的示例代码sn-p来重现你的问题吗?目前您的代码不完整(其中包含未定义的变量,这些变量对于故障排除至关重要)也不是最小的(它包含与您关于最近边缘搜索的问题无关的其他几行)。 我编辑了上面的代码,使它更完整。我认为它尽可能小。我还附上了我正在使用的测试数据。感谢您的帮助! 许多变量仍未定义。您的示例需要是独立的、可复制粘贴运行的,以便其他人对其进行复制和故障排除。 感谢您的耐心等待。我更新了代码并且能够运行它。 看起来您只是在交换 x 和 y 坐标。经度是 x,纬度是 y,但你似乎把它颠倒过来了。 【参考方案1】:这里发生了很多事情。很难排除故障,因为您没有将其提炼成最小示例,而且您最初的问题陈述不是很具体:
我正在使用 OSMNX 与 OSM 数据交互,但在使用最近边缘将 GPS 数据从我的路径匹配到 OSM 数据时得到奇怪的结果。
我不知道“奇怪的结果”是什么意思,但我已经提炼(我相信你正在尝试做的事情)这里是一个看起来工作正常的最小示例。
import geopandas as gpd
import osmnx as ox
import pandas as pd
# load the points
cols = ['lat', 'lng', 'a', 'b', 'c', 'd', 'e']
df = pd.read_csv('map_provider_test_data.csv', names=cols)
# download the graph
center = df['lat'].mean(), df['lng'].mean()
G = ox.graph_from_point(center, dist=1500, network_type='drive', truncate_by_edge=True)
# project graph and points to same CRS
Gp = ox.project_graph(G)
geom = gpd.points_from_xy(df['lng'], df['lat'])
gdf = gpd.GeoDataFrame(df, geometry=geom, crs='epsg:4326').to_crs(Gp.graph['crs'])
# calculate nearest edge to each point
ne = ox.nearest_edges(Gp, X=gdf['geometry'].x, Y=gdf['geometry'].y)
您可以根据需要绘制此图,以查看这些点是否捕捉到正确的最近边缘:
unique_edges = set(ne)
ec = ['r' if e in unique_edges else '#666666' for e in G.edges]
fig, ax = ox.plot_graph(G, edge_color=ec, edge_linewidth=1, node_size=0, show=False)
ax = ax.scatter(df['lng'], df['lat'], c='y', s=5, zorder=-1)
您也可以在 GIS 中打开它并平移和滚动:最近的边缘搜索看起来一切正常。
【讨论】:
以上是关于使用 OSMNX Nearest_edges 的结果不正确的主要内容,如果未能解决你的问题,请参考以下文章
将本地 XML 或 Shapefile 加载到 OSMNX 以创建图形
Osmnx 错误:模块“osmnx.elevation”没有属性“add_node_elevations_raster”