以下是素材:

最近项目中用到了根据一段线路的经纬度集合来在地图上播放该车辆的行驶轨迹的需求.下面我就讲一下我实现步骤:
效果图如下(因为制作gif图为了控制大小去掉了很多帧,不必在意这些细节,嘿嘿!!!):

1.首先在界面上展示百度地图(这不是废话么)如果不知道怎么展示请看我之前的博客.

2.初始化控件,把需要绘制在地图上的BitmapDescriptor准备好.也一个起点和终点的图标和灰色的线和绿色的线还有一辆小车.

3.调用百度地图的api把对应的图标绘制上去也就是addOverlay()这个方法.

4.然后就是循环不停的移动小车在地图上的位置了.

完成以上四步也就完成了轨迹播放的功能

初始化控件:

//初始化控件mMapView = findViewById(R.id.bmapView);BaiduMap mBaiduMap = mMapView.getMap();

处理数据:(这里由于每个人的数据源不同所以逻辑也不同,此处需要把自己的逻辑写进去)

//处理数据源,把assets中的文件数据转化成一个装有位置的集合List<Data> location = JsonReadUtil.fromJsonArray2(this, "test.json");latLngs = new ArrayList<>();LatLngBounds.Builder tempBounds = new LatLngBounds.Builder();for (int i = 0; i < location.size(); i++) {LatLng latLng = new LatLng(location.get(i).baidulat, location.get(i).baidulng);latLngs.add(latLng);tempBounds.include(latLng);}

注意:tempBounds.include(latLng);这个方法只是为了让地图上展示出我所有的经纬度而设定的,可根据自己的业务需要加入与否.

把需要绘制的图标设置好:

//五个需要绘制在地图上的图标BitmapDescriptor blueArrow = BitmapDescriptorFactory.fromResource(R.mipmap.icon_road_blue_arrow);BitmapDescriptor grayArrow = BitmapDescriptorFactory.fromResource(R.mipmap.icon_road_gray_arrow);BitmapDescriptor che = BitmapDescriptorFactory.fromResource(R.mipmap.che);BitmapDescriptor qi = BitmapDescriptorFactory.fromResource(R.mipmap.qi);BitmapDescriptor zhong = BitmapDescriptorFactory.fromResource(R.mipmap.zhong);

调用addOverlay()方法把图标绘制上去:

//控制线条的宽度样式等(画线)PolylineOptions ooPolyline = new PolylineOptions().customTexture(blueArrow).width(20).dottedLine(true).points(latLngs);PolylineOptions ooPolyline2 = new PolylineOptions().customTexture(grayArrow).width(20).dottedLine(true).points(latLngs);//在地图上批量添加(把灰线绘制入百度地图中)mBaiduMap.addOverlay(ooPolyline);//在地图上批量添加(把蓝线绘制入百度地图中)mPolyline2 = (Polyline) mBaiduMap.addOverlay(ooPolyline2);//拿到集合的第一个位置LatLng pointQi = new LatLng(location.get(0).baidulat, location.get(0).baidulng);//画起点的图标(也就是集合的第一个位置就是起点)OverlayOptions optionQi = new MarkerOptions().position(pointQi).icon(qi);//拿到集合最后一个位置LatLng pointZhong = new LatLng(location.get(location.size() - 1).baidulat, location.get(location.size() - 1).baidulng);//画终点的图标(也就是集合的最后一个位置就是终点)OverlayOptions optionZhong = new MarkerOptions().position(pointZhong).icon(zhong);//拿到集合的第一个位置LatLng pointChe = new LatLng(location.get(0).baidulat, location.get(0).baidulng);//画车辆的图标(因为车辆是从第一个位置开始行驶的,所以车辆的初始位置是第一个)MarkerOptions markerOptions = new MarkerOptions().position(pointChe).icon(che);//创建OverlayOptions的集合(把起点终点和车辆绘制在地图上)List<OverlayOptions> options = new ArrayList<>();options.add(optionQi);options.add(optionZhong);mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions);//(绘制在地图上)mBaiduMap.addOverlays(options);LatLngBounds mBaiduLatLngBounds = tempBounds.build();mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngBounds(mBaiduLatLngBounds));

循环移动:

