百度地图小车移动

来源:互联网 发布:淘宝卖食品备案怎么弄 编辑:程序博客网 时间: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秒钟完成小车移动的逻辑。因为是在循环里不停的设置小车的位置,所以感觉整个小车移动感觉不太平滑,不知道怎么用动画来设置,如果有人做过,可以告诉我。
以上
原创粉丝点击