安卓模仿膜拜单车地图显示的功能

这是效果的视频

https://pan.baidu.com/s/1c2IVmRA

百度地图版本4.0.0

首先是定位,定位成功后再添加一个这样的点


添加方式

val shopList = arrayListOf(LatlngBean(经度, 经度), LatlngBean(纬度, 经度), LatlngBean(纬度, 经度), LatlngBean(纬度,经度))
val home = BitmapDescriptorFactory.fromResource(R.mipmap.home2)//加载一张图片
shopList.map {
	val latlng = LatLng(it.lat, it.lng)
	val ood = MarkerOptions().position(latlng).icon(home)
	ood.animateType(MarkerOptions.MarkerAnimateType.grow)//设置动画,可以不用
	val marker = baiduMap.addOverlay(ood) as Marker//将这个点添加到百度地图
	val bundle = Bundle()
	bundle.putSerializable(TAG, it)//存储这个点经纬度
	marker.extraInfo = bundle
}
LatlngBean

data class LatlngBean(val lat: Double, val lng: Double) : Serializable

接下来是设置点的点击事件和规划路线

规划路线钱的准备

先初始化一个RoutePlanSearch并设置它的什么什么事件

 val search = RoutePlanSearch.newInstance()
 search.setOnGetRoutePlanResultListener(this)

设置之后要实现 OnGetRoutePlanResultListener 并实现这4个方法

//公交
override fun onGetTransitRouteResult(result: TransitRouteResult?) {
       
}

//驾车
override fun onGetDrivingRouteResult(result: DrivingRouteResult?) {
       
}

//步行
override fun onGetWalkingRouteResult(result: WalkingRouteResult?) {
       
}

//自行车
override fun onGetBikingRouteResult(result: BikingRouteResult?) {

}

然后通过mapView拿到BaiduMap,再设置点的点击事件,这个也可以在activity初始化的时候就设置

//这是开始的坐标
val startNode = PlanNode.withLocation(point)
baiduMap.setOnMarkerClickListener {
	val bean = it.extraInfo.get(TAG) as LatlngBean
	//这是设置步行的路线,也就是调用上面的onGetWalkingRouteResult方法.from是开始的坐标,to是结束的坐标
	//其他方式直接调用一下就知道对应哪个方法了
	search.walkingSearch(WalkingRoutePlanOption().from(startNode).to(PlanNode.withLocation(LatLng(bean.lat, bean.lng))))
	true
}


接下来就是在百度地图上添加路线.这里需要用到百度地图的WalkingRouteOverlay类,具体去地图的demo找.注:在自定义下载里面是找不到的,必须demo.

也可以到这里下载 http://download.csdn.net/download/android_upl/9979616

这里先说一下WalkingRouteOverlay这个类

//这个方法就是来设置线的数据
    @Override
    public final List<OverlayOptions> getOverlayOptions() {
        if (mRouteLine == null) {
            return null;
        }

        List<OverlayOptions> overlayList = new ArrayList<OverlayOptions>();
        if (mRouteLine.getAllStep() != null
                && mRouteLine.getAllStep().size() > 0) {
            for (WalkingRouteLine.WalkingStep step : mRouteLine.getAllStep()) {
                Bundle b = new Bundle();
                b.putInt("index", mRouteLine.getAllStep().indexOf(step));
				//如果不把下面这段代码去掉,就会在每条线上面添加方向坐标,我认为不好看,就去掉了,具体看需求
                /*if (step.getEntrance() != null) {
                    overlayList.add((new MarkerOptions())
                            .position(step.getEntrance().getLocation())
                                    .rotate((360 - step.getDirection()))
                                            .zIndex(10)
                                                    .anchor(0.5f, 0.5f)
                                                            .extraInfo(b)
                                                                    .icon(BitmapDescriptorFactory
                                                                            .fromAssetWithDpi("Icon_line_node.png")));
                }*///TODO 这段是去掉方向点
				
                //如果不把下面这段代码去掉,就会在每条线上面添加方向坐标,我认为不好看,就去掉了,具体看需求
                /*if (mRouteLine.getAllStep().indexOf(step) == (mRouteLine
                        .getAllStep().size() - 1) && step.getExit() != null) {
                    overlayList.add((new MarkerOptions())
                            .position(step.getExit().getLocation())
                                    .anchor(0.5f, 0.5f)
                                            .zIndex(10)
                                                    .icon(BitmapDescriptorFactory
                                                            .fromAssetWithDpi("Icon_line_node.png")));

                }*/
            }
        }
        //这里是设置起始坐标的点,还是看需求
        /*if (mRouteLine.getStarting() != null) {
            overlayList.add((new MarkerOptions())
                    .position(mRouteLine.getStarting().getLocation())
                            .icon(getStartMarker() != null ? getStartMarker() :
                                    BitmapDescriptorFactory
                                            .fromAssetWithDpi("Icon_start.png")).zIndex(10));
        }
        //这里是设置结束坐标的点,继续看需求
        if (mRouteLine.getTerminal() != null) {
            overlayList
                    .add((new MarkerOptions())
                            .position(mRouteLine.getTerminal().getLocation())
                                    .icon(getTerminalMarker() != null ? getTerminalMarker() :
                                            BitmapDescriptorFactory
                                                    .fromAssetWithDpi("Icon_end.png"))
                                                            .zIndex(10));
        }*/

        //这里就是划线的方法,怎么设置线的宽度不清楚
        if (mRouteLine.getAllStep() != null
                && mRouteLine.getAllStep().size() > 0) {
            LatLng lastStepLastPoint = null;
            for (WalkingRouteLine.WalkingStep step : mRouteLine.getAllStep()) {
                List<LatLng> watPoints = step.getWayPoints();
                if (watPoints != null) {
                    List<LatLng> points = new ArrayList<LatLng>();
                    if (lastStepLastPoint != null) {
                        points.add(lastStepLastPoint);
                    }
                    points.addAll(watPoints);
                    overlayList.add(new PolylineOptions().points(points).width(10)//#5E8CF1
							//这里是设置线的颜色
                            .color(getLineColor() != 0 ? getLineColor() : Color.argb(255, 94, 140, 241)).zIndex(0));
//                            .color(getLineColor() != 0 ? getLineColor() : Color.argb(178, 0, 78, 255)).zIndex(0));
                    lastStepLastPoint = watPoints.get(watPoints.size() - 1);
                }
            }
            
        }
	//执行到了这里,就代表已经规划完成,可以在这里设置回调
        return overlayList;
    }

