package com.example.tsdemo; import android.app.Activity; import android.os.Handler; import android.os.Looper; import java.util.ArrayList; import android.app.Activity; import android.os.Handler; import android.os.Looper; import android.util.Pair; import com.amap.api.maps.AMap; import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.CustomRenderer; import com.amap.api.maps.MapView; import com.amap.api.maps.UiSettings; import com.amap.api.maps.model.BitmapDescriptor; import com.amap.api.maps.model.BitmapDescriptorFactory; import com.amap.api.maps.model.LatLng; import com.amap.api.maps.model.LatLngBounds; import com.amap.api.maps.model.MyLocationStyle; import com.amap.api.maps.model.PolylineOptions; import com.amap.api.maps.model.Marker; import com.amap.api.maps.model.MarkerOptions; public class RecordAMapHelper { private Activity activity; private AMap mAMap; private MapView mapView; private UiSettings uiSettings; private PolylineOptions mPolylineOptions;//画线 private PathSmoothTool mpathSmoothTool;//平滑处理工具 官网下载 private final int maxZoomLevel = 16;//最大缩放 23最大 1最小 private int currentIndex; private Handler handler = new Handler(Looper.getMainLooper()); private final List<LatLng> resultList = new ArrayList<>();//数据过滤的时候 需要注意 private Marker tagMarker; private List<LatLng> mLatLngLists = new ArrayList<>(); private List<LatLng> mLatLngLists_move = new ArrayList<>(); public RecordAMapHelper(MapView mapView, Activity activity) { this.mapView = mapView; this.activity = activity; setMapSetting(); setUpMap(); currentIndex = 0; } private void setMapSetting() { mAMap = mapView.getMap(); mAMap.setMapType(AMap.MAP_TYPE_SATELLITE) mAMap.setMaxZoomLevel(maxZoomLevel); mAMap.setMapTextZIndex(2); mapView.getMap().moveCamera(CameraUpdateFactory.zoomTo(maxZoomLevel)) setMapUiSetting(); } private void setMapUiSetting() { uiSettings = mAMap.getUiSettings(); uiSettings.setMyLocationButtonEnabled(false);// 设置默认定位按钮是否显示 uiSettings.setZoomControlsEnabled(false);// 设置默认缩放按钮是否显示 uiSettings.setCompassEnabled(false);// 设置默认指南针是否显示 } public void setmLatLngLists(List<LatLng> mLatLngLists) { this.mLatLngLists.addAll(mLatLngLists); } public void addmLatLngLists_move(List<LatLng> mLatLngLists_move) { this.mLatLngLists_move.addAll(mLatLngLists_move); } private void setUpMap() { if (mAMap == null) { mAMap = mapView.getMap(); } mpathSmoothTool = new PathSmoothTool(); mpathSmoothTool.setIntensity(5); } private PolylineOptions initPolyline(List<LatLng> resultList) { mPolylineOptions = new PolylineOptions(); mPolylineOptions.color(0xff13E57B); mPolylineOptions.width(10f); mPolylineOptions.useGradient(false); mPolylineOptions.addAll(resultList); mPolylineOptions.setEraseColor(true, 0xffffffff); return mPolylineOptions; } Runnable runnable = new Runnable() { @Override public void run() { activity.runOnUiThread(() -> { //提升加载速度的话 设置currentIndex的值 结束了以后移除runner if (currentIndex >= mLatLngLists.size()) { handler.removeCallbacks(runnable); handler.postDelayed(completeRunnable, 1000); //走到最后一个点位的时候 移除小人显示 终点图标 if (tagMarker != null) { tagMarker.remove(); } if (resultList.size() > 1) { mAMap.addMarker(new MarkerOptions() .icon(getIconBitmap(1)) .position(mLatLngLists.get(mLatLngLists.size() - 1))); } } else { resultList.add(mLatLngLists.get(currentIndex)); currentIndex = currentIndex + 2;//循环获取➕2数据 可以过滤 +1 +2 +3 PolylineOptions options = initPolyline(resultList);//画线 每次进来数据都会++ mAMap.addPolyline(options);//添加到地图 tagMarker.setPosition(resultList.get(resultList.size() - 1));//小人的图标 //animateCamera 需要250毫秒才刷新一次 if (currentIndex % 50 == 0) { mAMap.animateCamera(CameraUpdateFactory.newLatLngZoom(resultList.get(resultList.size() - 1), maxZoomLevel)); } handler.postDelayed(this, 20); } }); } }; Runnable completeRunnable = new Runnable() { @Override public void run() { activity.runOnUiThread(() -> { setMapZoom(mLatLngLists); }); } }; private void setStartEndPoint() { // 增加起点开始 mAMap.addMarker(new MarkerOptions() .icon(getIconBitmap(0)) .position(mLatLngLists.get(0)) ); MarkerOptions option = new MarkerOptions(); option.anchor(0.5f, 0.5f) .icon(getIconBitmapTag()) .position(mLatLngLists.get(0)); tagMarker = mAMap.addMarker(option); } public void destroyAll() { handler.removeCallbacks(runnable); handler.removeCallbacks(completeRunnable); handler = null; } public BitmapDescriptor getIconBitmap(int type) { if (type == 1) { return BitmapDescriptorFactory.fromResource(R.mipmap.ic_sport_end); } else { return BitmapDescriptorFactory.fromResource(R.mipmap.ic_sport_start); } } public BitmapDescriptor getIconBitmapTag() { return BitmapDescriptorFactory.fromResource(R.mipmap.ic_sport_tag); } //在地图上添加本地轨迹数据,并处理 public void addLocpath() { if (mLatLngLists == null || mLatLngLists.isEmpty()) { return; } handler.postDelayed(runnable, 20); //增加起点 setStartEndPoint(); mAMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mLatLngLists.get(0), maxZoomLevel)); } //路线小人 平滑移动 官网上有 比自己写更加流畅 官网有的代码 public void moveMarker() { LatLng latLngStart = mLatLngLists_move.get(0); SmoothMoveMarker smoothMarker = new SmoothMoveMarker(mAMap); smoothMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.mipmap.ic_sport_tag)); Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(mLatLngLists_move, latLngStart); mLatLngLists_move.set(pair.first, latLngStart); List<LatLng> subList = mLatLngLists_move.subList(pair.first, mLatLngLists_move.size()); smoothMarker.setPoints(subList); smoothMarker.startSmoothMove(); } //newLatLngBounds 第二个参数 200 越大 显示的范围越大 public void setMapZoom(List<LatLng> latLngLists) { if (latLngLists != null && latLngLists.size() > 1) { LatLngBounds.Builder b = LatLngBounds.builder(); for (LatLng latLngList : latLngLists) { b.include(latLngList); } LatLngBounds bounds = b.build(); mAMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 150)); } else { LogUtil.e("缩放数据的大小小于1....."); } } } // use: // private ArrayList<LatLng> sportGPSData = new ArrayList<>(); // aMapHelper = new RecordAMapHelper(mapView, getActivity()); //aMapHelper.setmLatLngLists(sportGPSData); //aMapHelper.addmLatLngLists_move(sportGPSData); //aMapHelper.addLocpath();
1.使用handler post方法控制小人移动的速度
2.高德地图中animateCamera 跟其他移动到中心点的方法不太一样 注意,其中一个直接写地图缩放等级用的比较多 还有 bound 设置200这种 用法不一样看你自己需要
3.官网提供的轨迹平滑移动会过滤掉很多点坐标,不建议使用
4.在app切换到后台的时候 无法准确获取到定位坐标,会导致在路线绘制的时候一跳一跳的 ,或者本身定位的时候差异 在50米以上的时候 也会出现,目前暂时未解决,只有应用一直在前台的时候才不会出现该问题
5.在运动的时候通过他官网的计算两个点距离的方法过滤掉小于1.5米的会更加准确
6.计算运动移动的距离的时候如果是通过点坐标来计算获得的话 ,后面再绘制路线的时候更好把控,不然加业务需求的时候无法精准计算他的运动时间 还有每一公里的数值,导致计算不准确
7.定义成工具类不好操作ui页面,