分享

百度地图轨迹绘制

 好汉勃士 2024-02-28 发布于广东
<span style='font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);'>一直想做一个记录自己运动轨迹的app,只是不知如何绘制轨迹。看了百度地图API中的demo,其实很简单。</span>

核心代码只有两句:

  1. options = new PolylineOptions().color(0xAAFF0000).width(6)
  2. .points(points);
  3. mBaiduMap.addOverlay(options);
其中points是坐标的集合,大小size>=2&&size<=1000

完整的测试代码如下:--修改版(解决了中间GPS停止,获取不到数据的情况)

  1. <pre name='code' class='java'>package com.kelly.mapdemo;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import android.app.Activity;
  5. import android.os.Bundle;
  6. import android.os.Handler;
  7. import android.view.View;
  8. import android.view.View.OnClickListener;
  9. import android.widget.Button;
  10. import com.baidu.location.BDLocation;
  11. import com.baidu.location.BDLocationListener;
  12. import com.baidu.location.LocationClient;
  13. import com.baidu.location.LocationClientOption;
  14. import com.baidu.mapapi.map.BaiduMap;
  15. import com.baidu.mapapi.map.BitmapDescriptor;
  16. import com.baidu.mapapi.map.DotOptions;
  17. import com.baidu.mapapi.map.MapStatusUpdate;
  18. import com.baidu.mapapi.map.MapStatusUpdateFactory;
  19. import com.baidu.mapapi.map.MapView;
  20. import com.baidu.mapapi.map.MyLocationData;
  21. import com.baidu.mapapi.map.OverlayOptions;
  22. import com.baidu.mapapi.map.PolylineOptions;
  23. import com.baidu.mapapi.model.LatLng;
  24. public class MyRouteActivity extends Activity {
  25. // 地图相关
  26. MapView mMapView;
  27. BaiduMap mBaiduMap;
  28. // UI相关
  29. Button but_start;
  30. Button but_stop;
  31. // 定位相关
  32. private LocationClient mLocationClient;
  33. BitmapDescriptor mCurrentMarker;
  34. boolean isFirstLoc = true;// 是否首次定位
  35. List<LatLng> points = new ArrayList<LatLng>();
  36. List<LatLng> points_tem = new ArrayList<LatLng>();
  37. OverlayOptions options;
  38. // 定时器相关,定时检查GPS是否开启(这里只须检查mLocationClient是否启动)
  39. Handler handler = new Handler();
  40. // 是否停止定位服务
  41. boolean isStopLocClient = false;
  42. @Override
  43. protected void onCreate(Bundle savedInstanceState) {
  44. super.onCreate(savedInstanceState);
  45. setContentView(R.layout.activity_myroute);
  46. // 测试点,发布前去掉
  47. // points.add(new LatLng(34.2376, 108.9923));
  48. // 启动计时器(每3秒检测一次)
  49. handler.postDelayed(new MyRunable(), 3000);
  50. // 初始化地图
  51. mMapView = (MapView) findViewById(R.id.bmapView);
  52. mBaiduMap = mMapView.getMap();
  53. // UI初始化
  54. but_start = (Button) findViewById(R.id.but_start);
  55. but_stop = (Button) findViewById(R.id.but_stop);
  56. // 初始化定位信息
  57. initLocation();
  58. // 开始记录并绘制轨迹
  59. but_start.setOnClickListener(new OnClickListener() {
  60. @Override
  61. public void onClick(View v) {
  62. isStopLocClient = false;
  63. if (!mLocationClient.isStarted()) {
  64. mLocationClient.start();
  65. }
  66. }
  67. });
  68. // 结束此次运动,绘制终点
  69. but_stop.setOnClickListener(new OnClickListener() {
  70. @Override
  71. public void onClick(View v) {
  72. isStopLocClient = true;
  73. if (mLocationClient.isStarted()) {
  74. // 绘制终点
  75. drawEnd(points);
  76. mLocationClient.stop();
  77. }
  78. }
  79. });
  80. }
  81. class MyRunable implements Runnable {
  82. public void run() {
  83. if (!mLocationClient.isStarted()) {
  84. mLocationClient.start();
  85. }
  86. if (!isStopLocClient) {
  87. handler.postDelayed(this, 3000);
  88. }
  89. }
  90. }
  91. /**
  92. * 根据数据绘制轨迹
  93. *
  94. * @param points2
  95. */
  96. protected void drawMyRoute(List<LatLng> points2) {
  97. OverlayOptions options = new PolylineOptions().color(0xAAFF0000)
  98. .width(10).points(points2);
  99. mBaiduMap.addOverlay(options);
  100. }
  101. // 初始化定位
  102. public void initLocation() {
  103. // 开启定位图层
  104. mBaiduMap.setMyLocationEnabled(true);
  105. // 定位初始化
  106. mLocationClient = new LocationClient(this);
  107. mLocationClient.registerLocationListener(new MyLocationListenner());
  108. LocationClientOption option = new LocationClientOption();
  109. option.setOpenGps(true);// 打开gps
  110. option.setAddrType('all');// 返回的定位结果包含地址信息,(注意如果想获取关于地址的信息,这里必须进行设置)
  111. option.setCoorType('bd09ll'); // 设置坐标类型
  112. option.setScanSpan(1000);
  113. // 设置定位方式的优先级。
  114. // 当gps可用,而且获取了定位结果时,不再发起网络请求,直接返回给用户坐标。这个选项适合希望得到准确坐标位置的用户。如果gps不可用,再发起网络请求,进行定位。
  115. option.setPriority(LocationClientOption.GpsFirst);
  116. // option.setPriority(LocationClientOption.NetWorkFirst);
  117. mLocationClient.setLocOption(option);
  118. }
  119. /**
  120. * 定位SDK监听函数
  121. */
  122. class MyLocationListenner implements BDLocationListener {
  123. @Override
  124. public void onReceiveLocation(BDLocation location) {
  125. // map view 销毁后不在处理新接收的位置
  126. if (location == null || mMapView == null)
  127. return;
  128. // 如果不显示定位精度圈,将accuracy赋值为0即可
  129. MyLocationData locData = new MyLocationData.Builder().accuracy(0)
  130. .latitude(location.getLatitude())
  131. .longitude(location.getLongitude()).build();
  132. mBaiduMap.setMyLocationData(locData);
  133. LatLng point = new LatLng(location.getLatitude(),
  134. location.getLongitude());
  135. points.add(point);
  136. if (isFirstLoc) {
  137. points.add(point);
  138. isFirstLoc = false;
  139. LatLng ll = new LatLng(location.getLatitude(),
  140. location.getLongitude());
  141. MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
  142. mBaiduMap.animateMapStatus(u);
  143. }
  144. if (points.size() == 5) {
  145. // 这里绘制起点
  146. drawStart(points);
  147. } else if (points.size() > 7) {
  148. points_tem = points.subList(points.size() - 4, points.size());
  149. options = new PolylineOptions().color(0xAAFF0000).width(6)
  150. .points(points_tem);
  151. mBaiduMap.addOverlay(options);
  152. }
  153. }
  154. public void onReceivePoi(BDLocation poiLocation) {
  155. }
  156. }
  157. @Override
  158. protected void onStop() {
  159. isStopLocClient = true;
  160. mLocationClient.stop();
  161. super.onStop();
  162. }
  163. /**
  164. * 绘制起点,取前n个点坐标的平均值绘制起点
  165. *
  166. * @param points2
  167. */
  168. public void drawStart(List<LatLng> points2) {
  169. double myLat = 0.0;
  170. double myLng = 0.0;
  171. for (LatLng ll : points2) {
  172. myLat += ll.latitude;
  173. myLng += ll.longitude;
  174. }
  175. LatLng avePoint = new LatLng(myLat / points2.size(), myLng
  176. / points2.size());
  177. points.add(avePoint);
  178. options = new DotOptions().center(avePoint).color(0xAA00ff00)
  179. .radius(15);
  180. mBaiduMap.addOverlay(options);
  181. }
  182. /**
  183. * 绘制终点。
  184. *
  185. * @param points2
  186. */
  187. protected void drawEnd(List<LatLng> points2) {
  188. double myLat = 0.0;
  189. double myLng = 0.0;
  190. if (points2.size() > 5) {// points肯定大于5,其实不用判断
  191. for (int i = points2.size() - 5; i < points2.size(); i++) {
  192. LatLng ll = points2.get(i);
  193. myLat += ll.latitude;
  194. myLng += ll.longitude;
  195. }
  196. LatLng avePoint = new LatLng(myLat / 5, myLng / 5);
  197. options = new DotOptions().center(avePoint).color(0xAAff00ff)
  198. .radius(15);
  199. mBaiduMap.addOverlay(options);
  200. }
  201. }
  202. @Override
  203. protected void onPause() {
  204. mMapView.onPause();
  205. super.onPause();
  206. }
  207. @Override
  208. protected void onResume() {
  209. mMapView.onResume();
  210. super.onResume();
  211. }
  212. @Override
  213. protected void onDestroy() {
  214. // 退出时销毁定位
  215. mLocationClient.stop();
  216. isStopLocClient = true;
  217. // 关闭定位图层
  218. mBaiduMap.setMyLocationEnabled(false);
  219. mMapView.onDestroy();
  220. mMapView = null;
  221. super.onDestroy();
  222. }
  223. }

 
到最后问题变成了如何利用这些坐标点画出轨迹。

如果每次都将points传入options = new PolylineOptions().color(0xAAFF0000).width(6).points(points);

随着points越来越大,画图也变得越来越慢,优化的地方便是:每次传入option中的点控制为某一常数,如10.这样每次只需绘制10个点便可。最优化可能是每次只画两个点,例如第一次画A1、A2,第二次画A2、A3,但是这样会出现明显的折线。具体如何优化,还请思考,如果你有比较好的想法,麻烦告知一下。注意:千万不可第一次画A1、A2,第二次画A3、A4,因为这样A2、A3会断裂开。

修改一下部分:

1.优化起点与重点的绘制方法。其实就是去几个坐标的平均值。

2.当GPS停止检测时,数据的获取会出现问题,所以需要添加一个定时器,定时检测LocationClient是否启动,若没有启动,则执行启动。

待解决:

1.测试时发现一些噪点,跟轨迹差别很大,需要考虑如何去除这类坐标。

2.绘制的轨迹棱角过于分明,考虑如何使之变得圆滑好看。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多