本文将研究矢量地图以及A*算法等系统关键的技术支持。在实现的过程中,还引入了高德出行API、聚焦类爬虫、OpenStreetMap开源地图,二叉堆等技术。

通过解析OpenStreetMap提供的地图数据,获取不同类型的交通路网信息。然后将A*算法应用于路网数据中,并引入真实地理距离作为矢量地图的参数权重。最终找到两地之间的最短路径方案,成功的实现预期目标。

流程:

  1. 获取地图数据/路网数据化存储

  2. 不同路网数据获取(公共交通,机动车,自行车道,人行道....)

  3. 应用A*算法于地图中

地图路径规划的本质是遍历地图中的所有节点,然后找到最短路径的过程[8]。算法中的图是由大量节点和连接节点之间的线组成的。这里说的节点指的是现实生活中的每一个分叉路口,只要出现需要选择方向的时候,在地图上呈现的就是一个节点(vertices)[14]。而连接节点的线则是指现实生活中的道路,例如上海的南京西路,它在地图上的数据身份是一个边(edge)。每一条边都带有相对应的权重,即现实世界中的物理距离。图拥有两种类型,即有向图和无向图。有向图指的是带有方向的边,即a指向b的边和b指向a的边是两种不同的边。这两条边,在无向图中则是同一条边。

根据周小镜的描述,最短路径算法的基础是将图中的节点遍历[8]。由于实际路网的复杂性,节点的遍历有可能会出现从某一顶点选择一条边搜索后,该边又与带有该顶点的另一条边相交[8]。从而导致该顶点的重复遍历。因此在遍历地图的过程中,需要对已访问过的节点进行标记,以防重复遍历的出现[8]。

A*算法的关键在于启发函数,即F(n)=G(n)+H(n)。F(n)指代起始节点到目标节点的总代价。G(n)表示当前节点n到起始节点的当前代价。H(n)则表示当前节点n到目标节点的预估代价。依据这个函数,从而使得每一个被搜索的节点n都有一个总代价F(n)。然后选择其中最小的总代价节点作为下一步节点。接着继续计算新加入的节点的F(n),如此,循环。

1.获取地图数据/路网数据化存储

将实际路网信息变成节点和边的数据结构形式并存储。以上海市交通路网为例。首先,通过OpenStreetMap(OSM)提供的Overpass API Query Form获取XML格式的上海市交通路网的信息。

在该XML文件中,可以发现,地理数据的数据结构是带有拓扑性质的数据。地理信息系统的点,线,面以及它们之间的关系通过XML中node,way和relation进行分别描述。各自标签下的tag用于记录其标签的属性信息。

<node>标签记录路网节点信息,它包含经度和纬度,是<way>标签的组成部分。

<way>标签记录路的信息,是一个包含大量<nd>的集合。其属性包含街道,高速公路等信息。

<relation>标签将<way>和<node>结合在一起用于描述地理事物,例如公交路线和自行车道。

接着,使用ElementTree(元素树)方式对XML文件进行解析。该方式类似一种轻量级的DOM。相对于拥有大量函数的Simple API for XML(SAX)方法和需要将XML数据映射到内存中的树的Document Object Model(DOM)方法。ElementTree可以以更容易被理解的代码形式和更快的速度解析XML。通过ElementTree方法遍历获得搜索所有的<node>和<way>标签并定位。然后,导入Networkx库。下图展示的就是以实例化对象Map中的路网信息所绘制的SVG格式的上海市交通道路路网。

2.不同路网数据获取

OpenStreetMap提供的XML文件中包含了许多不同类型的道路信息,例如公共交通道路,机动车道路,自行车道路或人行道道路等等。

本段将基于OpenStreetMap提供的数据结构解析出公共交通路线数据。公共交通道路信息主要被存储与<relation>标签中,作为<relation>的子标签。图14中展示的是公共交通路网中某一个<relation>标签的数据结构。根据OSM的官方网站中提供的XML中<relation>标签的数据结构,图15展示的是其<tag>子标签的各类属性和值,图16展示的是其<member>子标签的各类属性和值。<member>标签中的“type”属性node和way分别表示节点和道路,“ref”表示对应的ID号,“role”表示对应的类型是站点或站台。<tag>标签中的“k”表示属性,“v”表示值。当k=“route”是,v中的值可以代表道路类型,即公交车,地铁,人行道,有轨电车,火车等等。通过定位不同的<tag>标签还可以解析获取线路的方向,站点名称等多样化的信息。

图14:

图15: OpenStreetMap官网上<relation>中<tag>属性值内容解析

图16: OpenStreetMap官网上<relation>中<member>属性值内容解析