然后是关于怎么在地图上画步行的线

//记录上一个WalkingRouteOverlay,用于清除之前的路线
private var option: WalkingRouteOverlay? = null
//记录上一个目的地的经纬度,如果一样就别重新规划路线
private var mLastLocation : LatLng? = null
//步行
override fun onGetWalkingRouteResult(result: WalkingRouteResult?) {
	//没有找到路线
	if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
		toast("未找到路线")
		return
	}
	if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
		//起终点或途经点地址有岐义,通过以下接口获取建议查询信息
		//result.getSuggestAddrInfo()
		return;
	}
	//规划路线成功
	if (result.error == SearchResult.ERRORNO.NO_ERROR) {
		//获取目的地的经纬度
		val lastLatlng = result.routeLines[0].terminal.location
		//一样的时候,返回
		if (mLastLocation?.latitude == lastLatlng.latitude && mLastLocation?.longitude == lastLatlng.longitude) {
			return
		}
		mLastLocation = lastLatlng
		toast("有路线")
		//如果有画过路线就清除
		option?.removeFromMap()
		//初始化
		option = WalkingRouteOverlay(baiduMap);
		//设置路线的点击事件,具体看需求
		//baiduMap.setOnMarkerClickListener(option);

		val line = result.routeLines[0]
		//设置路线数据
		option?.setData(line)
		//将路线添加到百度地图
		option?.addToMap()
//            option?.zoomToSpan() //会缩放地图
	}
}
接下来是

实现中间定位的功能

布局文件


然后监听百度地图的滑动状态事件

private var mTargetLatlng: LatLng? = null
baiduMap.setOnMapStatusChangeListener(object : BaiduMap.OnMapStatusChangeListener {
	override fun onMapStatusChangeStart(status: MapStatus?) {

	}

	//拖拽完成后的回调
	override fun onMapStatusChangeFinish(status: MapStatus) {
		//从百度的api看到,监听这个事件可以获取到MapStatus,而MapStatus里面有getTarget这个方法
		//这个可以获取到中间点的经纬度
		mTargetLatlng = status.target
	}

	override fun onMapStatusChange(status: MapStatus?) {

	}
})
然后点击go通过接口获取到中间点附近的网点,获取到再和上面一样设置目的地坐标

val latlng = LatLng(bean.FLatitude.toDouble(), bean.FLongitude.toDouble())
val ood = MarkerOptions().position(latlng).icon(home)
ood.animateType(MarkerOptions.MarkerAnimateType.grow)
val marker = baiduMap.addOverlay(ood) as Marker
val bundle = Bundle()
val bean2 = LatlngBean(bean.FLatitude.toDouble(),bean.FLongitude.toDouble())
bundle.putSerializable(TAG, bean2)
marker.extraInfo = bundle

下面是自驾的规划路线的方法,其实都差不多

//驾车
override fun onGetDrivingRouteResult(result: DrivingRouteResult?) {
	if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
		toast("未找到路线")
		return
	}
	if (result.error == SearchResult.ERRORNO.NO_ERROR) {
		//注:或许有多条路线,我这里只是取第一条路线
		val route = result.getRouteLines().get(0);
		val overlay = DrivingRouteOverlay(baiduMap);

		baiduMap.setOnMarkerClickListener(overlay);
		overlay.setData(route);
		overlay.addToMap();
		overlay.zoomToSpan();
	}
}


猜你喜欢

转载自blog.csdn.net/android_upl/article/details/77986579