前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android 高德地图API(详细步骤+源码)五

Android 高德地图API(详细步骤+源码)五

原创
作者头像
晨曦_LLW
修改于 2021-03-05 02:35:22
修改于 2021-03-05 02:35:22
2.3K00
代码可运行
举报
运行总次数:0
代码可运行

④ 驾车路线规划

  现在来写这个驾车路线规划,步骤还是和前面的差不多,这回你都不用改布局了,加一个值,如下所示

在这里插入图片描述

然后找到startRouteSearch方法,加一个驾车的条件分支

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
			case 2://驾车
                //构建驾车路线搜索对象  剩余三个参数分别是:途经点、避让区域、避让道路
                RouteSearch.DriveRouteQuery driveQuery = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.WalkDefault, null, null, "");
                //驾车规划路径计算
                routeSearch.calculateDriveRouteAsyn(driveQuery);
                break;

然后同样要有一个图层。在overlay包下新增DrivingRouteOverlay类,用于在地图上绘制驾车路线图层,代码如下:(SDK中代码)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.llw.mapdemo.overlay;

import android.content.Context;
import android.graphics.Color;

import com.amap.api.maps.AMap;
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.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveStep;
import com.amap.api.services.route.TMC;
import com.llw.mapdemo.R;
import com.llw.mapdemo.util.MapUtil;

import java.util.ArrayList;
import java.util.List;


/**
 * 驾车路线图层类
 */
public class DrivingRouteOverlay extends RouteOverlay{

	private DrivePath drivePath;
    private List<LatLonPoint> throughPointList;
    private List<Marker> throughPointMarkerList = new ArrayList<Marker>();
    private boolean throughPointMarkerVisible = true;
    private List<TMC> tmcs;
    private PolylineOptions mPolylineOptions;
    private PolylineOptions mPolylineOptionscolor;
    private Context mContext;
    private boolean isColorfulline = true;
    private float mWidth = 25;
    private List<LatLng> mLatLngsOfPath;

	public void setIsColorfulline(boolean iscolorfulline) {
		this.isColorfulline = iscolorfulline;
	}

	/**
     * 根据给定的参数,构造一个导航路线图层类对象。
     *
     * @param amap      地图对象。
     * @param path 导航路线规划方案。
     * @param context   当前的activity对象。
     */
    public DrivingRouteOverlay(Context context, AMap amap, DrivePath path,
                               LatLonPoint start, LatLonPoint end, List<LatLonPoint> throughPointList) {
    	super(context);
    	mContext = context; 
        mAMap = amap; 
        this.drivePath = path;
        startPoint = MapUtil.convertToLatLng(start);
        endPoint = MapUtil.convertToLatLng(end);
        this.throughPointList = throughPointList;
    }

    @Override
    public float getRouteWidth() {
        return mWidth;
    }

    /**
     * 设置路线宽度
     *
     * @param mWidth 路线宽度,取值范围:大于0
     */
    public void setRouteWidth(float mWidth) {
        this.mWidth = mWidth;
    }

    /**
     * 添加驾车路线添加到地图上显示。
     */
	public void addToMap() {
		initPolylineOptions();
        try {
            if (mAMap == null) {
                return;
            }

            if (mWidth == 0 || drivePath == null) {
                return;
            }
            mLatLngsOfPath = new ArrayList<LatLng>();
            tmcs = new ArrayList<TMC>();
            List<DriveStep> drivePaths = drivePath.getSteps();
            for (DriveStep step : drivePaths) {
                List<LatLonPoint> latlonPoints = step.getPolyline();
                List<TMC> tmclist = step.getTMCs();
                tmcs.addAll(tmclist);
                addDrivingStationMarkers(step, convertToLatLng(latlonPoints.get(0)));
                for (LatLonPoint latlonpoint : latlonPoints) {
                	mPolylineOptions.add(convertToLatLng(latlonpoint));
                	mLatLngsOfPath.add(convertToLatLng(latlonpoint));
				}
            }
            if (startMarker != null) {
                startMarker.remove();
                startMarker = null;
            }
            if (endMarker != null) {
                endMarker.remove();
                endMarker = null;
            }
            addStartAndEndMarker();
            addThroughPointMarker();
            if (isColorfulline && tmcs.size()>0 ) {
            	colorWayUpdate(tmcs);
            	showcolorPolyline();
			}else {
				showPolyline();
			}            
            
        } catch (Throwable e) {
        	e.printStackTrace();
        }
    }

	/**
     * 初始化线段属性
     */
    private void initPolylineOptions() {

        mPolylineOptions = null;

        mPolylineOptions = new PolylineOptions();
        mPolylineOptions.color(getDriveColor()).width(getRouteWidth());
    }

    private void showPolyline() {
        addPolyLine(mPolylineOptions);
    }
    
    private void showcolorPolyline() {
    	addPolyLine(mPolylineOptionscolor);
		
	}

    /**
     * 根据不同的路段拥堵情况展示不同的颜色
     *
     * @param tmcSection
     */
    private void colorWayUpdate(List<TMC> tmcSection) {
        if (mAMap == null) {
            return;
        }
        if (tmcSection == null || tmcSection.size() <= 0) {
            return;
        }
        TMC segmentTrafficStatus;
        mPolylineOptionscolor = null;
        mPolylineOptionscolor = new PolylineOptions();
        mPolylineOptionscolor.width(getRouteWidth());
        List<Integer> colorList = new ArrayList<Integer>();
        mPolylineOptionscolor.add(MapUtil.convertToLatLng(tmcSection.get(0).getPolyline().get(0)));
        colorList.add(getDriveColor());
        for (int i = 0; i < tmcSection.size(); i++) {
        	segmentTrafficStatus = tmcSection.get(i);
        	int color = getcolor(segmentTrafficStatus.getStatus());
        	List<LatLonPoint> mployline = segmentTrafficStatus.getPolyline();
			for (int j = 1; j < mployline.size(); j++) {
				mPolylineOptionscolor.add(MapUtil.convertToLatLng(mployline.get(j)));
				colorList.add(color);
			}
		}
        colorList.add(getDriveColor());
        mPolylineOptionscolor.colorValues(colorList);
    }
    
