高德地图中有可供调用的 点平滑移动 的 API,但是功能相对简单,不足以满足项目需求。
故多方寻求方案,未果!只能自己动手实现,现在贴出来和大家一起分享。
转载请注明出处:www.facex.xyz,如有发现错误或有其他更好的实现方式可与我联系。
首先声明,通过本文不一定能解决你所面临的问题,关键在于理解其实现原理,尤其是第3点:高德官方点平滑移动API实现过程。
1. 原有方案介绍
之前有写过一篇 使用高德地图模拟运动轨迹, 介绍了使用高德地图的点平滑移动 API 来实现模拟运动轨迹,但是存在几个问题:
- 一旦设置了动画时间并开始动画,只有停止选项,然后就没有然后了。
- 不支持在轨迹上任意位置暂停,高德 API 的动画只能在轨迹的经纬度数组中的点停止,当调用停止动画时,而点还没有到达经纬度数组中的点的位置,这时点会继续向前走(而不是马上停止),直到到达数组中下一个经纬度点上。
- 不支持以速度来驱动动画,并在动画过程中改变速度。
2. 优化方案介绍
针对上面的 3 个问题,本次分享的点平滑移动方案优化如下:
- 支持暂停和继续。
- 支持在任意时刻,任意位置暂停。
- 支持以速度来驱动动画,并且支持动画中改变速度。
下面开始我的分享:
3. 高德官方点平滑移动API实现过程
高德地图开源了点平滑移动 API 的技术实现, 我的优化也是建立在此基础之上的。
开源地址:android-smooth-move
文档地址:点平滑移动
我大概分析下其实现过程:
- 计算轨迹经纬度数组每两个点的距离
- 然后对每两个点之间的直线路径做 TranslateAnimation 动画,本段动画时间 = 动画总时间 * 本短距离 / 路径总距离
- 在一段动画结束后开始下一段动画,直到路径结束
其实质是对高德 3D 地图做了一个封装,具体的代码实现可以参考源码。
4. 优化方案要点讲解
下面是我的优化方案, 只贴部分代码,具体实现细节也请参考源码。
项目地址:SmoothMove
4.1 以速度驱动动画
在两点之间做 ValueAnimator 时,根据两点之间的距离,计算本次动画需要的时间,本段动画时间 = 本段距离 / 速度。
|
|
4.2 在任意时刻,任意点暂停
我修改了动画的实现方式,改用 ValueAnimator,通过实现 TypeEvaluator 自定义 LngLatEvaluator 类,使动画过程中返回当前点的经纬度值 LngLat。调用 ValueAnimator 的 cancel() 方法,动画即停止。此时可以取到当前点的坐标点。
|
|
4.3 暂停和继续
暂停时先取消当前动画
|
|
在动画取消的回调中重新计算剩余路径的经纬度数组
|
|
继续时对重新计算剩余的路径做动画。
|
|
4.4 改变平滑移动的速度
改变平滑移动的速度,需要用到暂停的继续功能,当改变速度时,先暂停当前动画,然后对动画的速度变量赋新值,最后继续动画。
|
|
4.5 回调平滑移动的累计移动距离和总距离
动画中回调平滑移动的累计移动距离和总距离,方便计算当前进度等。
回调的总距离不等同于路径规划的距离,相对于路径规划距离的不准确性,回调的总距离可视为精确距离(至少对于地图上本次平滑移动),因为回调的总距离是每两点间距离累加所得。
大概就这么多了,三言两语也说不清,还是看代码吧。
上一篇:在 IntelliJ IDEA 中创建 Spring boot 项目