百度地图小车移动
来源:互联网 发布:淘宝卖食品备案怎么弄 编辑:程序博客网 时间:2024/04/27 19:18
基于百度地图,覆盖物(小车)平滑移动
先看一下效果
直接贴上源码
import android.app.Activity;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.MapStatusUpdate;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.model.LatLng;/** * 平滑测试 */public class MapTest1 extends Activity { private MapView mMapView; private BaiduMap mBaiduMap; private Marker mMoveMarker;// 定义地图 Marker 覆盖物 private Handler mHandler; // 通过设置间隔时间和距离可以控制速度和图标移动的距离 private int TIME_INTERVAL = 80;// 时间间隔,线程休息的间隔 private double DISTANCE = 0;// 距离 private int time = 3000;// 每隔3秒钟,模拟掉一次获取位置的接口 private int moveFinishInterval = 4000;// 4秒钟内,完成移动 private int pointIndex = 0;// 取位置的下标 LatLng startPoint; Handler pointHandler = new Handler(); Runnable runnable = new Runnable() { @Override public void run() { // 模拟每次掉接口拿到的数据 if (pointIndex >= latlngs.length - 1) { pointIndex = 0; } LatLng endPoint = latlngs[++pointIndex]; carMove(startPoint, endPoint); startPoint = endPoint; pointHandler.postDelayed(this, time); } }; /** * 这一段的总长度 * 用两个点的经纬度和勾股定理,求得两个点之间的连线长度 */ private double getLength(LatLng fromPoint, LatLng toPoint) { if (toPoint.longitude == fromPoint.longitude) { return Double.MAX_VALUE; } return Math.sqrt(Math.pow(Math.abs(toPoint.latitude - fromPoint.latitude), 2) + Math.pow(Math.abs(toPoint.longitude - fromPoint.longitude), 2)); } /** * 小车移动的逻辑 */ private void carMove(final LatLng startPoint, final LatLng endPoint) { new Thread() { @Override public void run() { super.run(); mMoveMarker.setPosition(startPoint);// 设置 Marker 覆盖物的位置坐标 mHandler.post(new Runnable() { @Override public void run() { // 更新覆盖物的旋转角度 if (mMapView == null) { return; } mMoveMarker.setRotate((float) getAngle(startPoint, endPoint));// 设置 Marker 覆盖物旋转角度,逆时针 } }); boolean xIsReverse = endPoint.latitude > startPoint.latitude;// x方向,像右是正方向 boolean yIsReverse = endPoint.longitude > startPoint.longitude;// y方向,像上是正方向 double length = getLength(startPoint, endPoint);// 求得两个点之间的连线长度 DISTANCE = length / (moveFinishInterval / TIME_INTERVAL);// 每4000/80毫秒移动的距离 double xMove = xMoveDistance(startPoint, endPoint, DISTANCE, length);// 计算每次x方向上移动的距离 double yMove = yMoveDistance(startPoint, endPoint, DISTANCE, length);// 计算每次y方向上移动的距离 for (int i = 0; i < moveFinishInterval / TIME_INTERVAL; i++) {// 遍历4000/80次 double x, y; if (xIsReverse) {// 向右移动 x = startPoint.latitude + i * xMove; } else {// 向左移动 x = startPoint.latitude - i * xMove; } if (yIsReverse) {// 向上 y = startPoint.longitude + i * yMove; } else {// 向下 y = startPoint.longitude - i * yMove; } LatLng latLng = new LatLng(x, y); final LatLng finalLatLng = latLng; mHandler.post(new Runnable() { @Override public void run() { if (mMapView == null) { return; } // 刷新覆盖物的位置 mMoveMarker.setPosition(finalLatLng); } }); try { Thread.sleep(moveFinishInterval / TIME_INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } /** * X方向移动的距离 */ private double xMoveDistance(LatLng startPoint, LatLng endPoint, double DISTANCE, double length) { return Math.abs((endPoint.latitude - startPoint.latitude) / length * DISTANCE); } /** * Y方向移动的距离 */ private double yMoveDistance(LatLng startPoint, LatLng endPoint, double DISTANCE, double length) { return Math.abs((endPoint.longitude - startPoint.longitude) / length * DISTANCE); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map_test); mMapView = (MapView) findViewById(R.id.bmapView); mMapView.onCreate(this, savedInstanceState); mBaiduMap = mMapView.getMap(); mHandler = new Handler(Looper.getMainLooper()); intiMarker(); startPoint = latlngs[pointIndex]; pointHandler.postDelayed(runnable, time);// 每3秒执行一次runnable. } /** * 初始化覆盖物 */ private void intiMarker() { OverlayOptions markerOptions = new MarkerOptions().flat(true).anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory .fromResource(R.drawable.icon_bus_logo)).position(latlngs[0]).rotate((float) getAngle(latlngs[0], latlngs[1])); // 添加覆盖物小车的图标 mMoveMarker = (Marker) mBaiduMap.addOverlay(markerOptions); // 移动位置 MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.newLatLng(latlngs[0]); if (mBaiduMap != null && mapStatusUpdate != null) { mBaiduMap.animateMapStatus(mapStatusUpdate); } } /** * 根据两点算取图标转的角度 */ 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; } /** * 算斜率 * 结束的维度减去开始的维度(横) / 结束的经度减去开始的经度(竖) * x / y */ 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); pointHandler.removeCallbacks(runnable); mMapView.onSaveInstanceState(outState); } /** * 方法必须重写 */ @Override protected void onDestroy() { super.onDestroy(); mMapView.onDestroy(); mBaiduMap.clear(); } 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), };}
大多地方都添加了注释,具体思路就是,每次获取车的位置时,根据这次的位置和上个获取的位置来做移动逻辑(所以和车辆实际的位置会有延迟)。我模拟的数据是每隔3秒调用一次接口,然后4秒钟完成小车移动的逻辑。因为是在循环里不停的设置小车的位置,所以感觉整个小车移动感觉不太平滑,不知道怎么用动画来设置,如果有人做过,可以告诉我。
以上
阅读全文
0 0
- 百度地图小车移动
- iOS 百度地图路线绘制与小车平滑移动
- 类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(轨迹已画好)
- 类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(无轨迹)
- 百度地图-定时器移动地图
- 百度地图——显示小车轨迹动画回放
- 百度移动地图API1.1
- 百度地图移动版API简介(Android)
- 百度迅速开启移动地图入口争夺战
- 移动百度地图常用功能全集
- 移动百度地图常用功能全集
- android 百度地图移动覆盖物
- android 移动应用调用百度地图
- 移动端、手机调用百度地图 Demo
- 百度地图之定位+移动选址
- 百度地图 baiduMap(三) 移动轨迹
- 移动端调用百度地图APP导航
- Android 百度地图 Marker 平滑移动
- 把二叉树打印成多行java实现
- 问题记录--studio run 报错:INSTALL_FAILED_INTERNAL_ERROR
- 自学Node.js: WebStorm+Node.js开发环境的配置
- 《Spring技术内幕》学习笔记7——AOP基础
- fabric
- 百度地图小车移动
- 高德定位后缩放级别的设置
- Binder机制原理浅析
- 微信小程序 wepy wx.previewImage 封装
- java SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- 深度学习:CS231n官方笔记
- 如何在 Windows 下像 Mac 一样优雅开发
- 是的,今天要颁奖了
- Linux磁盘空间被占用问题,根目录满了,df和du占用不一样【转】