    private int getcolor(String status) {

    	if (status.equals("畅通")) {
    		return Color.GREEN;
		} else if (status.equals("缓行")) {
			 return Color.YELLOW;
		} else if (status.equals("拥堵")) {
			return Color.RED;
		} else if (status.equals("严重拥堵")) {
			return Color.parseColor("#990033");
		} else {
			return Color.parseColor("#537edc");
		}	
	}

	public LatLng convertToLatLng(LatLonPoint point) {
        return new LatLng(point.getLatitude(),point.getLongitude());
  }
    
    /**
     * @param driveStep
     * @param latLng
     */
    private void addDrivingStationMarkers(DriveStep driveStep, LatLng latLng) {
        addStationMarker(new MarkerOptions()
                .position(latLng)
                .title("\u65B9\u5411:" + driveStep.getAction()
                        + "\n\u9053\u8DEF:" + driveStep.getRoad())
                .snippet(driveStep.getInstruction()).visible(nodeIconVisible)
                .anchor(0.5f, 0.5f).icon(getDriveBitmapDescriptor()));
    }

    @Override
    protected LatLngBounds getLatLngBounds() {
        LatLngBounds.Builder b = LatLngBounds.builder();
        b.include(new LatLng(startPoint.latitude, startPoint.longitude));
        b.include(new LatLng(endPoint.latitude, endPoint.longitude));
        if (this.throughPointList != null && this.throughPointList.size() > 0) {
            for (int i = 0; i < this.throughPointList.size(); i++) {
                b.include(new LatLng(
                        this.throughPointList.get(i).getLatitude(),
                        this.throughPointList.get(i).getLongitude()));
            }
        }
        return b.build();
    }

