类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(无轨迹)
2017-05-26 23:28
525 查看
参考百度地图demo:轨迹运行demo展示,类名TrackShowDemo。百度TrackShowDemo类里只实现了一个完整的轨迹运行,并且是将所有的经纬点放在一个数组里,我觉得直接放在一个List集合里更好点。
先看一下完整的百度demo
先看一下完整的百度demo
/* * Copyright (C) 2016 Baidu, Inc. All Rights Reserved. */ package baidumapsdk.demo.map; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BitmapDescriptorFactory; import com.baidu.mapapi.map.MapStatus; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.Marker; import com.baidu.mapapi.map.MarkerOptions; import com.baidu.mapapi.map.OverlayOptions; import com.baidu.mapapi.map.Polyline; import com.baidu.mapapi.map.PolylineOptions; import com.baidu.mapapi.model.LatLng; import java.util.ArrayList; import java.util.List; import baidumapsdk.demo.R; /** * 轨迹运行demo展示 */ public class TrackShowDemo extends Activity { private MapView mMapView; private BaiduMap mBaiduMap; private Polyline mPolyline; private Marker mMoveMarker; private Handler mHandler; // 通过设置间隔时间和距离可以控制速度和图标移动的距离 private static final int TIME_INTERVAL = 80; private static final double DISTANCE = 0.00002; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMapView = (MapView) findViewById(R.id.bmapView); mMapView.onCreate(this, savedInstanceState); mBaiduMap = mMapView.getMap(); MapStatus.Builder builder = new MapStatus.Builder(); builder.target(new LatLng(40.056865, 116.307766)); builder.zoom(19.0f); mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); mHandler = new Handler(Looper.getMainLooper()); drawPolyLine(); moveLooper(); } private void drawPolyLine() { List<LatLng> polylines = new ArrayList<LatLng>(); for (int index = 0; index < latlngs.length; index++) { polylines.add(latlngs[index]); } polylines.add(latlngs[0]); PolylineOptions polylineOptions = new PolylineOptions().points(polylines).width(10).color(Color.RED); mPolyline = (Polyline) mBaiduMap.addOverlay(polylineOptions); OverlayOptions markerOptions; markerOptions = new MarkerOptions().flat(true).anchor(0.5f, 0.5f) .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)).position(polylines.get(0)) .rotate((float) getAngle(0)); mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions); } /** * 根据点获取图标转的角度 */ private double getAngle(int startIndex) { if ((startIndex + 1) >= mPolyline.getPoints().size()) { throw new RuntimeException("index out of bonds"); } LatLng startPoint = mPolyline.getPoints().get(startIndex); LatLng endPoint = mPolyline.getPoints().get(startIndex + 1); return getAngle(startPoint, endPoint); } /** * 根据两点算取图标转的角度 */ 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); double angle = 180 * (radio / Math.PI) + deltAngle - 90; return angle; } /** * 根据点和斜率算取截距 */ private double getInterception(double slope, LatLng point) { double interception = point.latitude - slope * point.longitude; return interception; } /** * 算斜率 */ private double getSlope(LatLng fromPoint, LatLng toPoint) { if (toPoint.longitude == fromPoint.longitude) { return Double.MAX_VALUE; } double slope = ((toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude)); return slope; } @Override protected void onResume() { super.onResume(); mMapView.onResume(); } @Override protected void onPause() { super.onPause(); mMapView.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mMapView.onSaveInstanceState(outState); } @Override protected void onDestroy() { super.onDestroy 10c57 (); mMapView.onDestroy(); mBaiduMap.clear(); } /** * 计算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() { new Thread() { public void run() { while (true) { for (int i = 0; i < latlngs.length - 1; i++) { final LatLng startPoint = latlngs[i]; final LatLng endPoint = latlngs[i + 1]; mMoveMarker .setPosition(startPoint); mHandler.post(new Runnable() { @Override public void run() { // refresh marker's rotate if (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 = null; 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() { @Override public void run() { if (mMapView == null) { return; } mMoveMarker.setPosition(finalLatLng); } }); try { Thread.sleep(TIME_INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }.start(); } private static final LatLng[] latlngs = new LatLng[] { new LatLng(40.055826, 116.307917), new LatLng(40.055916, 116.308455), new LatLng(40.055967, 116.308549), new LatLng(40.056014, 116.308574), new LatLng(40.056440, 116.308485), new LatLng(40.056816, 116.308352), new LatLng(40.057997, 116.307725), new LatLng(40.058022, 116.307693), new LatLng(40.058029, 116.307590), new LatLng(40.057913, 116.307119), new LatLng(40.057850, 116.306945), new LatLng(40.057756, 116.306915), new LatLng(40.057225, 116.307164), new LatLng(40.056134, 116.307546), new LatLng(40.055879, 116.307636), new LatLng(40.055826, 116.307697), }; }
改造后:
package com.xpro.ibusalmoner.activity; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; import com.baidu.mapapi.SDKInitializer; import com.baidu.mapapi.map.BaiduMap; import com.baidu.mapapi.map.BitmapDescriptorFactory; import com.baidu.mapapi.map.DotOptions; import com.baidu.mapapi.map.MapStatus; import com.baidu.mapapi.map.MapStatusUpdateFactory; import com.baidu.mapapi.map.MapView; import com.baidu.mapapi.map.Marker; import com.baidu.mapapi.map.MarkerOptions; import com.baidu.mapapi.map.OverlayOptions; import com.baidu.mapapi.map.Polyline; import com.baidu.mapapi.map.PolylineOptions; import com.baidu.mapapi.model.LatLng; import com.xpro.ibusalmoner.R; /** * 轨迹运行demo展示 */ public class SeeMapActivity extends Activity { private MapView mMapView; private BaiduMap mBaiduMap; private Polyline mPolyline; // private Marker mMoveMarker; private Handler mHandler; private List<List<LatLng>> tuoche; private List<LatLng> latlngs1;//拖车1经纬度集合 private List<LatLng> latlngs2;//拖车2经纬度集合 // 通过设置间隔时间和距离可以控制速度和图标移动的距离 private static final int TIME_INTERVAL = 80; private static final double DISTANCE = 0.00009; // private static final double DISTANCE = 0.00002; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_seemap); mMapView = (MapView) findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); MapStatus.Builder builder = new MapStatus.Builder(); builder.target(new LatLng(31.9695208489,118.7736524881));//故障车当前位置 builder.zoom(19.0f); mBaiduMap.setMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build())); mHandler = new Handler(Looper.getMainLooper()); initData(); for(int i=0;i<tuoche.size();i++){ drawPolyLine(tuoche.get(i)); } } private void drawPolyLine(List<LatLng> polylines) { // polylines.add(polylines.get(0));//将轨迹连成一个完整的环形 OverlayOptions markerOptions; markerOptions = new MarkerOptions().flat(true).anchor(0.5f, 0.5f) .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)). position(polylines.get(0)); //mMoveMarker局部变量,一辆小车一个移动箭头 Marker mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions); moveLooper(polylines,mMoveMarker); } /** * 循环进行移动逻辑 */ public void moveLooper(final List<LatLng> polylines,final Marker mMoveMarker) { new Thread() { public void run() { while (true) { for (int i = 0; i < polylines.size() - 1; i++) { final LatLng startPoint = polylines.get(i); final LatLng endPoint = polylines.get(i+1); Log.e("--", startPoint.latitude+"/"+startPoint.longitude); mMoveMarker.setPosition(startPoint); mHandler.post(new Runnable() { @Override public void run() { // refresh marker's rotate if (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 = null; 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() { @Override public void run() { if (mMapView == null) { return; } mMoveMarker.setPosition(finalLatLng);//走完一圈回到起点 } }); try { Thread.sleep(TIME_INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }.start(); } //拖车经纬度集合 public void initData(){ tuoche=new ArrayList<List<LatLng>>(); latlngs1=new ArrayList<LatLng>(); //第一辆车经纬度集合 latlngs2=new ArrayList<LatLng>();//第二辆车经纬度集合 latlngs1.add(new LatLng(31.9697048489,118.7748744881)); latlngs1.add(new LatLng(31.9702354581,118.7747304881)); latlngs1.add(new LatLng(31.9874731546,118.7744525592)); latlngs1.add(new LatLng(31.9961700713,118.7757586264)); latlngs1.add(new LatLng(32.0048694174,118.7774854183)); latlngs1.add(new LatLng(32.0037307114,118.7824144492)); latlngs1.add(new LatLng(31.9962609086,118.7872986406)); latlngs1.add(new LatLng(31.9944540133,118.7914938260)); latlngs1.add(new LatLng(31.9906570133,118.7968118260)); latlngs2.add(new LatLng(31.9733642960,118.7662912632)); latlngs2.add(new LatLng(31.9735350000,118.7557740000)); latlngs2.add(new LatLng(31.9714564110,118.7504893514)); latlngs2.add(new LatLng(31.9755604110,118.7513513514)); latlngs2.add(new LatLng(31.9767854110,118.7518543514)); latlngs2.add(new LatLng(31.9776434110,118.7491953514)); latlngs2.add(new LatLng(31.9812311339,118.7433553933)); tuoche.add(latlngs1); tuoche.add(latlngs2); } /** * 根据点获取图标转的角度 */ private double getAngle(int startIndex) { if ((startIndex + 1) >= mPolyline.getPoints().size()) { throw new RuntimeException("index out of bonds"); } LatLng startPoint = mPolyline.getPoints().get(startIndex); LatLng endPoint = mPolyline.getPoints().get(startIndex + 1); return getAngle(startPoint, endPoint); } /** * 根据两点算取图标转的角度 */ 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); double angle = 180 * (radio / Math.PI) + deltAngle - 90; return angle; } /** * 根据点和斜率算取截距 */ private double getInterception(double slope, LatLng point) { double interception = point.latitude - slope * point.longitude; return interception; } /** * 算斜率 */ private double getSlope(LatLng fromPoint, LatLng toPoint) { if (toPoint.longitude == fromPoint.longitude) { return Double.MAX_VALUE; } double slope = ((toPoint.latitude - fromPoint.latitude) / (toPoint.longitude - fromPoint.longitude)); return slope; } @Override protected void onResume() { super.onResume(); mMapView.onResume(); } @Override protected void onPause() { super.onPause(); mMapView.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // mMapView.onSaveInstanceState(outState); } @Override protected void onDestroy() { super.onDestroy(); mMapView.onDestroy(); mBaiduMap.clear(); } /** * 计算x方向每次移动的距离 */ private double getXMoveDistance(double slope) { if (slope == Double.MAX_VALUE) { return DISTANCE; } return Math.abs((DISTANCE * slope) / Math.sqrt(1 + slope * slope)); } }
相关文章推荐
- 类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(轨迹已画好)
- 类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(无轨迹)
- Android 滴滴打车,打车软件客户端实现小车在地图上平滑移动的实现;基于高德地图V4.1.1+
- 滴滴打车,打车软件app实现。小车在地图上平滑移动的实现,Android,基于高德地图开发实现
- 滴滴打车,打车软件app实现。小车在地图上平滑移动的实现,Android,基于高德地图开发实现
- Unity 实现类似 QQ泡泡堂一样平滑行走的 基于Tile的移动算法
- 关于地图中轨迹的平滑移动的实现
- Android开发实现距离位置变化(类似滴滴打车附件的车辆)
- Android基于mAppWidget实现手绘地图(十一)–移动地图到某个坐标
- 基于百度地图记录运动轨迹案例分析与实现
- 仿滴滴打车的平滑移动附近车辆效果实现全流程,基于高德地图
- 属性动画实现控件类似贝塞尔曲线轨迹移动效果
- 属性动画实现控件类似贝塞尔曲线轨迹移动效果
- 属性动画实现控件类似贝塞尔曲线轨迹移动效果
- 基于百度地图记录运动轨迹案例分析与实现
- 基于jquery的从一个页面跳转到另一个页面的指定位置的实现代码(带平滑移动的效果)
- 基于百度地图记录运动轨迹案例分析与实现
- 属性动画实现控件类似贝塞尔曲线轨迹移动效果
- 属性动画实现控件类似贝塞尔曲线轨迹移动效果
- 百度地图实现车辆轨迹移动播放(baidu map api)