解析公共交通路网数据的步骤如下。首先,需要确定当前标签记录的是道路信息,即<tag k=”type” v=”route”>。接着,确定道路的类型,公交,地铁,无轨电车和电车,即<tag k=”route” v=”bus/trolleybus/subway/tram”>。然后,收集<tag>标签中属性为“name”的值,以得到该条公共线路的起始站和终点站的站点信息。其次,遍历该<relation>标签下的<member>子标签中记录着way和node的ID信息并保存。最后,根据存储的ID信息获取对应的way和node的经度和纬度并存储。图17展示的是公共交通路网数据提取步骤的流程图。

TIP: 由于openstreetmap是一款国外的开源地图数据。因此国内路网数据上会存在一些缺失的现象,导致线路信息不完整。 例如,上海的公共交通线路数据,在openstreetmap中仅有少数线路。下图所示:

3.应用A*算法(A*算法应用于真实上海交通路网)

真实的交通路网地图区别于游戏中的栅格地图不同之处在于,真实的交通路网中的子节点扩展方式是找寻该父节点的最近直系节点,而不是节点的上下左右方位上的四个节点。它们之间的距离也不是固定为1,而是需要通过两节点的经度和纬度进行计算。

在寻找的过程中将使用韩忠民提供的两点的经纬度计算距离的近似公式[16]。假设有A, B两地,它们的纬度和经度分别是(lat1, lon1)和(lat2, lon2)。公式中S表示两地之间的距离(千米),a表示AB两地纬度之差(lat1-lat2),b表示AB两地经度之差(lon1-lon2),6378.137表示地球的半径(千米)。使用该公式计算出的距离精度和谷歌地图的距离精度误差在正负0.2米之内[16]。

然后,遍历地图中所有节点的经度和纬度。将其与起始地和目的地的经度和纬度进行距离计算,找出一定范围内的所有节点,并使用起始列表和目的列表分别保存被找到的节点的ID。接着,将起始列表中的所有节点于目的列表中的所有节点进行组合。两节点组合结果将作为Map对象中的起始节点和目的节点代入A*算法中。Map对象中的节点(node)间的地理距离也将使用韩忠民的距离近似函数进行计算,然后作为Map对象中边(edge)的权重。将节点组合代入A*算法中进行最优路径的寻找,如果不存在路径则会抛出异常。但如果两个节点列表中的所有节点组合的经度和纬度都不能通过A*算法找到它们之间的最优路径,则会扩大附近节点的搜索范围,每次增加10米。直到两个节点列表中出现可以找到最优路径的节点组合,搜索范围不再扩大,程序进入下一步运算。随后,将所有没有抛出异常的节点组合存放在字典中,并找到其中路径方案距离最小的节点组合。输出其节点组合中A*算法返回的字典回溯中的节点ID。将这些节点按照输出顺序进行连接,即可得到两节点之间的最短路径。

结束

最终测试:(图中显示的是整理过的路径规划数据,但后续还需再整理)

相比较高德地图app:

