如何实现复杂的导航功能

本文要求读者具备如下知识和技术背景:

1 熟悉Java开发,知道如何正确的编译运行Java代码;

2 知道GIS的基本概念,知道地图导航的基本概念;

3 对GeoTools有一定的认识

一开始先来明确我们的任务:在基本的路径查询基础上

1 实现单行道限制

2 实现左右拐弯限制

3 实现动态路况限制

4 选择最短距离和最短时间

图和图的搜索

要想了解路径查询的算法,首先得了解一下它的数学模型“图”。简而言之,图就是一系列的点和点之间的连接关系。【Graph

所谓路径查询,可以简化成对一个图的搜索。例如:从点6到点1的最短路径是,6-4-5-1,或者6-4-3-2-1,又或者6-4-5-2-3-4-5-1。如你所见,从6到1之间可以有许多条路径,其中第一条和第二条我们认为是合理的,第三条是不合理的,因为它有重复路段。所以查询节点间路径的算法就显得至关重要了。经典的查询算法有:Dijkstra和它的改进版本A*。这两个算法的实现各种语言都有,也很成熟了,我们不需要自己去写,但是最为一种训练,有兴趣的读者可以自己试着实现。

我在这里只介绍一下基本概念。从前面的例子我们看到两点间可以有多条路径,但是实际上我们一般只关心一条路径,就拿开车来说,我们关心驾驶时间最少的路。一般情况下,实际距离短驾驶时间就少,所以我们先从实际距离入手。作为搜索算法如何确定距离最短呢。6-4-5-1一定比6-4-3-2-1距离短吗。显然我们不能仅仅根据节点的个数来判断距离。事实是我们除了拥有点和点之间的连接外,还需要连接的属性,这里就是距离。用上面的例子我们来指定距离:

6-4距离10

4-5距离7

5-1距离6

4-3距离2

3-2距离4

2-1距离1

6-4-5-1距离10+7+6=23

6-4-3-2-1距离10+2+4+1=17

显然第二条路虽然节点多但是距离短。这里需要引人一个概念“开销”,在这个例子中目前我们使用路径距离来代表开销。我们总是选择开销小的路径。现实中影响驾驶时间的因素除了距离还有道路拥堵情况,所以我们增加属性,叫拥堵系数,假设距离乘上系数才是我们需要的开销:

6-4距离10  拥堵1

4-5距离7   拥堵2

5-1距离6   拥堵1

4-3距离2   拥堵13

3-2距离4   拥堵11

2-1距离1  拥堵11

6-4-5-1距离10*1+7*2+6*1=30

6-4-3-2-1距离10*1+2*13+4*11+1*11=91

可以看到,虽然第二条路的实际距离短,但是由于拥堵情况严重,它的开销远大于第一条路。在这种情况下我们应该选择实际距离长的第一条路。我们可以不断对上面的计算进行完善,增加更多的属性来应对更复杂的实际情况。

分析任务

有了上面的知识我们来看看我们的任务:

1 实现单行道限制

我们可以给连接增加属性叫“行驶方向限制”,有三个值,分别是:“正向通行”,“反向通行”,“双向通行”。然后在计算开销的时候,判断当前方向是否与连接节点的方向一致,然后根据“行驶方向限制”的值来决定是否允许通行,如果不允许则返回一个极大值代表开销。

2 实现左右拐弯限制

在实现单行线的基础上就可以实现拐弯限制,但是需要在数据制作上做文章:

我们不能用一条线来代表一个路段,而应该用并行且方向相反的两条线,这样拐弯的地方也自然变成了单行线的一部分了。

3 实现动态路况限制

这个在上一节介绍图的时候已经说明了不在赘述。

4 选择最短距离和最短时间

这个在上一节介绍图的时候已经说明了不在赘述。

代码实现

代码  路网数据

改程序要求:

1 路网数据是Shapfile格式保存的线段数据

2 属性必须提供两个:

id  整数

type 整数  只有三个值 1:正向通行;-1:反向通行;0:双向通行

程序采用Java编写,利用GeoTools 11软件包中的graph扩展实现图的搜索。程序启动后需要先选择路网数据,然后可见主界面,在主界面地图上点击设置起止位置。不同方向会选择不同道路,如图:

如何实现复杂的导航功能

时间: 2024-10-30 12:12:37

如何实现复杂的导航功能的相关文章

ROS机器人程序设计(原书第2版)补充资料 (捌) 第八章 导航功能包集入门 navigation

