类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(轨迹已画好)

参考百度地图demo:轨迹运行demo展示,类名TrackShowDemo。百度TrackShowDemo类里只实现了一个完整的轨迹运行,并且是将所有的经纬点放在一个数组里,我觉得直接放在一个List集合里更好点。

先看一下完整的百度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();
        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.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));
//        	moveLooper(tuoche.get(i));
        }
    }

    private void drawPolyLine(List<LatLng> polylines) {

    			polylines.add(polylines.get(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 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));
    }
    
}


资源与“类似滴滴打车,多辆小车在地图上平滑移动的实现,基于百度地图实现(无轨迹)”文章资源相同,只需下载一份就好。

代码传送门



  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值