该项目的缺点:(亲自测试过的)

  • openstreetmap的数据不完整性。
  • 高德api存在的数据不确定性。
  • openstreetmap中的数据还需要进一步整理(当然了,按照上述方式10米10米的增加,可以解决部分路径规划问题。但这并不是真正的解决方案,具体请翻阅【陈舒燕. 基于OpenStreetMap的出行可达性分析与实现[D].上海师范大学,2010.】,上面有数据整理的方法。
  • 道路两节点之间取的是直线距离,未考虑道路弯曲的情况。

参考文献:

8. 周小镜. 基于改进A*算法的游戏地图寻径的研究[D].西南大学,2011.

14. 严寒冰,刘迎春.基于GIS的城市道路网最短路径算法探讨[J].计算机学报,2000(02):210-215.

16. 韩忠民.知经纬度计算两点精确距离[J].科技传播,2011(11):196+174.

真实地图最短路径规划(A*算法)相关推荐

  1. 【Matlab路径规划】蚁群算法机器人大规模栅格地图最短路径规划【含源码 1860期】

    一.代码运行视频(哔哩哔哩) [Matlab路径规划]蚁群算法机器人大规模栅格地图最短路径规划[含源码 1860期] 二.蚁群算法及栅格地图简介 随着机器人技术在诸多领域的应用, 如机器人协作焊接.灾 ...

  2. 【Matlab路径规划】蚁群算法求解机器人栅格地图最短路径规划问题【含源码 1580期】

    一.代码运行视频(哔哩哔哩) [Matlab路径规划]蚁群算法求解机器人栅格地图最短路径规划问题[含源码 1580期] 二.matlab版本及参考文献 1 matlab版本 2014a 2 参考文献 ...

  3. 【路径规划】基于matlab蚁群算法机器人栅格地图最短路径规划【含Matlab源码 119期】

    ⛄一.简介 路径规划是实现移动机器人自主导航的关键技术,是指在有障碍物的环境中,按照一定的评价标准(如距离.时间.能耗等),寻找到一条从起始点到目标点的无碰撞路径,这里选取最短距离路径规划的评价标准, ...

  4. 【路径规划】基于matlab蚁群算法机器人栅格地图最短路径规划【含Matlab源码 1580期】

    ⛄一.简介 路径规划是实现移动机器人自主导航的关键技术,是指在有障碍物的环境中,按照一定的评价标准(如距离.时间.能耗等),寻找到一条从起始点到目标点的无碰撞路径,这里选取最短距离路径规划的评价标准, ...

  5. 【路径规划】基于matlab蚁群算法机器人大规模栅格地图最短路径规划【含Matlab源码 1860期】

    ⛄一.蚁群算法及栅格地图简介 随着机器人技术在诸多领域的应用, 如机器人协作焊接.灾后搜救.军事.太空探索.深海勘探.家用和服务行业等, 机器人的发展正向智能化方向延伸, 要求其具有自组织.自学习.自 ...

  6. 【路径规划】基于matlab灰狼算法机器人栅格地图最短路径规划【含Matlab源码 2334期】

    ⛄一.灰狼算法的厂房巡检机器人路径规划简介 0 引言 近年来,我国各行各业的不断发展使相关工作流程得到了完善,其中巡检岗位是一个不可或缺的职位,尤其是在电厂.燃气厂房和煤矿等危险领域中的工作,更不能缺 ...

  7. 【路径规划】基于matlab蚁群优化遗传算法机器人栅格地图最短路径规划【含Matlab源码 1581期】

    ⛄一.简介 路径规划是实现移动机器人自主导航的关键技术,是指在有障碍物的环境中,按照一定的评价标准(如距离.时间.能耗等),寻找到一条从起始点到目标点的无碰撞路径,这里选取最短距离路径规划的评价标准, ...

  8. 【路径规划】基于matlab GUI蚁群算法机器人栅格地图最短路径规划【含Matlab源码 927期】

    ⛄一.蚁群算法简介 1 引言 在自然界中各种生物群体显现出来的智能近几十年来得到了学者们的广泛关注,学者们通过对简单生物体的群体行为进行模拟,进而提出了群智能算法.其中, 模拟蚁群觅食过程的蚁群优化算 ...

  9. 【路径规划】基于matlab蚁群算法机器人栅格地图最短路径规划【含Matlab源码 1618期】

    ⛄一.蚁群算法及栅格地图简介 1 蚁群算法 1.1 蚁群算法的提出 蚁群算法(ant colony optimization, ACO),又称蚂蚁算法,是一种用来寻找优化路径的机率型算法.它由Marc ...

最新文章

  1. 疯狂kotlin讲义连载之运算符和表达式——区间运算符
  2. Apache Kafka源码分析 – Log Management
  3. 语义分割中的深度学习方法全解:从FCN、SegNet到各版本DeepLab
  4. 嵌入式Linux驱动程序
  5. 一个自带简易数据集的模拟线性分类器matlab代码——实验训练
  6. EasyUI下拉框级联
  7. 前端基础-git(三):git和GitHub的一些基础操作
  8. 波士顿咨询评出全球50大最创新公司:华为位列第八
  9. 腾讯往事:微信其实就是第四代 QQ 邮箱
  10. 基于VUE2.0的分页插件
  11. 虚拟机无法将文件......DVD1.iso作为映像进行连接:找不到该文件
  12. 【find】Linux中find常见用法示例
  13. docker php 一键部署,Docker Compose 一键部署LNMP
  14. vue3结合element-plus实现标签手动标注效果
  15. python背单词小程序_微信小程序仿《乐词》背单词APP源码
  16. 什么叫单模光纤_单模光纤和多模光纤有什么区别
  17. HBuildX配置夜游神模拟器
  18. aliexpress商品详情API接口(速卖通商品详情页面数据接口)
  19. 史上最全的各种鱼的做法,爱吃鱼的可不要错过哦!
  20. Java实现第十届蓝桥杯最大降雨量

热门文章

  1. android高仿小米时钟,Android高仿小米时钟
  2. xrc C语言解释器
  3. LTP 依存句法分析
  4. 解决在英文版MSSQL中插入中文乱码的问题
  5. Neo4j:BBC冠军联赛图表
  6. 计算机系高考激励的句子,高考激励句子
  7. 蚂蚁金服如何开垦农村金融市场
  8. 汉语真奇妙:“吾”与“汝”
  9. Python爬取PPT模板(requests+BeautifulSoup+多线程)
  10. Linux VI文本编辑器