你的位置:首页 > ASP.net教程

[ASP.net教程]第3章(第13讲) 路径规划功能


分类:C#、Android、百度地图应用; 日期:2016-02-04

一、简介

线路规划支持以下功能:

  • 公交信息查询:可对公交详细信息进行查询;
  • 公交换乘查询:根据起、终点,查询策略,进行线路规划方案;
  • 驾车线路规划:提供不同策略,规划驾车路线;(支持设置途经点)
  • 步行路径检索:支持步行路径的规划。

其中驾车线路规划自v3.4.0版本起支持多线路检索结果的能力。

二、运行截图

简介:介绍公交、驾车和步行三种线路规划方法和自设路线方法。

详述:

(1)驾车查询新增路径点查询功能,具体使用方法详见开发者指南路径规划部分,只需重载接口;

(2)自设路线功能演示开发者如何自己设定一条路线,包括如何设定起点、终点、途径站点和路段;

(3)自设路线功能同时也介绍如何在两个Activity之间切换的时候管理Mapview的生命周期;

(4)可自定义路线的起终点图标;

本示例运行截图如下:

image

三、设计步骤

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.在layout文件夹下添加该文件,然后将代码改为下面的内容:

<??><LinearLayout ="http://schemas.android.com/apk/res/android"  android:layout_width="fill_parent"  android:layout_height="fill_parent"  android:orientation="vertical" >  <LinearLayout    ="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    ="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    ="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    ="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      ="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      ="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】下面的注释。

运行观察结果。