分類:C#、Android、百度地圖應用; 日期: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】下面的注釋。
運行觀察結果。