/*** 循环进行移动逻辑*/public void moveLooper() {//为了不阻塞ui线程所以开启子线程new Thread(new Runnable() {@Overridepublic void run() {//死循环while (true) {for (int i = 0; i < latLngs.size() - 1; i++) {final LatLng startPoint = latLngs.get(i);final LatLng endPoint = latLngs.get(i + 1);mMoveMarker.setPosition(startPoint);mHandler.post(new Runnable() {@Overridepublic void run() {// refresh marker's rotateif (mMapView == null) {return;}mMoveMarker.setRotate((float) getAngle(startPoint,endPoint));}});double slope = getSlope(startPoint, endPoint);// 是不是正向的标示boolean isReverse = (startPoint.latitude > endPoint.latitude);double intercept = getInterception(slope, startPoint);double xMoveDistance = isReverse ? getXMoveDistance(slope) :-1 * getXMoveDistance(slope);for (double j = startPoint.latitude; !((j > endPoint.latitude) ^ isReverse);j = j - xMoveDistance) {LatLng latLng;if (slope == Double.MAX_VALUE) {latLng = new LatLng(j, startPoint.longitude);} else {latLng = new LatLng(j, (j - intercept) / slope);}final LatLng finalLatLng = latLng;mHandler.post(new Runnable() {@Overridepublic void run() {if (mMapView == null) {return;}mMoveMarker.setPosition(finalLatLng);latLngs2.add(startPoint);latLngs2.add(finalLatLng);mPolyline2.setPoints(latLngs2);}});try {Thread.sleep(TIME_INTERVAL);} catch (InterruptedException e) {e.printStackTrace();}}}}}}).start();}

关于计算的方法:

/*** 根据两点算取图标转的角度*/private double getAngle(LatLng fromPoint, LatLng toPoint) {double slope = getSlope(fromPoint, toPoint);if (slope == Double.MAX_VALUE) {if (toPoint.latitude > fromPoint.latitude) {return 0;} else {return 180;}}float deltAngle = 0;if ((toPoint.latitude - fromPoint.latitude) * slope < 0) {deltAngle = 180;}double radio = Math.atan(slope);return 180 * (radio / Math.PI) + deltAngle - 90;}/*** 根据点和斜率算取截距*/private double getInterception(double slope, LatLng point) {return point.latitude - slope * point.longitude;}/*** 算斜率*/private double getSlope(LatLng fromPoint, LatLng toPoint) {if (toPoint.longitude == fromPoint.longitude) {return Double.MAX_VALUE;}return ((toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude));}

贴上我全部的代码:(具体的注释已经写的很清楚了)

private MapView mMapView;private Polyline mPolyline2;private Handler mHandler;private ArrayList<LatLng> latLngs;private Marker mMoveMarker;// 通过设置间隔时间和距离可以控制速度和图标移动的距离private static final int TIME_INTERVAL = 80;private static final double DISTANCE = 0.00250;private ArrayList<LatLng> latLngs2 = new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化控件mMapView = findViewById(R.id.bmapView);BaiduMap mBaiduMap = mMapView.getMap();//处理数据源,把assets中的文件数据转化成一个装有位置的集合List<Data> location = JsonReadUtil.fromJsonArray2(this, "test.json");latLngs = new ArrayList<>();LatLngBounds.Builder tempBounds = new LatLngBounds.Builder();for (int i = 0; i < location.size(); i++) {LatLng latLng = new LatLng(location.get(i).baidulat, location.get(i).baidulng);latLngs.add(latLng);tempBounds.include(latLng);}mHandler = new Handler(Looper.getMainLooper());//五个需要绘制在地图上的图标BitmapDescriptor blueArrow = BitmapDescriptorFactory.fromResource(R.mipmap.icon_road_blue_arrow);BitmapDescriptor grayArrow = BitmapDescriptorFactory.fromResource(R.mipmap.icon_road_gray_arrow);BitmapDescriptor che = BitmapDescriptorFactory.fromResource(R.mipmap.che);BitmapDescriptor qi = BitmapDescriptorFactory.fromResource(R.mipmap.qi);BitmapDescriptor zhong = BitmapDescriptorFactory.fromResource(R.mipmap.zhong);//控制线条的宽度样式等(画线)PolylineOptions ooPolyline = new PolylineOptions().customTexture(blueArrow).width(20).dottedLine(true).points(latLngs);PolylineOptions ooPolyline2 = new PolylineOptions().customTexture(grayArrow).width(20).dottedLine(true).points(latLngs);//在地图上批量添加(把灰线绘制入百度地图中)mBaiduMap.addOverlay(ooPolyline);//在地图上批量添加(把蓝线绘制入百度地图中)mPolyline2 = (Polyline) mBaiduMap.addOverlay(ooPolyline2);//拿到集合的第一个位置LatLng pointQi = new LatLng(location.get(0).baidulat, location.get(0).baidulng);//画起点的图标(也就是集合的第一个位置就是起点)OverlayOptions optionQi = new MarkerOptions().position(pointQi).icon(qi);//拿到集合最后一个位置LatLng pointZhong = new LatLng(location.get(location.size() - 1).baidulat, location.get(location.size() - 1).baidulng);//画终点的图标(也就是集合的最后一个位置就是终点)OverlayOptions optionZhong = new MarkerOptions().position(pointZhong).icon(zhong);//拿到集合的第一个位置LatLng pointChe = new LatLng(location.get(0).baidulat, location.get(0).baidulng);//画车辆的图标(因为车辆是从第一个位置开始行驶的,所以车辆的初始位置是第一个)MarkerOptions markerOptions = new MarkerOptions().position(pointChe).icon(che);//创建OverlayOptions的集合(把起点终点和车辆绘制在地图上)List<OverlayOptions> options = new ArrayList<>();options.add(optionQi);options.add(optionZhong);mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions);//(绘制在地图上)mBaiduMap.addOverlays(options);LatLngBounds mBaiduLatLngBounds = tempBounds.build();mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newLatLngBounds(mBaiduLatLngBounds));//循环移动车辆位置moveLooper();}/*** 计算x方向每次移动的距离*/private double getXMoveDistance(double slope) {if (slope == Double.MAX_VALUE) {return DISTANCE;}return Math.abs((DISTANCE * slope) / Math.sqrt(1 + slope * slope));}/*** 循环进行移动逻辑*/public void moveLooper() {//为了不阻塞ui线程所以开启子线程new Thread(new Runnable() {@Overridepublic void run() {//死循环while (true) {for (int i = 0; i < latLngs.size() - 1; i++) {final LatLng startPoint = latLngs.get(i);final LatLng endPoint = latLngs.get(i + 1);mMoveMarker.setPosition(startPoint);mHandler.post(new Runnable() {@Overridepublic void run() {// refresh marker's rotateif (mMapView == null) {return;}mMoveMarker.setRotate((float) getAngle(startPoint,endPoint));}});double slope = getSlope(startPoint, endPoint);// 是不是正向的标示boolean isReverse = (startPoint.latitude > endPoint.latitude);double intercept = getInterception(slope, startPoint);double xMoveDistance = isReverse ? getXMoveDistance(slope) :-1 * getXMoveDistance(slope);for (double j = startPoint.latitude; !((j > endPoint.latitude) ^ isReverse);j = j - xMoveDistance) {LatLng latLng;if (slope == Double.MAX_VALUE) {latLng = new LatLng(j, startPoint.longitude);} else {latLng = new LatLng(j, (j - intercept) / slope);}final LatLng finalLatLng = latLng;mHandler.post(new Runnable() {@Overridepublic void run() {if (mMapView == null) {return;}mMoveMarker.setPosition(finalLatLng);latLngs2.add(startPoint);latLngs2.add(finalLatLng);mPolyline2.setPoints(latLngs2);}});try {Thread.sleep(TIME_INTERVAL);} catch (InterruptedException e) {e.printStackTrace();}}}}}}).start();}/*** 根据两点算取图标转的角度*/private double getAngle(LatLng fromPoint, LatLng toPoint) {double slope = getSlope(fromPoint, toPoint);if (slope == Double.MAX_VALUE) {if (toPoint.latitude > fromPoint.latitude) {return 0;} else {return 180;}}float deltAngle = 0;if ((toPoint.latitude - fromPoint.latitude) * slope < 0) {deltAngle = 180;}double radio = Math.atan(slope);return 180 * (radio / Math.PI) + deltAngle - 90;}/*** 根据点和斜率算取截距*/private double getInterception(double slope, LatLng point) {return point.latitude - slope * point.longitude;}/*** 算斜率*/private double getSlope(LatLng fromPoint, LatLng toPoint) {if (toPoint.longitude == fromPoint.longitude) {return Double.MAX_VALUE;}return ((toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude));}

百度地图上根据经纬度集合绘制行车轨迹相关推荐

  1. android百度地图轨迹实现,android 获取GPS经纬度在百度地图上绘制轨迹

    实现将一组GPS模块获取的经纬度数据在百度地图上绘制轨迹 1.将经纬度转换成百度地图坐标 /** * 标准的GPS经纬度坐标直接在地图上绘制会有偏移,这是测绘局和地图商设置的加密,要转换成百度地图坐标 ...

  2. android 获取GPS经纬度在百度地图上绘制轨迹

    实现将一组GPS模块获取的经纬度数据在百度地图上绘制轨迹 1.将经纬度转换成百度地图坐标 /*** 标准的GPS经纬度坐标直接在地图上绘制会有偏移,这是测绘局和地图商设置的加密,要转换成百度地图坐标* ...

  3. 根据经纬度坐标值在百度地图上绘制轨迹

    因为项目需要做物体轨迹检测,所以要把物体移动的轨迹在百度地图上进行绘制和显示,于是就在网上找到了这个方法,现在做个记录方便以后查阅: 1.html 部分设置存放地图的容器和设置你的百度地图的ak ht ...

  4. Python地理地图可视化:folium把百度地图中国城市中心经纬度解析出来并在地图上展示(三)

    python地理地图可视化:folium把百度地图各个城市经纬度解析出来并在地图上展示(三) 上一篇(https://zhangphil.blog.csdn.net/article/details/1 ...

  5. python地图可视化把直辖市和地级市画在一起_Python地理地图可视化:Folium解析百度地图上中国城市中心的经纬度并显示在地图上(3),folium,把,出来,展示,三...

    python地理地图可视化:folium把百度地图各个城市经纬度解析出来并在地图上展示(三) import json import webbrowser as wb import folium NAM ...

  6. 如何在百度地图上绘制建筑楼块(矢量面)数据并导出为图片

    万能地图下载器的矢量面绘制功能可以在百度地图上绘制行政边界.建筑楼块.街区.居民地.植被.水系和湖泊等矢量面状数据. 这里我们以绘制建筑为例,通过以下几个步骤说明如何在地图中绘制建筑楼块,但请确保你的 ...

  7. 关于微信开发定位获取当前经纬度在百度地图上不准确的问题。

    这个其实在18年都不是问题,因为微信定位的不准,我们可以选择直接用地图的获取当前经纬度的方法,还是很准的,但是微信更新后我发现在微信浏览器中都不能使用其他地图的定位功能了,这里我自己是测试了百度和腾讯 ...

  8. navigator.geolocation的应用 - 将定位信息显示在百度地图上

    在学习navigator.geolocation的时候,有一个实例是获取坐标后显示在谷歌地图上.众所周知,谷歌地图国内并不能直接访问,得用特殊手段,那我要测试的时候还要开着梯子挺麻烦的,想给别人用也得 ...

  9. html5获取我的位置并在百度地图上显示

    html5获取我的位置并在百度地图上显示 一.前言 二.在线演示和GitHub源码 一.前言 最近有兴趣研究了下移动端的地图api,发现其实挺简单的,HTML5也提供了地理位置API:Geolocat ...

最新文章

  1. 如何在Linux实现自动运行程序
  2. 2.13 向量化 Logistic 回归-深度学习-Stanford吴恩达教授
  3. javascript span ie 与FF
  4. [转]Angular2 Material2 封装组件 —— confirmDialog确定框
  5. 工程师如何“神还原”用户问题?闲鱼回放技术揭秘
  6. C#通过COM组件操作IE浏览器(三):了解IHTMLDocument2
  7. 数据标准是物联网大集成应用的核心
  8. 页面加载之window.onload=function(){} 和 $(function(){})的区别
  9. 全网首发:LINUX右键新建时的模板问题
  10. 博图/博途(TIA)V13 V14 V15 V16 软件安装教程,适用于新手的傻瓜式安装方法,强推!!!!
  11. EndNote简明教程(三分钟上手EndNote)
  12. 钳工常识与钳工技能实训教学
  13. Jenkins里的Crumb
  14. 什么是高耦合低内聚?
  15. bing重定向次数过多怎么办?新必应用不了了?只需一个小软件就可以轻松免费解决!
  16. 大学综评自招面试 计算机专业,沪9高校举行自招面试 高中学生综合素质纪实报告成重要参考...
  17. 【特纳斯电子】基于单片机的智能风扇-开题报告
  18. java-net-php-python-jsp家具进销存管理系统1计算机毕业设计程序
  19. 注意火车站的开门时间
  20. Qt跨线程使用moveToThread的注意事项(Cannot move to target thread )

热门文章

  1. #cat /proc/meminfo 详解
  2. android 7.1 禁止安装第三方软件
  3. WPS JS宏之遍历目录文件
  4. linux系统分区备份,备份Linux操作系统的几种方法
  5. echarts 中x轴 设置步长,间隔的距离
  6. 扩展c盘时,如何删除恢复分区
  7. C#加载动态链接库的类
  8. TiDB 在 UCloud 公有云上的实践
  9. Redis内部数据结构详解(2)——skiplist
  10. OpenGL笔记-1.OpenGL概念基础入门