mapbox 导航记录(release-v2.15分支 纯kotlin)

一、简单使用示例

1. 初始化 MapboxNavigation

初始化时使用 NavigationOptions 设置一些参数,包括accessToken、appMetaData、LocationEngine等,其它还有很多,具体可以详看 NavigationOptions 类的内部。

下面示例中 LocationEngine 使用的重演定位引擎,可以看到模拟导航的效果,关键的两个类就是 ReplayLocationEngine 和 MapboxReplayer 。

/* ----- Mapbox Navigation components ----- */
private lateinit var mapboxNavigation: MapboxNavigationprivate val mapboxReplayer = MapboxReplayer()// initialize Mapbox Navigation
mapboxNavigation = MapboxNavigationProvider.create(NavigationOptions.Builder(applicationContext).accessToken(getMapboxAccessTokenFromResources()).eventsAppMetadata(EventsAppMetadata.Builder(BuildConfig.APPLICATION_ID,BuildConfig.VERSION_NAME).build()).locationEngine(ReplayLocationEngine(mapboxReplayer)).build()
)

2. 初始化 LocationObserver,对位置改变做观察

navigationLocationProvider 只是把当前导航的位置点给到 MapView,实现地图移动或者加位置图标等。

MapboxNavigationViewportDataSource 也是一样,移动地图的Camera到一个合适的位置,要结合 NavigationCamera 使用。NavigationCamera 还可以改变导航是 Following 还是 Overview 。

