<span style='font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);'>一直想做一个记录自己运动轨迹的app,只是不知如何绘制轨迹。看了百度地图API中的demo,其实很简单。</span>
核心代码只有两句: options = new PolylineOptions().color(0xAAFF0000).width(6) mBaiduMap.addOverlay(options);
其中points是坐标的集合,大小size>=2&&size<=1000
完整的测试代码如下:--修改版(解决了中间GPS停止,获取不到数据的情况) <pre name='code' class='java'>package com.kelly.mapdemo; import java.util.ArrayList; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import com.baidu.location.BDLocation; import com.baidu.location.BDLocationListener; import com.baidu.location.LocationClient; import com.baidu.location.LocationClientOption; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BitmapDescriptor; import com.baidu.mapapi.map.DotOptions; import com.baidu.mapapi.map.MapStatusUpdate; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.MyLocationData; import com.baidu.mapapi.map.OverlayOptions; import com.baidu.mapapi.map.PolylineOptions; import com.baidu.mapapi.model.LatLng; public class MyRouteActivity extends Activity { private LocationClient mLocationClient; BitmapDescriptor mCurrentMarker; boolean isFirstLoc = true;// 是否首次定位 List<LatLng> points = new ArrayList<LatLng>(); List<LatLng> points_tem = new ArrayList<LatLng>(); // 定时器相关,定时检查GPS是否开启(这里只须检查mLocationClient是否启动) Handler handler = new Handler(); boolean isStopLocClient = false; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_myroute); // points.add(new LatLng(34.2376, 108.9923)); handler.postDelayed(new MyRunable(), 3000); mMapView = (MapView) findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); but_start = (Button) findViewById(R.id.but_start); but_stop = (Button) findViewById(R.id.but_stop); but_start.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (!mLocationClient.isStarted()) { but_stop.setOnClickListener(new OnClickListener() { public void onClick(View v) { if (mLocationClient.isStarted()) { class MyRunable implements Runnable { if (!mLocationClient.isStarted()) { handler.postDelayed(this, 3000); protected void drawMyRoute(List<LatLng> points2) { OverlayOptions options = new PolylineOptions().color(0xAAFF0000) .width(10).points(points2); mBaiduMap.addOverlay(options); public void initLocation() { mBaiduMap.setMyLocationEnabled(true); mLocationClient = new LocationClient(this); mLocationClient.registerLocationListener(new MyLocationListenner()); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true);// 打开gps option.setAddrType('all');// 返回的定位结果包含地址信息,(注意如果想获取关于地址的信息,这里必须进行设置) option.setCoorType('bd09ll'); // 设置坐标类型 option.setScanSpan(1000); // 当gps可用,而且获取了定位结果时,不再发起网络请求,直接返回给用户坐标。这个选项适合希望得到准确坐标位置的用户。如果gps不可用,再发起网络请求,进行定位。 option.setPriority(LocationClientOption.GpsFirst); // option.setPriority(LocationClientOption.NetWorkFirst); mLocationClient.setLocOption(option); class MyLocationListenner implements BDLocationListener { public void onReceiveLocation(BDLocation location) { // map view 销毁后不在处理新接收的位置 if (location == null || mMapView == null) // 如果不显示定位精度圈,将accuracy赋值为0即可 MyLocationData locData = new MyLocationData.Builder().accuracy(0) .latitude(location.getLatitude()) .longitude(location.getLongitude()).build(); mBaiduMap.setMyLocationData(locData); LatLng point = new LatLng(location.getLatitude(), location.getLongitude()); LatLng ll = new LatLng(location.getLatitude(), location.getLongitude()); MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll); mBaiduMap.animateMapStatus(u); if (points.size() == 5) { } else if (points.size() > 7) { points_tem = points.subList(points.size() - 4, points.size()); options = new PolylineOptions().color(0xAAFF0000).width(6) mBaiduMap.addOverlay(options); public void onReceivePoi(BDLocation poiLocation) { protected void onStop() { public void drawStart(List<LatLng> points2) { for (LatLng ll : points2) { LatLng avePoint = new LatLng(myLat / points2.size(), myLng options = new DotOptions().center(avePoint).color(0xAA00ff00) mBaiduMap.addOverlay(options); protected void drawEnd(List<LatLng> points2) { if (points2.size() > 5) {// points肯定大于5,其实不用判断 for (int i = points2.size() - 5; i < points2.size(); i++) { LatLng ll = points2.get(i); LatLng avePoint = new LatLng(myLat / 5, myLng / 5); options = new DotOptions().center(avePoint).color(0xAAff00ff) mBaiduMap.addOverlay(options); protected void onPause() { protected void onResume() { protected void onDestroy() { mBaiduMap.setMyLocationEnabled(false);
到最后问题变成了如何利用这些坐标点画出轨迹。
如果每次都将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.绘制的轨迹棱角过于分明,考虑如何使之变得圆滑好看。
|