标签:python networkx openstreetmap
OSMnx提供了计算两个节点之间最短路径的解决方案,但我想在街道上使用相同的点(我有从车辆记录的GPS坐标).我知道还有一种获取最近节点的方法,但我对这个问题有两个问题.
i)当计算出最近的节点时,还要考虑该点的街道? (我假设不是)
ii)如果我想实现这样的东西,我想知道街道(边缘)如何表示为曲线(Bézier曲线可能?).是否有可能得到边缘的曲线(或曲线的方程)?
我在这里问了这个问题,因为OSMnx的贡献指南问了这个问题.
解决方法:
OSMnx中的Streets和node是shapely.geometry.LineString和shapely.geometry.Point对象,因此没有曲线,只有坐标序列.您所描述的技术术语是地图匹配.有不同的地图匹配方法,最简单的方法是几何地图匹配,您可以在其中找到GPS点的最近几何(节点或边).使用内置的osmnx函数ox.get_nearest_node()可以轻松实现点对点映射匹配.如果你有一个豪华的密集GPS轨道,这种方法可以很好地工作.对于点到线地图匹配,您必须使用形状函数.这种方法的问题在于它非常慢.你可以使用空间索引来加速算法,但是,对于大多数用途来说,它还不够快.请注意,几何图匹配在所有方法中最不准确.几个星期前我写了一个函数,使用边缘GeoDataFrame和可以从OSMnx获得的节点GeoDataFrame进行简单的点到线匹配.我放弃了这个想法,现在我正在研究一种新算法(希望更快),我将在完成时在GitHub上发布.同时,这可能对您或其他人有所帮助,所以我在这里发布.这是废弃代码的早期版本,未经过充分测试且未经过优化.尝试一下,让我知道它是否适合你.
def GeoMM(traj, gdfn, gdfe):
"""
performs map matching on a given sequence of points
Parameters
----------
Returns
-------
list of tuples each containing timestamp, projected point to the line, the edge to which GPS point has been projected, the geometry of the edge))
"""
traj = pd.DataFrame(traj, columns=['timestamp', 'xy'])
traj['geom'] = traj.apply(lambda row: Point(row.xy), axis=1)
traj = gpd.GeoDataFrame(traj, geometry=traj['geom'], crs=EPSG3740)
traj.drop('geom', axis=1, inplace=True)
n_sindex = gdfn.sindex
res = []
for gps in traj.itertuples():
tm = gps[1]
p = gps[3]
circle = p.buffer(150)
possible_matches_index = list(n_sindex.intersection(circle.bounds))
possible_matches = gdfn.iloc[possible_matches_index]
precise_matches = possible_matches[possible_matches.intersects(circle)]
candidate_nodes = list(precise_matches.index)
candidate_edges = []
for nid in candidate_nodes:
candidate_edges.append(G.in_edges(nid))
candidate_edges.append(G.out_edges(nid))
candidate_edges = [item for sublist in candidate_edges for item in sublist]
dist = []
for edge in candidate_edges:
# get the geometry
ls = gdfe[(gdfe.u == edge[0]) & (gdfe.v == edge[1])].geometry
dist.append([ls.distance(p), edge, ls])
dist.sort()
true_edge = dist[0][1]
true_edge_geom = dist[0][2].item()
pp = true_edge_geom.interpolate(true_edge_geom.project(p)) # projected point
res.append((tm, pp, true_edge, true_edge_geom))
return res
标签:python,networkx,openstreetmap 来源: https://codeday.me/bug/20190701/1349328.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。