    public void setThroughPointIconVisibility(boolean visible) {
        try {
            throughPointMarkerVisible = visible;
            if (this.throughPointMarkerList != null
                    && this.throughPointMarkerList.size() > 0) {
                for (int i = 0; i < this.throughPointMarkerList.size(); i++) {
                    this.throughPointMarkerList.get(i).setVisible(visible);
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
    
    private void addThroughPointMarker() {
        if (this.throughPointList != null && this.throughPointList.size() > 0) {
            LatLonPoint latLonPoint = null;
            for (int i = 0; i < this.throughPointList.size(); i++) {
                latLonPoint = this.throughPointList.get(i);
                if (latLonPoint != null) {
                    throughPointMarkerList.add(mAMap
                            .addMarker((new MarkerOptions())
                                    .position(
                                            new LatLng(latLonPoint
                                                    .getLatitude(), latLonPoint
                                                    .getLongitude()))
                                    .visible(throughPointMarkerVisible)
                                    .icon(getThroughPointBitDes())
                                    .title("\u9014\u7ECF\u70B9")));
                }
            }
        }
    }
    
    private BitmapDescriptor getThroughPointBitDes() {
    	return BitmapDescriptorFactory.fromResource(R.drawable.amap_through);
       
    }

    /**
     * 获取两点间距离
     *
     * @param start
     * @param end
     * @return
     */
    public static int calculateDistance(LatLng start, LatLng end) {
        double x1 = start.longitude;
        double y1 = start.latitude;
        double x2 = end.longitude;
        double y2 = end.latitude;
        return calculateDistance(x1, y1, x2, y2);
    }

    public static int calculateDistance(double x1, double y1, double x2, double y2) {
        final double NF_pi = 0.01745329251994329; // 弧度 PI/180
        x1 *= NF_pi;
        y1 *= NF_pi;
        x2 *= NF_pi;
        y2 *= NF_pi;
        double sinx1 = Math.sin(x1);
        double siny1 = Math.sin(y1);
        double cosx1 = Math.cos(x1);
        double cosy1 = Math.cos(y1);
        double sinx2 = Math.sin(x2);
        double siny2 = Math.sin(y2);
        double cosx2 = Math.cos(x2);
        double cosy2 = Math.cos(y2);
        double[] v1 = new double[3];
        v1[0] = cosy1 * cosx1 - cosy2 * cosx2;
        v1[1] = cosy1 * sinx1 - cosy2 * sinx2;
        v1[2] = siny1 - siny2;
        double dist = Math.sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]);

        return (int) (Math.asin(dist / 2) * 12742001.5798544);
    }


    //获取指定两点之间固定距离点
    public static LatLng getPointForDis(LatLng sPt, LatLng ePt, double dis) {
        double lSegLength = calculateDistance(sPt, ePt);
        double preResult = dis / lSegLength;
        return new LatLng((ePt.latitude - sPt.latitude) * preResult + sPt.latitude, (ePt.longitude - sPt.longitude) * preResult + sPt.longitude);
    }
    /**
     * 去掉DriveLineOverlay上的线段和标记。
     */
    @Override
    public void removeFromMap() {
        try {
            super.removeFromMap();
            if (this.throughPointMarkerList != null
                    && this.throughPointMarkerList.size() > 0) {
                for (int i = 0; i < this.throughPointMarkerList.size(); i++) {
                    this.throughPointMarkerList.get(i).remove();
                }
                this.throughPointMarkerList.clear();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

然后回到RouteActivity中,找到onDriveRouteSearched方法,里面的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	/**
     * 驾车规划路径结果
     *
     * @param driveRouteResult 结果
     * @param code            结果码
     */
    @Override
    public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int code) {
        aMap.clear();// 清理地图上的所有覆盖物
        if (code == AMapException.CODE_AMAP_SUCCESS) {
            if (driveRouteResult != null && driveRouteResult.getPaths() != null) {
                if (driveRouteResult.getPaths().size() > 0) {
                    final DrivePath drivePath = driveRouteResult.getPaths()
                            .get(0);
                    if(drivePath == null) {
                        return;
                    }
                    DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(
                            this, aMap, drivePath,
                            driveRouteResult.getStartPos(),
                            driveRouteResult.getTargetPos(), null);
                    drivingRouteOverlay.removeFromMap();
                    drivingRouteOverlay.addToMap();
                    drivingRouteOverlay.zoomToSpan();

                    int dis = (int) drivePath.getDistance();
                    int dur = (int) drivePath.getDuration();
                    String des = MapUtil.getFriendlyTime(dur)+"("+MapUtil.getFriendlyLength(dis)+")";
                    Log.d(TAG, des);
                } else if (driveRouteResult.getPaths() == null) {
                    showMsg("对不起,没有搜索到相关数据!");
                }
            } else {
                showMsg("对不起,没有搜索到相关数据!");
            }
        } else {
            showMsg("错误码;" + code);
        }
    }

下面运行一下:

在这里插入图片描述

⑤ 公交路线规划

  还有一个公交路线规划,公交的规划其实还包括了步行,不过步行是一点点。下面首先是改变里面的值,增加一个出行方式。

在这里插入图片描述

然后找到startRouteSearch方法,增加如下方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
			case 3://公交
                //构建驾车路线搜索对象 第三个参数表示公交查询城市区号,第四个参数表示是否计算夜班车,0表示不计算,1表示计算
                RouteSearch.BusRouteQuery busQuery = new RouteSearch.BusRouteQuery(fromAndTo, RouteSearch.BusLeaseWalk, "0755",0);
                //公交规划路径计算
                routeSearch.calculateBusRouteAsyn(busQuery);
                break;

这里注意一点,那就是城市的区号,这里我填的是0755,表示深圳。你可以通过城市区号查询去查看你所在地的城市区号,当然如果你不想去查询也可以,你可以直接用中文来解决,比如把0755改成深圳,也是可以的。如果你觉得这样也比较麻烦的话,那么你可以定义一个成员变量。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	//城市
    private String city;

然后在onLocationChanged中赋值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	city = aMapLocation.getCity();

最后在替换,这样的话就会以你当前所在城市为准。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	RouteSearch.BusRouteQuery busQuery = new RouteSearch.BusRouteQuery(fromAndTo, RouteSearch.BusLeaseWalk, city, 0);

那么下面同样要绘制公交的图层,在overlay包下新建一个BusRouteOverlay类,代码如下:(来源于SDK)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.llw.mapdemo.overlay;

import android.content.Context;

import com.amap.api.maps.AMap;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.services.busline.BusStationItem;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.BusPath;
import com.amap.api.services.route.BusStep;
import com.amap.api.services.route.Doorway;
import com.amap.api.services.route.RailwayStationItem;
import com.amap.api.services.route.RouteBusLineItem;
import com.amap.api.services.route.RouteBusWalkItem;
import com.amap.api.services.route.RouteRailwayItem;
import com.amap.api.services.route.TaxiItem;
import com.amap.api.services.route.WalkStep;
import com.llw.mapdemo.util.MapUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * 公交路线图层类。在高德地图API里,如果需要显示公交路线,可以用此类来创建公交路线图层。如不满足需求,也可以自己创建自定义的公交路线图层。
 * @since V2.1.0
 */
public class BusRouteOverlay extends RouteOverlay {

	private BusPath busPath;
	private LatLng latLng;

	/**
	 * 通过此构造函数创建公交路线图层。
	 * @param context 当前activity。
	 * @param amap 地图对象。
	 * @param path 公交路径规划的一个路段。详见搜索服务模块的路径查询包(com.amap.api.services.route)中的类<strong> <a href="../../../../../../Search/com/amap/api/services/route/BusPath.html" title="com.amap.api.services.route中的类">BusPath</a></strong>。
	 * @param start 起点坐标。详见搜索服务模块的核心基础包(com.amap.api.services.core)中的类 <strong><a href="../../../../../../Search/com/amap/api/services/core/LatLonPoint.html" title="com.amap.api.services.core中的类">LatLonPoint</a></strong>。
	 * @param end 终点坐标。详见搜索服务模块的核心基础包(com.amap.api.services.core)中的类 <strong><a href="../../../../../../Search/com/amap/api/services/core/LatLonPoint.html" title="com.amap.api.services.core中的类">LatLonPoint</a></strong>。
	 * @since V2.1.0
	 */
	public BusRouteOverlay(Context context, AMap amap, BusPath path,
                           LatLonPoint start, LatLonPoint end) {
		super(context);
		this.busPath = path;
		startPoint = MapUtil.convertToLatLng(start);
		endPoint = MapUtil.convertToLatLng(end);
		mAMap = amap;
	}

	/**
	 * 添加公交路线到地图上。
	 * @since V2.1.0
	 */

	public void addToMap() {
		/**
		 * 绘制节点和线<br>
		 * 细节情况较多<br>
		 * 两个step之间,用step和step1区分<br>
		 * 1.一个step内可能有步行和公交,然后有可能他们之间连接有断开<br>
		 * 2.step的公交和step1的步行,有可能连接有断开<br>
		 * 3.step和step1之间是公交换乘,且没有步行,需要把step的终点和step1的起点连起来<br>
		 * 4.公交最后一站和终点间有步行,加入步行线路,还会有一些步行marker<br>
		 * 5.公交最后一站和终点间无步行,之间连起来<br>
		 */
		try {
			List<BusStep> busSteps = busPath.getSteps();
			for (int i = 0; i < busSteps.size(); i++) {
				BusStep busStep = busSteps.get(i);
				if (i < busSteps.size() - 1) {
					BusStep busStep1 = busSteps.get(i + 1);// 取得当前下一个BusStep对象
					// 假如步行和公交之间连接有断开,就把步行最后一个经纬度点和公交第一个经纬度点连接起来,避免断线问题
					if (busStep.getWalk() != null
							&& busStep.getBusLine() != null) {
						checkWalkToBusline(busStep);
					}

					// 假如公交和步行之间连接有断开,就把上一公交经纬度点和下一步行第一个经纬度点连接起来,避免断线问题
					if (busStep.getBusLine() != null
							&& busStep1.getWalk() != null 
							&& busStep1.getWalk().getSteps().size() > 0) {
						checkBusLineToNextWalk(busStep, busStep1);
					}
					// 假如两个公交换乘中间没有步行,就把上一公交经纬度点和下一步公交第一个经纬度点连接起来,避免断线问题
					if (busStep.getBusLine() != null
							&& busStep1.getWalk() == null
							&& busStep1.getBusLine() != null) {
						checkBusEndToNextBusStart(busStep, busStep1);
					}
					// 和上面的很类似
					if (busStep.getBusLine() != null
							&& busStep1.getWalk() == null
							&& busStep1.getBusLine() != null) {
						checkBusToNextBusNoWalk(busStep, busStep1);
					}
					if (busStep.getBusLine() != null
							&& busStep1.getRailway() != null ) {
						checkBusLineToNextRailway(busStep, busStep1);
					}
					if (busStep1.getWalk() != null &&
							busStep1.getWalk().getSteps().size() > 0 &&
							busStep.getRailway() != null) {
						checkRailwayToNextWalk(busStep, busStep1);
					}
					
					if ( busStep1.getRailway() != null &&
							busStep.getRailway() != null) {
						checkRailwayToNextRailway(busStep, busStep1);
					}
					
					if (busStep.getRailway() != null && 
						busStep1.getTaxi() != null ){
						checkRailwayToNextTaxi(busStep, busStep1);
					}
					

				}

				if (busStep.getWalk() != null
						&& busStep.getWalk().getSteps().size() > 0) {
					addWalkSteps(busStep);
				} else {
					if (busStep.getBusLine() == null && busStep.getRailway() == null && busStep.getTaxi() == null) {
						addWalkPolyline(latLng, endPoint);
					}
				}
				if (busStep.getBusLine() != null) {
					RouteBusLineItem routeBusLineItem = busStep.getBusLine();
					addBusLineSteps(routeBusLineItem);
					addBusStationMarkers(routeBusLineItem);
					if (i == busSteps.size() - 1) {
						addWalkPolyline(MapUtil.convertToLatLng(getLastBuslinePoint(busStep)), endPoint);
					}
				}
				if (busStep.getRailway() != null) {
					addRailwayStep(busStep.getRailway());
					addRailwayMarkers(busStep.getRailway());
					if (i == busSteps.size() - 1) {
						addWalkPolyline(MapUtil.convertToLatLng(busStep.getRailway().getArrivalstop().getLocation()), endPoint);
					}
				}
				if (busStep.getTaxi() != null) {
					addTaxiStep(busStep.getTaxi());
					addTaxiMarkers(busStep.getTaxi());
				}
			}
			addStartAndEndMarker();

		} catch (Throwable e) {
			e.printStackTrace();
		}
	}



	private void checkRailwayToNextTaxi(BusStep busStep, BusStep busStep1) {
		LatLonPoint railwayLastPoint = busStep.getRailway().getArrivalstop().getLocation();
		LatLonPoint taxiFirstPoint = busStep1.getTaxi().getOrigin();
		if (!railwayLastPoint.equals(taxiFirstPoint)) {
			addWalkPolyLineByLatLonPoints(railwayLastPoint, taxiFirstPoint);
		}
	}

	private void checkRailwayToNextRailway(BusStep busStep, BusStep busStep1) {
		LatLonPoint railwayLastPoint = busStep.getRailway().getArrivalstop().getLocation();
		LatLonPoint railwayFirstPoint = busStep1.getRailway().getDeparturestop().getLocation();
		if (!railwayLastPoint.equals(railwayFirstPoint)) {
			addWalkPolyLineByLatLonPoints(railwayLastPoint, railwayFirstPoint);
		}
		
	}

	private void checkBusLineToNextRailway(BusStep busStep, BusStep busStep1) {
		LatLonPoint busLastPoint = getLastBuslinePoint(busStep);
		LatLonPoint railwayFirstPoint = busStep1.getRailway().getDeparturestop().getLocation();
		if (!busLastPoint.equals(railwayFirstPoint)) {
			addWalkPolyLineByLatLonPoints(busLastPoint, railwayFirstPoint);
		}
		
	}

	private void checkRailwayToNextWalk(BusStep busStep, BusStep busStep1) {
		LatLonPoint railwayLastPoint = busStep.getRailway().getArrivalstop().getLocation();
		LatLonPoint walkFirstPoint = getFirstWalkPoint(busStep1);
		if (!railwayLastPoint.equals(walkFirstPoint)) {
			addWalkPolyLineByLatLonPoints(railwayLastPoint, walkFirstPoint);
		}
		
	}

	private void addRailwayStep(RouteRailwayItem railway) {
		List<LatLng> railwaylistpoint = new ArrayList<LatLng>();
		List<RailwayStationItem> railwayStationItems = new ArrayList<RailwayStationItem>();
		railwayStationItems.add(railway.getDeparturestop());
		railwayStationItems.addAll(railway.getViastops());
		railwayStationItems.add(railway.getArrivalstop());
		for (int i = 0; i < railwayStationItems.size(); i++) {
			railwaylistpoint.add(MapUtil.convertToLatLng(railwayStationItems.get(i).getLocation()));
		}
		addRailwayPolyline(railwaylistpoint);
	}
	
	private void addTaxiStep(TaxiItem taxi){
		addPolyLine(new PolylineOptions().width(getRouteWidth())
				.color(getBusColor())
				.add(MapUtil.convertToLatLng(taxi.getOrigin()))
				.add(MapUtil.convertToLatLng(taxi.getDestination())));
	}

	/**
	 * @param busStep
	 */
	private void addWalkSteps(BusStep busStep) {
		RouteBusWalkItem routeBusWalkItem = busStep.getWalk();
		List<WalkStep> walkSteps = routeBusWalkItem.getSteps();
		for (int j = 0; j < walkSteps.size(); j++) {
			WalkStep walkStep = walkSteps.get(j);
			if (j == 0) {
				LatLng latLng = MapUtil.convertToLatLng(walkStep
						.getPolyline().get(0));
				String road = walkStep.getRoad();// 道路名字
				String instruction = getWalkSnippet(walkSteps);// 步行导航信息
				addWalkStationMarkers(latLng, road, instruction);
			}

			List<LatLng> listWalkPolyline = MapUtil
					.convertArrList(walkStep.getPolyline());
			this.latLng = listWalkPolyline.get(listWalkPolyline.size() - 1);

			addWalkPolyline(listWalkPolyline);

			// 假如步行前一段的终点和下的起点有断开,断画直线连接起来,避免断线问题
			if (j < walkSteps.size() - 1) {
				LatLng lastLatLng = listWalkPolyline.get(listWalkPolyline
						.size() - 1);
				LatLng firstlatLatLng = MapUtil
						.convertToLatLng(walkSteps.get(j + 1).getPolyline()
								.get(0));
				if (!(lastLatLng.equals(firstlatLatLng))) {
					addWalkPolyline(lastLatLng, firstlatLatLng);
				}
			}

		}
	}

	/**
	 * 添加一系列的bus PolyLine
	 *
	 * @param routeBusLineItem
	 */
	private void addBusLineSteps(RouteBusLineItem routeBusLineItem) {
		addBusLineSteps(routeBusLineItem.getPolyline());
	}

	private void addBusLineSteps(List<LatLonPoint> listPoints) {
		if (listPoints.size() < 1) {
			return;
		}
		addPolyLine(new PolylineOptions().width(getRouteWidth())
				.color(getBusColor())
				.addAll(MapUtil.convertArrList(listPoints)));
	}

	/**
	 * @param latLng
	 *            marker
	 * @param title
	 * @param snippet
	 */
	private void addWalkStationMarkers(LatLng latLng, String title,
                                       String snippet) {
		addStationMarker(new MarkerOptions().position(latLng).title(title)
				.snippet(snippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
				.icon(getWalkBitmapDescriptor()));
	}

	/**
	 * @param routeBusLineItem
	 */
	private void addBusStationMarkers(RouteBusLineItem routeBusLineItem) {
		BusStationItem startBusStation = routeBusLineItem
				.getDepartureBusStation();
		LatLng position = MapUtil.convertToLatLng(startBusStation
				.getLatLonPoint());
		String title = routeBusLineItem.getBusLineName();
		String snippet = getBusSnippet(routeBusLineItem);

		addStationMarker(new MarkerOptions().position(position).title(title)
				.snippet(snippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
				.icon(getBusBitmapDescriptor()));
	}
	
	private void addTaxiMarkers(TaxiItem taxiItem) {
		
		LatLng position = MapUtil.convertToLatLng(taxiItem
				.getOrigin());
		String title = taxiItem.getmSname()+"打车";
		String snippet = "到终点";

		addStationMarker(new MarkerOptions().position(position).title(title)
				.snippet(snippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
				.icon(getDriveBitmapDescriptor()));
	}

	private void addRailwayMarkers(RouteRailwayItem railway) {
		LatLng Departureposition = MapUtil.convertToLatLng(railway
				.getDeparturestop().getLocation());
		String Departuretitle = railway.getDeparturestop().getName()+"上车";
		String Departuresnippet = railway.getName();

		addStationMarker(new MarkerOptions().position(Departureposition).title(Departuretitle)
				.snippet(Departuresnippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
				.icon(getBusBitmapDescriptor()));
		
		
		LatLng Arrivalposition = MapUtil.convertToLatLng(railway
				.getArrivalstop().getLocation());
		String Arrivaltitle = railway.getArrivalstop().getName()+"下车";
		String Arrivalsnippet = railway.getName();

		addStationMarker(new MarkerOptions().position(Arrivalposition).title(Arrivaltitle)
				.snippet(Arrivalsnippet).anchor(0.5f, 0.5f).visible(nodeIconVisible)
				.icon(getBusBitmapDescriptor()));
	}
	/**
	 * 如果换乘没有步行 检查bus最后一点和下一个step的bus起点是否一致
	 *
	 * @param busStep
	 * @param busStep1
	 */
	private void checkBusToNextBusNoWalk(BusStep busStep, BusStep busStep1) {
		LatLng endbusLatLng = MapUtil
				.convertToLatLng(getLastBuslinePoint(busStep));
		LatLng startbusLatLng = MapUtil
				.convertToLatLng(getFirstBuslinePoint(busStep1));
		if (startbusLatLng.latitude - endbusLatLng.latitude > 0.0001
				|| startbusLatLng.longitude - endbusLatLng.longitude > 0.0001) {
			drawLineArrow(endbusLatLng, startbusLatLng);// 断线用带箭头的直线连?
		}
	}

	/**
	 *
	 * checkBusToNextBusNoWalk 和这个类似
	 *
	 * @param busStep
	 * @param busStep1
	 */
	private void checkBusEndToNextBusStart(BusStep busStep, BusStep busStep1) {
		LatLonPoint busLastPoint = getLastBuslinePoint(busStep);
		LatLng endbusLatLng = MapUtil.convertToLatLng(busLastPoint);
		LatLonPoint busFirstPoint = getFirstBuslinePoint(busStep1);
		LatLng startbusLatLng = MapUtil.convertToLatLng(busFirstPoint);
		if (!endbusLatLng.equals(startbusLatLng)) {
			drawLineArrow(endbusLatLng, startbusLatLng);//
		}
	}

	/**
	 * 检查bus最后一步和下一各step的步行起点是否一致
	 *
	 * @param busStep
	 * @param busStep1
	 */
	private void checkBusLineToNextWalk(BusStep busStep, BusStep busStep1) {
		LatLonPoint busLastPoint = getLastBuslinePoint(busStep);
		LatLonPoint walkFirstPoint = getFirstWalkPoint(busStep1);
		if (!busLastPoint.equals(walkFirstPoint)) {
			addWalkPolyLineByLatLonPoints(busLastPoint, walkFirstPoint);
		}
	}

	/**
	 * 检查 步行最后一点 和 bus的起点 是否一致
	 *
	 * @param busStep
	 */
	private void checkWalkToBusline(BusStep busStep) {
		LatLonPoint walkLastPoint = getLastWalkPoint(busStep);
		LatLonPoint buslineFirstPoint = getFirstBuslinePoint(busStep);

		if (!walkLastPoint.equals(buslineFirstPoint)) {
			addWalkPolyLineByLatLonPoints(walkLastPoint, buslineFirstPoint);
		}
	}

	/**
	 * @param busStep1
	 * @return
	 */
	private LatLonPoint getFirstWalkPoint(BusStep busStep1) {
		return busStep1.getWalk().getSteps().get(0).getPolyline().get(0);
	}

	/**
	 *
	 */
	private void addWalkPolyLineByLatLonPoints(LatLonPoint pointFrom,
                                               LatLonPoint pointTo) {
		LatLng latLngFrom = MapUtil.convertToLatLng(pointFrom);
		LatLng latLngTo = MapUtil.convertToLatLng(pointTo);

		addWalkPolyline(latLngFrom, latLngTo);
	}

	/**
	 * @param latLngFrom
	 * @param latLngTo
	 * @return
	 */
	private void addWalkPolyline(LatLng latLngFrom, LatLng latLngTo) {
		addPolyLine(new PolylineOptions().add(latLngFrom, latLngTo)
				.width(getRouteWidth()).color(getWalkColor()).setDottedLine(true));
	}

	/**
	 * @param listWalkPolyline
	 */
	private void addWalkPolyline(List<LatLng> listWalkPolyline) {

		addPolyLine(new PolylineOptions().addAll(listWalkPolyline)
				.color(getWalkColor()).width(getRouteWidth()).setDottedLine(true));
	}

	private void addRailwayPolyline(List<LatLng> listPolyline) {

		addPolyLine(new PolylineOptions().addAll(listPolyline)
				.color(getDriveColor()).width(getRouteWidth()));
	}
	
	
	private String getWalkSnippet(List<WalkStep> walkSteps) {
		float disNum = 0;
		for (WalkStep step : walkSteps) {
			disNum += step.getDistance();
		}
		return "\u6B65\u884C" + disNum + "\u7C73";
	}

	public void drawLineArrow(LatLng latLngFrom, LatLng latLngTo) {

		addPolyLine(new PolylineOptions().add(latLngFrom, latLngTo).width(3)
				.color(getBusColor()).width(getRouteWidth()));// 绘制直线
	}

	private String getBusSnippet(RouteBusLineItem routeBusLineItem) {
		return "("
				+ routeBusLineItem.getDepartureBusStation().getBusStationName()
				+ "-->"
				+ routeBusLineItem.getArrivalBusStation().getBusStationName()
				+ ") \u7ECF\u8FC7" + (routeBusLineItem.getPassStationNum() + 1)
				+ "\u7AD9";
	}

	/**
	 * @param busStep
	 * @return
	 */
	private LatLonPoint getLastWalkPoint(BusStep busStep) {

		List<WalkStep> walkSteps = busStep.getWalk().getSteps();
		WalkStep walkStep = walkSteps.get(walkSteps.size() - 1);
		List<LatLonPoint> lonPoints = walkStep.getPolyline();
		return lonPoints.get(lonPoints.size() - 1);
	}

	private LatLonPoint getExitPoint(BusStep busStep) {
		Doorway doorway = busStep.getExit();
		if (doorway == null) {
			return null;
		}
		return doorway.getLatLonPoint();
	}

	private LatLonPoint getLastBuslinePoint(BusStep busStep) {
		List<LatLonPoint> lonPoints = busStep.getBusLine().getPolyline();

		return lonPoints.get(lonPoints.size() - 1);
	}

	private LatLonPoint getEntrancePoint(BusStep busStep) {
		Doorway doorway = busStep.getEntrance();
		if (doorway == null) {
			return null;
		}
		return doorway.getLatLonPoint();
	}

	private LatLonPoint getFirstBuslinePoint(BusStep busStep) {
		return busStep.getBusLine().getPolyline().get(0);
	}
}

最后回到RouteActivity,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	 /**
     * 公交规划路径结果
     *
     * @param busRouteResult 结果
     * @param code           结果码
     */
    @Override
    public void onBusRouteSearched(BusRouteResult busRouteResult, int code) {
        aMap.clear();// 清理地图上的所有覆盖物
        if (code == AMapException.CODE_AMAP_SUCCESS) {
            if (busRouteResult != null && busRouteResult.getPaths() != null) {
                if (busRouteResult.getPaths().size() > 0) {
                    final BusPath busPath = busRouteResult.getPaths().get(0);
                    if (busPath == null) {
                        return;
                    }
                    BusRouteOverlay busRouteOverlay = new BusRouteOverlay(
                            this, aMap, busPath,
                            busRouteResult.getStartPos(),
                            busRouteResult.getTargetPos());
                    busRouteOverlay.removeFromMap();
                    busRouteOverlay.addToMap();
                    busRouteOverlay.zoomToSpan();

                    int dis = (int) busPath.getDistance();
                    int dur = (int) busPath.getDuration();
                    String des = MapUtil.getFriendlyTime(dur) + "(" + MapUtil.getFriendlyLength(dis) + ")";
                    Log.d(TAG, des);
                } else if (busRouteResult.getPaths() == null) {
                    showMsg("对不起,没有搜索到相关数据!");
                }
            } else {
                showMsg("对不起,没有搜索到相关数据!");
            }
        } else {
            showMsg("错误码;" + code);
        }
    }

然后来看看运行的效果。

公交路线规划就写完了。

下一篇

Android 高德地图API(详细步骤+源码)六

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
设计模式 ☞ 概述
  设计模式是软件设计中常见问题的典型解决方案。 它们就像能根据需求进行调整的预制蓝图, 可用于解决代码中反复出现的设计问题。设计模式与方法或库的使用方式不同, 很难直接在自己的程序中套用某个设计模式。 模式并不是一段特定的代码, 而是解决特定问题的一般性概念。 可以根据模式来实现符合自己程序实际所需的解决方案。   人们常常会混淆模式和算法, 因为两者在概念上都是已知特定问题的典型解决方案。 但算法总是明确定义达成特定目标所需的一系列步骤, 而模式则是对解决方案的更高层次描述。 同一模式在两个不同程序中的实现代码可能会不一样。算法更像是菜谱: 提供达成目标的明确步骤。 而模式更像是蓝图: 可以看到最终的结果和模式的功能, 但需要自己确定实现步骤。
Demo_Null
2020/12/16
3850
设计模式 ☞ 概述
Java二十三种设计模式-中介者模式(22/23)
本文深入探讨了中介者模式,这是一种行为型设计模式,通过定义一个中介者对象来简化对象间的通信,降低耦合度,并提高系统的模块化,同时提供了实现示例、使用场景、优缺点分析、与其他设计模式的比较,以及最佳实践和替代方案。
正在走向自律
2024/12/18
1740
Java二十三种设计模式-中介者模式(22/23)
武林秘籍之设计模式迷你手册
编程是一个江湖,江湖之大,鱼龙混杂,一部分江湖人士乃虾兵蟹将,一不小心就被一箭射死,我们称之为“码农”,这些人事江湖的重要组成部分,他们承担着堆砌代码,实现功能设计的使命,他们在江湖中虽为龙套,但不可或缺。另一部分人,华山论剑,刀光剑影,矗立江湖之巅,他们是系统分析师、架构师等,他们内功深厚,视野开阔,一招一式,举手投足间蕴藏着对可维护性、可扩展性等的深思熟虑。当然,更多的一部分人,他们不甘于现状,天资聪慧,正由“码农”向高手的身份努力中。
陈宇明
2020/12/15
4390
武林秘籍之设计模式迷你手册
一起学习设计模式--设计模式
武侠小说中武术分招式和内功,比如独孤九剑就是招式,九阳神功就是内功。招式可能照猫画虎很快就能学会,但是内功心法则需要日积月累,一点一点的修炼。
独立观察员
2022/12/06
1960
一起学习设计模式--设计模式
业余草谈设计模式
设计模式之间并不是完全独立的,而是互相之间,会有一些相同的影子,下面我们来一起总结下这24种设计模式。
业余草
2019/01/21
4110
Java二十三种设计模式-策略模式(13/23)
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
正在走向自律
2024/12/18
2710
Java二十三种设计模式-策略模式(13/23)
C#设计模式开启闯关之路
  这是一条望不到尽头的编程之路,自踏入编程之路开始。就面临着各式各样的挑战,而我们也需要不断的挑战自己、不断学习充实自己、打好坚实的基础。以使我们可以走的更远。刚踏入编程的时候。根据需求编程,需求改代码改。需求加代码加。重复来重复去。一切都觉得还不错。功能实现了,项目跑起来了。但是真的就不错了吗?当然不是,也许过了几年你再回头看这些代码或许你也不知道写的啥了。这样写出来的代码你自己都可能看不到,更何况其他人呢?对吧。偶尔一次闯入一处秘境。发现了一本名叫”设计模式”的”武功”秘籍。也是编程之路之上不可获取的能力之一。它解决了代码重复使用,代码冗余的问题。使代码结构简洁易懂。使代码的思路清晰明了。代码优美,结构完善合理。我们一起看看这个至高的秘籍。
小世界的野孩子
2019/09/11
5780
【JAVA今法修真】 第九章 兼容并包 适配模式
万维仙网正如它的名字一样,方法在一个空间内叠加了无数维度,利用超链接技术,可以自由的在各个维度内穿梭。
南橘
2022/03/07
2370
【JAVA今法修真】 第九章  兼容并包 适配模式
设计模式专题(二十四) ——访问者模式
设计模式专题(二十四)——访问者模式 (原创内容,转载请注明来源,谢谢) 一、概述 访问者模式(visitor)表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下,定义作用于这些元素的新操作。 访问者模式适用于数据结构相对稳定的系统,并把数据结构和作用于结构上的操作之间的耦合解开,使操作可以自由地演化。 访问者模式的目的是为了把处理从数据结构分离出来,如果有比较稳定的数据结构,易于变化的算法,则访问者模式比较合适。 访问者模式的优点在于增加新的操作很容易,意味着增加一个新
用户1327360
2018/03/07
8300
设计模式专题(二十四) ——访问者模式
设计模式专题(二十三) ——解释器模式
设计模式专题(二十三)——解释器模式 (原创内容,转载请注明来源,谢谢) 一、概述 解释器模式(interpreter)是给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 如果某一特定类型发生的频率足够高,那么就可以将问题的各个实例表述为一个简单语言中的句子,并构建解释器,通过解释句子,解释器来解决问题。 例如字符串匹配,大多数语言用到的正则表达式,就可以理解成一种解释器模式,字符串是待匹配字符的集合,而表达式是一种匹配模式。 当有一个语言需要解释器执
用户1327360
2018/03/07
7060
设计模式专题(二十三) ——解释器模式
十五.各设计模式总结与对比
3、 不要为了用设计模式去生搬硬套,而是在业务上到遇到问题时,很自然地想到设计模式作为一种解 决方案。
编程之心
2020/08/12
9030
十五.各设计模式总结与对比
设计模式(十四)中介者模式
前言 写了很多篇设计模式的文章,才发现没有讲关于设计模式的分类,那么这一篇就补上这一内容,顺便带来中介者模式的讲解,并与此前讲过的代理模式和外观模式做对比。 1.设计模式的分类 GoF提出的设计模式总共有23种,根据目的准则分类分为三大类: 创建型模式,共五种:单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备
用户1269200
2018/02/01
6300
设计模式(十四)中介者模式
Java二十三种设计模式-代理模式(8/23)
代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一个代替或占位符,以控制对它的访问。
正在走向自律
2024/12/18
2050
Java二十三种设计模式-代理模式(8/23)
再谈23种设计模式(3):行为型模式(学习笔记)
无论造型如何变化,不变的有两种东西:“奶油”和“面包”。其余的材料随意搭配,就凑成了各式各样的蛋糕。
周陆军博客
2024/06/06
3420
Java二十三种设计模式-装饰器模式(7/23)
装饰器模式(Decorator Pattern)是一种结构型设计模式,用于在不修改对象自身的基础上,通过添加额外的职责来扩展对象的功能。
正在走向自律
2024/12/18
1720
Java二十三种设计模式-装饰器模式(7/23)
Java二十三种设计模式-备忘录模式(19/23)
本文深入探讨了备忘录模式,从定义、组成、实现到使用场景、优缺点、与其他模式的比较,以及最佳实践和替代方案,全面解析了如何在软件开发中有效地保存和恢复对象状态,以支持复杂的撤销操作和历史状态管理。
正在走向自律
2024/12/18
1360
Java二十三种设计模式-备忘录模式(19/23)
设计模式专题(二十一) ——中介者模式
设计模式专题(二十一)——中介者模式 (原创内容,转载请注明来源,谢谢) 一、概述 中介者模式(Mediator)是用一个中介对象,来封装一系列对象的交互。中介者使各对象不需要显式地相互引用,从而松耦合,可以独立改变它们之间的交互。 中介者模式使得多个类之间互相通信,可以通过中介者快速实现。但是,也需要注意的是,如果系统频繁出现多对多通信的情况,首先需要排查类的设计,有可能是设计问题导致的。 1、优点 中介者模式减少各个类之间的耦合,使得可以读了改变和复用各个类。另外,由于把对象之间的协作进行抽象,将
用户1327360
2018/03/07
6330
设计模式专题(二十一) ——中介者模式
设计模式概念总结
   定义一个用于创建对象的接口,让子类决定实例化哪个类,工厂方法使一个类的实例化延迟其子类
莫问今朝
2019/02/25
5570
Java二十三种设计模式-访问者模式(21/23)
本文深入探讨了访问者模式,一种允许向对象结构添加新操作而不修改其本身的设计模式,涵盖了其定义、组成部分、实现方式、使用场景、优缺点、与其他模式的比较,以及最佳实践和替代方案。
正在走向自律
2024/12/18
7690
Java二十三种设计模式-访问者模式(21/23)
Java二十三种设计模式-迭代子模式(16/23)
迭代器模式(Iterator Pattern)是一种行为型设计模式,它允许顺序访问一个集合对象中的各个元素,而不需要暴露集合的底层表示。
正在走向自律
2024/12/18
1510
Java二十三种设计模式-迭代子模式(16/23)
相关推荐
设计模式 ☞ 概述
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档