// camera
private lateinit var navigationCamera: NavigationCamera
private lateinit var viewportDataSource: MapboxNavigationViewportDataSource// initialize Navigation Camera
viewportDataSource = MapboxNavigationViewportDataSource(binding.mapView.getMapboxMap()
)
navigationCamera = NavigationCamera(binding.mapView.getMapboxMap(),binding.mapView.camera,viewportDataSource
)/* ----- Location and route progress callbacks ----- */
private val locationObserver = object : LocationObserver {override fun onNewRawLocation(rawLocation: Location) {// not handled}override fun onNewLocationMatcherResult(locationMatcherResult: LocationMatcherResult) {// update location puck's position on the mapnavigationLocationProvider.changePosition(location = locationMatcherResult.enhancedLocation,keyPoints = locationMatcherResult.keyPoints,)// update camera position to account for new locationviewportDataSource.onLocationChanged(locationMatcherResult.enhancedLocation)viewportDataSource.evaluate()}
}

3. 初始化 RoutesObserver,对多条路线的处理

private val routesObserver = RoutesObserver { result ->if (result.routes.isNotEmpty()) {// generate route geometries asynchronously and render themCoroutineScope(Dispatchers.Main).launch {val result = routeLineAPI.setRoutes(listOf(RouteLine(result.routes.first(), null)))val style = mapboxMap.getStyle()if (style != null) {routeLineView.renderRouteDrawData(style, result)}}// update the camera position to account for the new routeviewportDataSource.onRouteChanged(result.routes.first())viewportDataSource.evaluate()} else {// remove the route line and route arrow from the mapval style = mapboxMap.getStyle()if (style != null) {routeLineAPI.clearRouteLine { value ->routeLineView.renderClearRouteLineValue(style,value)}routeArrowView.render(style, routeArrowAPI.clearArrows())}// remove the route reference to change camera positionviewportDataSource.clearRouteData()viewportDataSource.evaluate()}
}

4. 初始化 NavigationSessionStateObserver ,对导航状态的监测

private val navigationSessionStateObserver = NavigationSessionStateObserver {logD("NavigationSessionState=$it", LOG_CATEGORY)logD("sessionId=${mapboxNavigation.getNavigationSessionState().sessionId}", LOG_CATEGORY)
}

5. 初始化 RouteProgressObserver ,对导航进度的监测

最关键的部分,如下是正常导航时的进度处理。但是对于模拟导航,只需要实例化 ReplayProgressObserver 对象。

// 模拟导航使用
private val routeProgressObserver1 = ReplayProgressObserver(mapboxReplayer)// 正常导航使用private val routeProgressObserver =RouteProgressObserver { routeProgress ->// update the camera position to account for the progressed fragment of the routeviewportDataSource.onRouteProgressChanged(routeProgress)viewportDataSource.evaluate()// show arrow on the route line with the next maneuverval maneuverArrowResult = routeArrowAPI.addUpcomingManeuverArrow(routeProgress)val style = mapboxMap.getStyle()if (style != null) {routeArrowView.renderManeuverUpdate(style, maneuverArrowResult)}// update top maneuver instructionsval maneuvers = maneuverApi.getManeuvers(routeProgress)maneuvers.fold({ error ->Toast.makeText(this@MapboxNavigationActivity,error.errorMessage,Toast.LENGTH_SHORT).show()},{binding.maneuverView.visibility = VISIBLEbinding.maneuverView.renderManeuvers(maneuvers)})// update bottom trip progress summarybinding.tripProgressView.render(tripProgressApi.getTripProgress(routeProgress))}

6. 初始化 VoiceInstructionsObserver ,对语音指令的监测

// 语音播报对象
private lateinit var voiceInstructionsPlayer: MapboxVoiceInstructionsPlayervoiceInstructionsPlayer = MapboxVoiceInstructionsPlayer(this,Locale.US.language
)// 静音和取消静音
voiceInstructionsPlayer.volume(SpeechVolume(0f))
voiceInstructionsPlayer.volume(SpeechVolume(1f))/* ----- Voice instruction callbacks ----- */
private val voiceInstructionsObserver =VoiceInstructionsObserver { voiceInstructions ->speechAPI.generate(voiceInstructions,speechCallback)}// speechCallback 中做 play
private val speechCallback =MapboxNavigationConsumer<Expected<SpeechError, SpeechValue>> { expected ->expected.fold({ error ->// play the instruction via fallback text-to-speech enginevoiceInstructionsPlayer.play(error.fallback,voiceInstructionsPlayerCallback)},{ value ->// play the sound file from the external generatorvoiceInstructionsPlayer.play(value.announcement,voiceInstructionsPlayerCallback)})}

7. findRoute并将路线设置给导航模块,然后开启导航

// findRoute
mapboxNavigation.requestRoutes()// 路线获取成功 onRoutesReady 后的处理
private fun setRouteAndStartNavigation(route: List<NavigationRoute>) {// set routemapboxNavigation.setNavigationRoutes(route)// show UI elementsbinding.soundButton.visibility = VISIBLEbinding.routeOverview.visibility = VISIBLEbinding.tripProgressCard.visibility = VISIBLEbinding.routeOverview.showTextAndExtend(2000L)binding.soundButton.unmuteAndExtend(2000L)// move the camera to overview when new route is availablenavigationCamera.requestNavigationCameraToOverview()
}override fun onStart() {super.onStart()mapboxNavigation.registerRoutesObserver(routesObserver)mapboxNavigation.registerNavigationSessionStateObserver(navigationSessionStateObserver)
//    mapboxNavigation.registerRouteProgressObserver(routeProgressObserver)mapboxNavigation.registerRouteProgressObserver(routeProgressObserver1)mapboxNavigation.registerLocationObserver(locationObserver)mapboxNavigation.registerVoiceInstructionsObserver(voiceInstructionsObserver)// 实际导航只需要注册好上面的观察者,下面时模拟导航的特殊开启方式mapboxReplayer.pushRealLocation(this, 0.0)mapboxReplayer.playbackSpeed(1.5)mapboxReplayer.play()
}

二、关键类

类名所属模块作用
MapboxNavigationlibnavigation-core核心类,要给它配置token,定位引擎等。
mapboxNavigation.startTripSession()
registerLocationObserver() 观察位置变化。
registerRoutesObserver() 对导航路线的处理,比如渲染,箭头等。
registerNavigationSessionStateObserver()
registerRouteProgressObserver() 导航进度。
registerVoiceInstructionsObserver() 语音指令。
NavigationOptionslibnavigation-base给 MapboxNavigation 配置token,定位引擎等使用此对象。
还有很多其它的配置项。
RoutesObserverlibnavigation-core对导航路线改变时,在这个接口方法中实现渲染。
RouteProgressObserverlibnavigation-core提供状态、进度和其他有关当前逐点路由的信息的回调。
LocationObserverlibnavigation-core监听位置更新。
VoiceInstructionsObserverlibnavigation-core语音指令接口。
---------------------------------------------------------------------------------------
MapboxNavigationViewportDataSourcelibnavui-mapsUI相关,需要把 MapView 对象传递给此类。
NavigationCameralibnavui-mapsUI相关,需要把 MapView,camera,MapboxNavigationViewportDataSource 对象传递给此类。
NavigationBasicGesturesHandlerlibnavui-mapsUI相关,基础手势。
MapboxManeuverApilibnavui-maneuverUI相关,顶部显示还有多少米向左向右转等信息。
MapboxTripProgressApilibnavui-tripprogressUI相关,底部进度,剩余时间,剩余距离,当前时间。
MapboxSpeechApilibnavui-voiceUI相关,语音部分。
MapboxVoiceInstructionsPlayerlibnavui-voiceUI相关,语音部分。
MapboxRouteLineApilibnavui-mapsUI相关,路线上图相关。
MapboxRouteLineViewlibnavui-mapsUI相关,路线上图相关。
MapboxRouteArrowViewlibnavui-mapsUI相关,路线上图相关。
---------------------------------------------------------------------------------------
ReplayLocationEnginelibnavigation-core模拟导航相关类,要在NavigationOptions设置这种定位引擎
MapboxReplayerlibnavigation-core模拟导航相关类,控制模拟导航play,finish等
ReplayRouteMapperlibnavigation-core模拟导航相关类,利用它里面的方法把要模拟的路线对象DirectionsRoute设置进去
ReplayProgressObserverlibnavigation-core模拟导航相关类,观察模拟导航的进度,替代正常导航进度观察RouteProgressObserver

三、NavigationView

布局文件 mapbox_navigation_view_layout.xml

init { } 方法块中会创建MapView并添加到布局,利用mapLayoutCoordinator(binding) 实例化 MapLayoutCoordinator

再利用 MapLayoutCoordinator 里的方法给 core 模块中的 MapboxNavigation 绑定 MapView。

MapView 的创建使用 MapViewBinder,而对它设置样式使用 MapStyleLoader

NavigationViewContext
NavigationViewBinder
NavigationViewStyles
NavigationViewOptions
MapViewOwner
MapStyleLoader
_mapViewBinder
_infoPanelRoutePreviewButtonBinder
_infoPanelStartNavigationButtonBinder
_infoPanelEndNavigationButtonBinder
_infoPanelContentBinder

四、获取导航路线 requestRoutes() 详细

MapboxNavigation 中获取导航路线的方法,有两个方法,参数有差异

fun requestRoutes(routeOptions: RouteOptions,routesRequestCallback: RouterCallback
)fun requestRoutes(routeOptions: RouteOptions,callback: NavigationRouterCallback
)

RouterCallback 中获取导航路线成功得到的是 DirectionsRoute 集合,在模拟导航中使用 DirectionsRoute 对象。也对应结合 MapboxNavigation.setRoutes(List<DirectionsRoute>) 使用,方法内部会利用 toNavigationRoutes() 做转换。

NavigationRouterCallback 中获取导航路线成功得到的是 NavigationRoute 集合,对应结合 MapboxNavigation.setNavigationRoutes(List<NavigationRoute>) 使用。

toNavigationRoutes() 是把 DirectionsRoute 集合转为 NavigationRoute 集合,也有 toDirectionsRoutes() 可以把 NavigationRoute 集合转为 DirectionsRoute 集合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 多线程编程教程:使用 std::thread 和 std::future 进行并发任务管理 ,处理线程超时

C 多线程编程教程&#xff1a;使用 std::thread 和 std::future 进行并发任务管理 引言 多线程编程是一种强大的工具&#xff0c;可以加速计算密集型任务的执行&#xff0c;提高应用程序的性能。C提供了多种多线程编程工具&#xff0c;包括std::thread和std::future&#xff…

【infiniband】用udaddy测试RDMA_CM API通过GID连接

1. 运行ibv_devinfo -vv 找到GID[ 0]。 2.udaddy用1.找到的GID[ 0]测试连接 服务器: rootdebian:~/infiniband/rdma-core-50mlnx1# build/bin/udaddy -f gid -b fe80:0000:0000:0000:e41d:2e03:0051:26d1 udaddy: starting server test.rai->ai_src_addr->sa_famil…

IDEA版SSM入门到实战(Maven+MyBatis+Spring+SpringMVC) -Maven使用前准备

一&#xff0e;Maven准备 注意&#xff1a;IDEA2019.1.x 最高支持Maven的3.6.0 下载地址&#xff1a;http://maven.apache.org/Maven底层使用Java语言编写的&#xff0c;所以需要配置JAVA_HOME环境变量及Path将Maven解压非中文无空格目录下配置MAVEN_HOME环境变量及Path输入【c…

基于AERMOD模型在大气环境影响评价中的实践

AERMOD模型是在美国EPA&#xff08;AMS/EPA&#xff09;在ISC3&#xff08;Industrial Source Complex Model&#xff09;基础上建立开发的高斯稳态扩散模型&#xff0c;是我国《环境影响评价技术导则 大气环境&#xff08;HJ 2.2-2018&#xff09;》技术导则推荐的大气污染物浓…

人工智能的优势:使用 GPT 和扩散模型生成图像

推荐&#xff1a;使用 NSDT场景编辑器快速搭建3D应用场景 世界被人工智能 &#xff08;AI&#xff09; 所吸引&#xff0c;尤其是自然语言处理 &#xff08;NLP&#xff09; 和生成 AI 的最新进展&#xff0c;这是有充分理由的。这些突破性技术有可能提高各种任务的日常生产力。…

Vue前端框架08 Vue框架简介、VueAPI风格、模板语法、事件处理、数组变化侦测

目录 一、Vue框架1.1渐进式框架1.2 Vue的版本 二、VueAPI的风格三、Vue开发准备工作四、模板语法文本插值属性绑定条件渲染列表渲染key管理状态 四、事件处理定义事件事件参数事件修饰符 五、数组变化侦测 一、Vue框架 渐进式JavaScript框架&#xff0c;易学易用&#xff0c;性…

Unity的GPUSkinning进一步介绍

大家好&#xff0c;我是阿赵。   在几年前&#xff0c;我曾经写过一篇介绍GPUSkinning的文章&#xff0c;这么多年之后&#xff0c;还是看到不停有朋友在翻看这篇旧文章。今天上去GitHub看了一下&#xff0c;GPUSkinning这个开源的插件已经很久没有更新过了&#xff0c;还是停…

SSH详解

文章目录 SSH简介SSH安装SSH秘钥秘钥生成公钥上传(免密登录) 基本用法命令行配置配置文件SSH代码动态转发本地转发远程转发搭建简易版的VPN SCP命令本地复制到远程远程复制到本地远程复制到远程 Rsync命令安装基本用法本地同步到远程远程同步到本地 SFTP命令 SSH简介 Secure Sh…

分享一个有意思的线程相关的程序运行题

翻开之前的代码&#xff0c;发现了一个有意思的代码&#xff0c;猜以下代码的运行结果&#xff1a; package thread;/*** author heyunlin* version 1.0*/ public class ThreadMethodExample {public static void main(String[] args) {Thread thread new Thread(new Runnabl…

云原生Kubernetes:kubectl管理命令

目录 一、理论 1.kubectl 管理命令 2.项目的生命周期 二、实验 1.kubectl 管理命令 2.项目的生命周期 三、总结 一、理论 1.kubectl 管理命令 &#xff08;1&#xff09;陈述式资源管理方法 kubernetes集群管理集群资源的唯一入口是通过相应的方法调用apiserver的接口…

复旦-华盛顿EMBA:AI时代掘金,科技进化里的挑战与机遇

如果从去年年底ChatGPT3.5发布算起&#xff0c;AI赛道的热度已经持续飙升了半年有余。      “AI的iPhone时刻”代表什么&#xff1f;AI驱动的商业时代已经到来&#xff1f;      我们能看到担忧、恐惧、憧憬&#xff0c;但唯独不缺狂飙突进、加速进化。人类制造AI&…

WordPress(4)关于网站的背景图片更换

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、更改的位置1. 红色区域是要更换的随机的图片二、替换图片位置三.开启随机数量四.结束前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也…

Android 10.0 Launcher3桌面显示多个相同app图标的解决办法

1.前言 在10.0的系统ROM定制化开发中,在Launcher3的系统原生桌面中,在显示桌面的时候,在禁用和启用app的功能测试的时候,会发现有多个相同app的图标显示在桌面 这对Launcher3的体验效果不是很好,所以为了优化产品,需要解决这个bug,然后让产品更完善 2.桌面显示多个相同…

Hadoop的分布式文件存储系统HDFS组件的使用

Hadoop的第一个核心组件&#xff1a;HDFS&#xff08;分布式文件存储系统&#xff09; 一、HDFS的组成1、NameNode2、DataNode3、SecondaryNameNode4、客户端&#xff1a;命令行/Java API 二、HDFS的基本使用1、命令行操作2、Java API操作 三、HDFS的工作流程问题&#xff08;H…

Direct3D颜色

在Direct3D中颜色用RGB三元组来表示&#xff0c;RGB数据可用俩种不同的结构来保存&#xff0c;第一种是D3DCOLOR&#xff0c;它实际上与DWORD类型完全相同&#xff0c;共有32位&#xff0c;D3DCOLOR类型种的各位被分成四个8位项&#xff0c;每项存储了一种颜色分量的亮度值。 由…

【Hive SQL 每日一题】统计用户连续下单的日期区间

文章目录 测试数据需求说明需求实现 测试数据 create table test(user_id string,order_date string);INSERT INTO test(user_id, order_date) VALUES(101, 2021-09-21),(101, 2021-09-22),(101, 2021-09-23),(101, 2021-09-27),(101, 2021-09-28),(101, 2021-09-29),(101, 20…

ChatGPT如何协助人们学习新的科学和技术概念?

ChatGPT可以在许多方面协助人们学习新的科学和技术概念。随着科学和技术的不断发展&#xff0c;学习成为了一个终身的过程&#xff0c;人们需要不断地更新和扩展他们的知识。ChatGPT作为一种强大的自然语言处理工具&#xff0c;可以在以下几个方面为学习者提供帮助&#xff1a;…

力扣(LeetCode)算法_C++——至多包含两个不同字符的最长子串

给你一个字符串 s &#xff0c;请你找出 至多 包含 两个不同字符 的最长子串&#xff0c;并返回该子串的长度。 示例 1&#xff1a; 输入&#xff1a;s “eceba” 输出&#xff1a;3 解释&#xff1a;满足题目要求的子串是 “ece” &#xff0c;长度为 3 。 示例 2&#xff…

C语言sizeof()计算空间大小为8的问题

在练习数据结构过程中&#xff0c;定义指针p&#xff0c;并且申请了10个char类型空间&#xff0c;但在计算p所指空间大小时候&#xff0c;发现了一些奇怪的现象。 #include <stdio.h> #include <stdlib.h>int main(){char s[12];printf("the size of memory …

Java反射:探索对象创建与类信息获取

文章目录 1. 对象的创建2. 类的初始化2.1 类的加载2.2 类的连接2.3 类的初始化 3. 反射是什么&#xff1f;4. 获取Class类对象4.1 使用类名.class4.2 使用对象的getClass()方法4.3 使用Class.forName() 5. 获取构造器对象5.1 使用getConstructors()和getDeclaredConstructors()…