如何通过OpenStreetMapX.jl获取路段距离、通行时间与道路等级?
问题描述
使用OpenStreetMapX.jl包查询OpenStreetMap导出的路网边信息时,发现部分功能没有直接提供:现有格式为Vector{Tuple{Int64, Int64}}的路段集合,需要批量获取各路段的距离、通行时间与道路等级。
目前已知单条边的距离可以通过逐点传入节点的方式查询,示例代码如下:
Links = [(301972446, 60649731) (60649731, 301972446) (2505989518, 2489651510) (2489651510, 60649731) (60649731, 301972503) (267224410, 2895172669) (2895172669, 267224410) (582794232, 582794289)] # 查询Links集合中第一条边的距离示例 distance(map.nodes[links[1][1]],map.nodes[links[1][2]] )
这种查询方式效率很低,期望能有直接返回各边距离、通行时间、道路等级的方法,支持如下调用形式:
distance( (582794232, 582794289)) distance( links[1]) time(links[1]) class(links[1])
解决方案
OpenStreetMapX.jl解析完地图后,所有边的属性已经预加载到map.edges邻接结构中,不需要逐节点传入坐标实时计算,直接通过边的首尾节点ID索引即可,查询效率远高于逐点计算。
三个属性的对应字段和调用扩展方式如下:
- 距离:边的实际路网行驶距离(非两点直线欧氏距离)存储在
map.edges[from, to].dist字段,单位为米。可以直接扩展包内的distance方法支持元组入参:
# 扩展distance方法,支持直接传入(Int, Int)格式的边元组 OpenStreetMapX.distance(edge::Tuple{Int64, Int64}) = map.edges[edge...].dist
- 通行时间:包内根据道路等级限速预计算的通行时间存储在
map.edges[from, to].time字段,单位为秒。新增对应方法即可支持元组调用:
# 新增通行时间查询方法 time(edge::Tuple{Int64, Int64}) = map.edges[edge...].time
- 道路等级:对应OpenStreetMap道路分类的等级字段存储在
map.edges[from, to].class,返回值为包内定义的道路类型枚举。新增查询方法:
# 新增道路等级查询方法 class(edge::Tuple{Int64, Int64}) = map.edges[edge...].class
注意:OpenStreetMapX.jl存储的路网为有向图,双向通行道路会存储两条方向相反的边,和示例Links集合中成对出现的双向元组逻辑一致,索引时首尾节点顺序不能颠倒,否则会触发键不存在的错误。
批量查询整个Links集合的属性时,直接用Julia的广播语法即可,比如distance.(Links)会一次性返回所有边的距离数组,全程是内存索引操作,没有实时计算开销,效率比逐节点计算高两个数量级以上。
另外需要注意,示例中使用的distance(nodeA, nodeB)方法计算的是两个节点间的直线欧氏距离,不是沿道路的实际行驶距离,做路径分析相关计算时应当使用edges结构中存储的dist字段值。
内容的提问来源于stack exchange,提问作者Hemfri
相关产品推荐
相关产品推荐