ROS机器人程序设计(原书第2版)补充资料 (捌) 第八章 导航功能包集入门 navigation 书中,大部分出现hydro的地方,直接替换为indigo或jade或kinetic,即可在对应版本中使用. 本章三个非常重要概念:TF,SLAM,AMCL.务必掌握. 补充内容:http://blog.csdn.net/zhangrelay/article/details/50299417 第216页: 简介本章要点. 第217页: 导航综合功能包组成架构等. 补充如下: 目录 配置并使用导航功能

【微信公众平台开发】利用百度接口,制作一键导航功能

微信开发中,很多商家用户都要求点具体地址,能在百度或者soso地图上面显示自己的地址. 而这样的功能,利用百度api接口地图标点功能就可以很简单实现. 1.功能说明如下: 地图标点功能 调用该接口可调起PC或web地图,且在指定坐标点上显示点的名称和内容信息. 实例 http://api.map.baidu.com/marker?location=40.047669,116.313082&title=我的位置&content=百度奎科大厦 &output=html&src=

ROS探索总结(十九)——如何配置机器人的导航功能

1.概述 ROS的二维导航功能包,简单来说,就是根据输入的里程计等传感器的信息流和机器人的全局位置,通过导航算法,计算得出安全可靠的机器人速度控制指令.但是,如何在特定的机器人上实现导航功能包的功能,却是一件较为复杂的工程.作为导航功能包使用的必要先决条件,机器人必须运行ROS,发布tf变换树,并发布使用ROS消息类型的传感器数据.同时,为了让机器人更好的完成导航任务,开发者还要根据机器人的外形尺寸和性能,配置导航功能包的一些参数. 2.硬件要求 尽管导航功能包设计得尽可能通用,但是仍然对机器人

常规功能和模块自定义系统 (cfcmms)—043模块导航功能的重构(1)

043模块导航功能的重构(1) 模块导航即基于grid的条件限定.可以明确在导航树中导航条件,以及在该导航条件之下当前模块的记录数.在选中某个导航记录时,grid的数据会更新为该导航所设置的条件中.(这个功能应该是一个很好的功能,为什么现在还不太流行呢.可能是我见识的软件太少了) 导航作为引导用户浏览和筛选数据的功能,由于每一个导航记录上都标有记录数,可以很好的体现模块数据的分布情况(为了完成这个目的,可以加入每个导航的记录的百分比).现在来看看现在系统中的一些已有的导航功能. 更加复杂一点的导

常规功能和模块自定义系统 (cfcmms)—044模块导航功能的重构(2)

044模块导航功能的重构(2) 经过分析,可以将一级导航的数据类型分为以下几类: 1.模块实际字段值:例如对于"省份"模块,所属区域是其一个字符串字段,里面放着各个区域的名称. 2.父模块的导航:例如对于"市"模块,可以用省来对其进行导航. 3.某个数值字段的数值区间:可以自定义数值区间来完成分组.经过配置可以完成更加复杂的分组. 4.日期字段根据年,月,日来进行分分组,再可以扩展到比如说最近半月,最近一月,最近半年等的分组. 对于数值字段和日期字段的分组,可以是基

在iframe子页面中添加导航功能代码

使用iframe嵌套页面,并在页面中添加导航功能,iframe只适应高度 效果图如下图 主页面 <div class="date_app" id="postRightContent" style="height: 725px; margin-bottom: 30px;"> <iframe id="rightIframePage" name="rightIframePage" scrolli

使用 JavaScript 实现灵活的固定导航功能

如果你想在网页中实现灵活的固定导航功能,那么 Smart Fixed Navigation 这个 JavaScript 小脚本可以帮助轻松实现一个固定的导航,让用户在访问你的网站的时候可以随时使用菜单.它比全宽度的固定导航更小,并一个聪明UX的解决方案来取代回到顶部按钮功能. 您可能感兴趣的相关文章 Web 开发中很实用的10个效果[附源码下载] 精心挑选的优秀jQuery Ajax分页插件和教程 12款经典的白富美型 jQuery 图片轮播插件 让网站动起来!12款优秀的 jQuery 动画插

OpenLayers导航功能

获得视图的中心点坐标,进行调整即可.ol.Map.render();//request a map render 请求地图绘制ol.proj.transform主要用于坐标转换,它的第一个参数是ol.Coordinate类型的坐标,后面两个参数依次是当前坐标所用的坐标系,及转换后的坐标所用的坐标系,ol.proj.transform([104.06, 30.67], 'EPSG:4326', 'EPSG:3857')就能把EPSG:4326的坐标[104.06, 30.67]转换为EPSG:38

高德导航功能模块

主要代码: public class MainActivity extends BaseActivity { private EditText edit_end_lng; private EditText edit_end_lat; private EditText edi_star_Lat; private EditText edi_star_Lng; public static Double endLng = 0.0; public static Double endLat = 0.0; p