这是效果的视频
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.
这里先说一下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();
}
}