【Android】3.13 路径规划功能
分类:C#、Android、VS2015、百度地图应用; 创建日期:2016-02-04
一、简介
线路规划支持以下功能:
- 公交信息查询:可对公交详细信息进行查询;
- 公交换乘查询:根据起、终点,查询策略,进行线路规划方案;
- 驾车线路规划:提供不同策略,规划驾车路线;(支持设置途经点)
- 步行路径检索:支持步行路径的规划。
其中驾车线路规划自v3.4.0版本起支持多线路检索结果的能力。
二、运行截图
简介:介绍公交、驾车和步行三种线路规划方法和自设路线方法。
详述:
(1)驾车查询新增路径点查询功能,具体使用方法详见开发者指南路径规划部分,只需重载接口;
(2)自设路线功能演示开发者如何自己设定一条路线,包括如何设定起点、终点、途径站点和路段;
(3)自设路线功能同时也介绍如何在两个Activity之间切换的时候管理Mapview的生命周期;
(4)可自定义路线的起终点图标;
本示例运行截图如下:
三、设计步骤
1、添加自定义类【代码太多,就不再粘贴在这里了】
本示例用到的文件很多,主要涉及的是自定义覆盖物的相关类,这些文件都在SrcOverlayUtil文件夹下,除了上一节列出的OverlayManager.cs文件和PoiOverlay.cs外,还包括下面的文件。
(1)BikingRouteOverlay.cs文件
用于显示骑行路线的Overlay,自3.4.0版本起可实例化多个添加在地图中显示。
(2)BusLineOverlay.cs文件
用于显示一条公交详情结果的Overlay。
(3)DrivingRouteOverlay.cs文件
用于显示一条驾车路线的overlay,自3.4.0版本起可实例化多个添加在地图中显示,当数据中包含路况数据时,则默认使用路况纹理分段绘制。
(4)TransitRouteOverlay.cs文件
用于显示换乘路线的Overlay,自3.4.0版本起可实例化多个添加在地图中显示。
(5)WalkingRouteOverlay.cs文件
用于显示步行路线的overlay,自3.4.0版本起可实例化多个添加在地图中显示。
2、添加demo13_routeplan.xml文件
在layout文件夹下添加该文件,然后将代码改为下面的内容:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="起点:" /> <EditText android:id="@+id/start" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ems="10" android:text="龙泽" > <requestFocus /> </EditText> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="终点:" /> <EditText android:id="@+id/end" android:layout_width="fill_parent" android:layout_height="wrap_content" android:ems="10" android:text="西单" > <requestFocus /> </EditText> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dip" android:layout_marginTop="5dip" android:orientation="horizontal" > <Button android:id="@+id/drive" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="2dip" android:layout_marginRight="2dip" android:layout_weight="1.0" android:background="@drawable/button_style" android:text="驾车搜索" /> <Button android:id="@+id/transit" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="2dip" android:layout_marginRight="2dip" android:layout_weight="1.0" android:background="@drawable/button_style" android:text="公交搜索" /> <Button android:id="@+id/walk" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="2dip" android:layout_marginRight="2dip" android:layout_weight="1.0" android:background="@drawable/button_style" android:text="步行搜索" /> <Button android:id="@+id/bike" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="2dip" android:layout_marginRight="2dip" android:layout_weight="1.0" android:background="@drawable/button_style" android:text="骑行搜索" /> </LinearLayout> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.baidu.mapapi.map.TextureMapView android:id="@+id/map" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_alignWithParentIfMissing="false" android:layout_marginRight="10dp" android:layout_marginTop="10dip" android:orientation="vertical" > <Button android:id="@+id/customicon" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="10dip" android:layout_weight="1.0" android:background="@drawable/button_style" android:text="自定义起终点图标" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignWithParentIfMissing="false" android:layout_centerHorizontal="true" android:layout_centerVertical="false" android:layout_marginBottom="10dip" > <Button android:id="@+id/pre" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="2dip" android:layout_marginRight="2dip" android:layout_weight="1.0" android:background="@drawable/pre_" /> <Button android:id="@+id/next" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="2dip" android:layout_marginRight="2dip" android:layout_weight="1.0" android:background="@drawable/next_" /> </LinearLayout> </RelativeLayout> </LinearLayout>
3、添加Demo13RoutePlan.cs文件
在SrcSdkDemos文件夹下添加该文件,然后将代码改为下面的内容:
using Android.App; using Android.Content.PM; using Android.OS; using Android.Views; using Android.Widget; using Com.Baidu.Mapapi.Map; using Com.Baidu.Mapapi.Model; using Com.Baidu.Mapapi.Search.Core; using Com.Baidu.Mapapi.Search.Route; using BdMapV371Demos.SrcOverlayUtil; namespace BdMapV371Demos.SrcSdkDemos { /// <summary> ///此demo用来展示如何进行驾车、步行、公交路线搜索并在地图使用RouteOverlay、TransitOverlay绘制, ///同时展示如何进行节点浏览并弹出泡泡。 /// </summary> [Activity(Label = "@string/demo_name_route", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, ScreenOrientation = ScreenOrientation.Sensor)] public class Demo13RoutePlan : Activity { //浏览路线节点相关 Button btnPre = null;//上一个节点 Button btnNext = null;//下一个节点 int nodeIndex = -2;//节点索引,供浏览节点时使用 RouteLine route = null; OverlayManager routeOverlay = null; bool useDefaultIcon = false; private TextView popupText = null;//泡泡view //地图相关,使用MyRouteMapView目的是重写touch事件实现泡泡处理。 //如果不处理touch事件,则无需继承,直接使用TextureMapView即可。 TextureMapView mMapView = null; // 地图View BaiduMap mBaidumap = null; //搜索相关 RoutePlanSearch mSearch = null; // 搜索模块,也可去掉地图模块独立使用 protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.demo13_routeplan); //初始化地图 mMapView = FindViewById<TextureMapView>(Resource.Id.map); mBaidumap = mMapView.Map; btnPre = FindViewById<Button>(Resource.Id.pre); btnNext = FindViewById<Button>(Resource.Id.next); btnPre.Visibility = ViewStates.Invisible; btnNext.Visibility = ViewStates.Invisible; //处理地图点击事件 mBaidumap.MapClick += (s, e) => { //LatLng point = e.P0; //Toast.MakeText(this, point.ToString(), ToastLength.Long).Show(); mBaidumap.HideInfoWindow(); }; //--begin--初始化搜索模块,注册处理事件 mSearch = RoutePlanSearch.NewInstance(); //处理驾车搜索结果 mSearch.GetDrivingRouteResult += (s, e) => { var result = e.P0; if (result == null || result.Error != SearchResult.ERRORNO.NoError) { Toast.MakeText(this, "抱歉,未找到结果", ToastLength.Short).Show(); } if (result.Error == SearchResult.ERRORNO.AmbiguousRoureAddr) { //起终点或途经点地址有岐义,通过result.SuggestAddrInfo属性获取建议查询信息 //...... return; } if (result.Error == SearchResult.ERRORNO.NoError) { nodeIndex = -1; btnPre.Visibility = ViewStates.Visible; btnNext.Visibility = ViewStates.Visible; route = result.RouteLines[0]; DrivingRouteOverlay overlay = new MyDrivingRouteOverlay(this, mBaidumap); routeOverlay = overlay; mBaidumap.MarkerClick += (sender, args) => { //...... }; overlay.SetData(result.RouteLines[0]); overlay.AddToMap(); overlay.ZoomToSpan(); } }; //处理公交搜索结果 mSearch.GetTransitRouteResult += (s,e) => { var result = e.P0; if (result == null || result.Error != SearchResult.ERRORNO.NoError) { Toast.MakeText(this, "抱歉,未找到结果", ToastLength.Short).Show(); } if (result.Error == SearchResult.ERRORNO.AmbiguousRoureAddr) { //起终点或途经点地址有岐义,通过以下接口获取建议查询信息 //result.getSuggestAddrInfo() return; } if (result.Error == SearchResult.ERRORNO.NoError) { nodeIndex = -1; btnPre.Visibility = ViewStates.Visible; btnNext.Visibility = ViewStates.Visible; route = result.RouteLines[0]; TransitRouteOverlay overlay = new MyTransitRouteOverlay(this, mBaidumap); mBaidumap.MarkerClick += (sender, args) => { //...... }; routeOverlay = overlay; overlay.SetData(result.RouteLines[0]); overlay.AddToMap(); overlay.ZoomToSpan(); } }; //处理步行搜索结果 mSearch.GetWalkingRouteResult += (s, e) => { var result = e.P0; if (result == null || result.Error != SearchResult.ERRORNO.NoError) { Toast.MakeText(this, "抱歉,未找到结果", ToastLength.Short).Show(); } if (result.Error == SearchResult.ERRORNO.AmbiguousRoureAddr) { //起终点或途经点地址有岐义,通过以下接口获取建议查询信息 //result.getSuggestAddrInfo() return; } if (result.Error == SearchResult.ERRORNO.NoError) { nodeIndex = -1; btnPre.Visibility = ViewStates.Visible; btnNext.Visibility = ViewStates.Visible; route = result.RouteLines[0]; WalkingRouteOverlay overlay = new MyWalkingRouteOverlay(this, mBaidumap); mBaidumap.MarkerClick += (sender, args) => { //...... }; routeOverlay = overlay; overlay.SetData(result.RouteLines[0]); overlay.AddToMap(); overlay.ZoomToSpan(); } }; //处理骑行搜索结果 mSearch.GetBikingRouteResult += (s, e) => { var result = e.P0; if (result == null || result.Error != SearchResult.ERRORNO.NoError) { Toast.MakeText(this, "抱歉,未找到结果", ToastLength.Short).Show(); } if (result.Error == SearchResult.ERRORNO.AmbiguousRoureAddr) { // 如果起终点或途经点地址有岐义,可通过result.SuggestAddrInfo属性获取建议查询信息 //...... return; } if (result.Error == SearchResult.ERRORNO.NoError) { nodeIndex = -1; btnPre.Visibility = ViewStates.Visible; btnNext.Visibility = ViewStates.Visible; route = result.RouteLines[0]; BikingRouteOverlay overlay = new MyBikingRouteOverlay(this, mBaidumap); routeOverlay = overlay; mBaidumap.MarkerClick += (sender, args) => { //...... }; overlay.SetData(result.RouteLines[0]); overlay.AddToMap(); overlay.ZoomToSpan(); } }; //--end--初始化搜索模块,注册监听事件 //处理【驾车搜素】按钮点击事件 var btnDrive = FindViewById<Button>(Resource.Id.drive); btnDrive.Click += delegate { SearchButtonProcess(Resource.Id.drive); }; //处理【公交搜素】按钮点击事件 var btnTransit = FindViewById<Button>(Resource.Id.transit); btnTransit.Click += delegate { SearchButtonProcess(Resource.Id.transit); }; //处理【步行搜素】按钮点击事件 var btnWalk = FindViewById<Button>(Resource.Id.walk); btnWalk.Click += delegate { SearchButtonProcess(Resource.Id.walk); }; //处理【骑行搜素】按钮点击事件 var btnBike = FindViewById<Button>(Resource.Id.bike); btnBike.Click += delegate { SearchButtonProcess(Resource.Id.bike); }; //处理【自定义起终点图标】按钮点击事件 var btnCustomicon = FindViewById<Button>(Resource.Id.customicon); btnCustomicon.Click += delegate { //切换路线图标,刷新地图使其生效。注意:起终点图标使用中心对齐。 if (routeOverlay == null) return; if (useDefaultIcon) { btnCustomicon.Text = "自定义起终点图标"; Toast.MakeText(this,"将使用系统起终点图标", ToastLength.Short).Show(); } else { btnCustomicon.Text = "系统起终点图标"; Toast.MakeText(this, "将使用自定义起终点图标", ToastLength.Short).Show(); } useDefaultIcon = !useDefaultIcon; routeOverlay.RemoveFromMap(); routeOverlay.AddToMap(); }; //处理节点浏览相关的按钮事件 btnPre.Click += delegate { NodeClick(Resource.Id.pre); }; btnNext.Click += delegate { NodeClick(Resource.Id.next); }; } /// <summary> /// 发起路线规划搜索 /// </summary> /// <param name="id">按钮的id</param> public void SearchButtonProcess(int id) { //重置浏览节点的路线数据 route = null; btnPre.Visibility = ViewStates.Invisible; btnNext.Visibility = ViewStates.Invisible; mBaidumap.Clear(); // 处理搜索按钮响应示例 EditText editSt = FindViewById<EditText>(Resource.Id.start); EditText editEn = FindViewById<EditText>(Resource.Id.end); //设置起终点信息,对于tranist search 来说,城市名无意义 PlanNode stNode = PlanNode.WithCityNameAndPlaceName("北京", editSt.Text); PlanNode enNode = PlanNode.WithCityNameAndPlaceName("北京", editEn.Text); // 实际使用中请对起点终点城市进行正确的设定 if (id == Resource.Id.drive) { mSearch.DrivingSearch(new DrivingRoutePlanOption() .From(stNode).To(enNode)); } else if (id == Resource.Id.transit) { mSearch.TransitSearch(new TransitRoutePlanOption() .From(stNode).City("北京").To(enNode)); } else if (id == Resource.Id.walk) { mSearch.WalkingSearch(new WalkingRoutePlanOption() .From(stNode).To(enNode)); } else if (id == Resource.Id.bike) { mSearch.BikingSearch(new BikingRoutePlanOption() .From(stNode).To(enNode)); } } /// <summary> /// 节点浏览示例 /// </summary> /// <param name="id">按钮的id</param> public void NodeClick(int id) { if (nodeIndex < -1 || route == null || route.AllStep == null || nodeIndex > route.AllStep.Count) { return; } //设置节点索引 if (id == Resource.Id.next && nodeIndex < route.AllStep.Count - 1) { nodeIndex++; } else if (id == Resource.Id.pre && nodeIndex > 1) { nodeIndex--; } if (nodeIndex < 0 || nodeIndex >= route.AllStep.Count) { return; } //获取节结果信息 LatLng nodeLocation = null; string nodeTitle = null; var step = route.AllStep[nodeIndex]; if (step is DrivingRouteLine.DrivingStep) { nodeLocation = ((DrivingRouteLine.DrivingStep)step).Entrance.Location; nodeTitle = ((DrivingRouteLine.DrivingStep)step).Instructions; } else if (step is WalkingRouteLine.WalkingStep) { nodeLocation = ((WalkingRouteLine.WalkingStep)step).Entrance.Location; nodeTitle = ((WalkingRouteLine.WalkingStep)step).Instructions; } else if (step is TransitRouteLine.TransitStep) { nodeLocation = ((TransitRouteLine.TransitStep)step).Entrance.Location; nodeTitle = ((TransitRouteLine.TransitStep)step).Instructions; } if (nodeLocation == null || nodeTitle == null) { return; } //移动节点至中心 mBaidumap.SetMapStatus(MapStatusUpdateFactory.NewLatLng(nodeLocation)); // Show popup popupText= new TextView(this); popupText.SetBackgroundResource(Resource.Drawable.popup); popupText.SetTextColor(Android.Graphics.Color.Black); popupText.Text = nodeTitle; mBaidumap.ShowInfoWindow(new InfoWindow(popupText, nodeLocation, 0)); } protected override void OnRestoreInstanceState(Bundle savedInstanceState) { base.OnRestoreInstanceState(savedInstanceState); } //定制RouteOverly private class MyDrivingRouteOverlay : DrivingRouteOverlay { Demo13RoutePlan routePlanDemo; public MyDrivingRouteOverlay(Demo13RoutePlan routePlanDemo, BaiduMap baiduMap) : base(baiduMap) { this.routePlanDemo = routePlanDemo; } public override BitmapDescriptor GetStartMarker() { if (routePlanDemo.useDefaultIcon) { return BitmapDescriptorFactory.FromResource(Resource.Drawable.icon_st); } return null; } public override BitmapDescriptor GetTerminalMarker() { if (routePlanDemo.useDefaultIcon) { return BitmapDescriptorFactory.FromResource(Resource.Drawable.icon_en); } return null; } } private class MyWalkingRouteOverlay : WalkingRouteOverlay { Demo13RoutePlan routePlanDemo; public MyWalkingRouteOverlay(Demo13RoutePlan routePlanDemo, BaiduMap baiduMap) : base(baiduMap) { this.routePlanDemo = routePlanDemo; } public new BitmapDescriptor GetStartMarker() { if (routePlanDemo.useDefaultIcon) { return BitmapDescriptorFactory.FromResource(Resource.Drawable.icon_st); } return null; } public new BitmapDescriptor GetTerminalMarker() { if (routePlanDemo.useDefaultIcon) { return BitmapDescriptorFactory.FromResource(Resource.Drawable.icon_en); } return null; } } private class MyTransitRouteOverlay : TransitRouteOverlay { Demo13RoutePlan routePlanDemo; public MyTransitRouteOverlay(Demo13RoutePlan routePlanDemo, BaiduMap baiduMap) : base(baiduMap) { this.routePlanDemo = routePlanDemo; } public override BitmapDescriptor GetStartMarker() { if (routePlanDemo.useDefaultIcon) { return BitmapDescriptorFactory.FromResource(Resource.Drawable.icon_st); } return null; } public override BitmapDescriptor GetTerminalMarker() { if (routePlanDemo.useDefaultIcon) { return BitmapDescriptorFactory.FromResource(Resource.Drawable.icon_en); } return null; } } private class MyBikingRouteOverlay : BikingRouteOverlay { Demo13RoutePlan routePlanDemo; public MyBikingRouteOverlay(Demo13RoutePlan routePlanDemo, BaiduMap baiduMap) : base(baiduMap) { this.routePlanDemo = routePlanDemo; } public new BitmapDescriptor GetStartMarker() { if (routePlanDemo.useDefaultIcon) { return BitmapDescriptorFactory.FromResource(Resource.Drawable.icon_st); } return null; } public new BitmapDescriptor GetTerminalMarker() { if (routePlanDemo.useDefaultIcon) { return BitmapDescriptorFactory.FromResource(Resource.Drawable.icon_en); } return null; } } protected override void OnPause() { mMapView.OnPause(); base.OnPause(); } protected override void OnResume() { mMapView.OnResume(); base.OnResume(); } protected override void OnDestroy() { mSearch.Destroy(); mMapView.OnDestroy(); base.OnDestroy(); } } }
4、修改MainActivity.cs
在MainActivity.cs文件的demos字段定义中,去掉【示例13】下面的注释。
运行观察结果。