分類: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】下面的注釋。
運行觀察結果。