<?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:onClick="SearchButtonProcess"
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:onClick="SearchButtonProcess"
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:onClick="SearchButtonProcess"
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.MapView
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:onClick="changeRouteIcon"
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_"
android:onClick="nodeClick" />
<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_"
android:onClick="nodeClick" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>
/**
* 此demo用来展示如何进行驾车、步行、公交路线搜索并在地图使用RouteOverlay、TransitOverlay绘制
* 同时展示如何进行节点浏览并弹出泡泡
*
* 介绍公交,驾车和不行三种线路规划方法和自设路线方法
*/
public class RoutePlanDemo extends Activity implements BaiduMap.OnMapClickListener,
OnGetRoutePlanResultListener {
//上一个节点
Button mBtnPre = null;
//下一个节点
Button mBtnNext = null;
//节点索引,供浏览节点时使用
int nodeIndex = -1;
/**
* 路线数据结构的基类,表示一条路线,路线可能包括:路线规划中的换乘/驾车/步行路线
* 此类为路线数据结构的基类,一般关注其子类对象即可,无需直接生成该类对象
* */
RouteLine route = null;
/**
* 该类提供一个能够显示和管理多个Overlay的基类
* */
OverlayManager routeOverlay = null;
boolean useDefaultIcon = false;
private TextView popupText = null;//泡泡view
//地图相关,使用继承MapView的MyRouteMapView目的是重写touch事件实现泡泡处理
//如果不处理touch事件,则无需继承,直接使用MapView即可
// 地图View
MapView mMapView = null;
BaiduMap mBaidumap = null;
/**
* 路径规划搜索接口
* */
RoutePlanSearch mSearch = null; // 搜索模块,也可去掉地图模块独立使用
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_routeplan);
CharSequence titleLable = "路线规划功能";
setTitle(titleLable);
//初始化地图
mMapView = (MapView) findViewById(R.id.map);
mBaidumap = mMapView.getMap();
mBtnPre = (Button) findViewById(R.id.pre);
mBtnNext = (Button) findViewById(R.id.next);
mBtnPre.setVisibility(View.INVISIBLE);
mBtnNext.setVisibility(View.INVISIBLE);
/**
* public final void setOnMapClickListener(BaiduMap.OnMapClickListener listener)
* 设置地图单击事件监听者
* @param listener - 地图单击事件监听者
* 需要实现BaiduMap.OnMapClickListener接口的
* onMapClick(LatLng point)和onMapPoiClick(MapPoi poi)方法
* */
mBaidumap.setOnMapClickListener(this);
/**
* public static RoutePlanSearch newInstance()
* 获取RoutePlan检索实例
* @param RoutePlan检索实例
* */
mSearch = RoutePlanSearch.newInstance();
/**
* public void setOnGetRoutePlanResultListener(OnGetRoutePlanResultListener listener)
* 设置路线检索监听者
* @param listener - 监听者
* 需要实现以下方法:
* onGetDrivingRouteResult(DrivingRouteResult result)
* onGetTransitRouteResult(TransitRouteResult result)
* onGetWalkingRouteResult(WalkingRouteResult result)
* */
mSearch.setOnGetRoutePlanResultListener(this);
}
/**
* 驾车搜索,公交搜索,步行搜索按钮点击事件
*
* 发起路线规划搜索示例
* @param v
*/
public void SearchButtonProcess(View v) {
//重置浏览节点的路线数据
route = null;
mBtnPre.setVisibility(View.INVISIBLE);
mBtnNext.setVisibility(View.INVISIBLE);
mBaidumap.clear();
// 处理搜索按钮响应
EditText editSt = (EditText) findViewById(R.id.start);
EditText editEn = (EditText) findViewById(R.id.end);
//设置起终点信息,对于tranist search 来说,城市名无意义
/**
* PlanNode:
* 路径规划中的出行节点信息,出行节点包括:起点,终点,途经点
* 出行节点信息可以通过两种方式确定:
*
* 1: 给定出行节点经纬度坐标
* 2: 给定出行节点地名和城市名
*
* public static PlanNode withCityNameAndPlaceName(java.lang.String city,
* java.lang.String placeName)
* 通过地名和城市名确定出行节点信息
* @param placeName - 地点名; city - 城市名
* @return 出行节点对象
* */
PlanNode stNode = PlanNode.withCityNameAndPlaceName("北京", editSt.getText().toString());
PlanNode enNode = PlanNode.withCityNameAndPlaceName("北京", editEn.getText().toString());
// 实际使用中请对起点终点城市进行正确的设定
/**
* 驾车搜索
* */
if (v.getId() == R.id.drive) {
/**
* public boolean drivingSearch(DrivingRoutePlanOption option)
* 发起驾车路线规划
* @param option - 请求参数
* @return 成功发起检索返回true , 失败返回false
*
* DrivingRoutePlanOption:驾车路线规划参数
* public DrivingRoutePlanOption from(PlanNode from)
* 设置起点
* @param from - 起点
* @return 该 DrivingRoutePlanOption 选项对象
*
* public DrivingRoutePlanOption to(PlanNode to)
* 设置终点
* @param to - 终点
* @return 该 DrivingRoutePlanOption 选项对象
* */
mSearch.drivingSearch((new DrivingRoutePlanOption())
.from(stNode)
.to(enNode));
/**
* 公交搜索
* */
} else if (v.getId() == R.id.transit) {
/**
* public boolean transitSearch(TransitRoutePlanOption option)
* 发起换乘路线规划
* @param option - 请求参数
* @return 成功发起检索返回true , 失败返回false
*
* TransitRoutePlanOption:换乘路线规划参数
* public TransitRoutePlanOption from(PlanNode from)
* 设置起点
* @param from - 起点
* @return 该换乘路线规划参数对象
*
* public TransitRoutePlanOption city(java.lang.String city)
* 设置换乘路线规划城市,起终点中的城市将会被忽略
* @param city - 城市
* @return 该换乘路线规划参数对象
*
* public TransitRoutePlanOption to(PlanNode to)
* 设置终点
* @return 该换乘路线规划参数对象
* */
mSearch.transitSearch((new TransitRoutePlanOption())
.from(stNode)
.city("北京")
.to(enNode));
/**
* 步行搜索
* */
} else if (v.getId() == R.id.walk) {
/**
* public boolean walkingSearch(WalkingRoutePlanOption option)
* 发起步行路线规划
* @param option - 请求参数
* @return 成功发起检索返回true , 失败返回false
*
* WalkingRoutePlanOption:步行路线规划参数
* public WalkingRoutePlanOption from(PlanNode from)
* 设置起点
* @param from - 起点
* @return 该步行路线规划参数对象
*
* public WalkingRoutePlanOption to(PlanNode to)
* 设置终点
* @param to - 终点
* @return 该步行路线规划参数对象
* */
mSearch.walkingSearch((new WalkingRoutePlanOption())
.from(stNode)
.to(enNode));
}
}
/**
* 上一个或下一个节点点击事件
*
* 节点浏览示例
*
* @param v
*/
public void nodeClick(View v) {
/**
* public java.util.List<T> getAllStep()
* 获取路线中的所有路段
* 返回:路线中的所有路段
* */
if (route == null ||route.getAllStep() == null) {
return;
}
if (nodeIndex == -1 && v.getId() == R.id.pre) {
return;
}
//设置节点索引
if (v.getId() == R.id.next) {
if (nodeIndex < route.getAllStep().size() - 1) {
nodeIndex++;
} else {
return;
}
} else if (v.getId() == R.id.pre) {
if (nodeIndex > 0) {
nodeIndex--;
} else {
return;
}
}
//获取节结果信息
LatLng nodeLocation = null;
String nodeTitle = null;
Object step = route.getAllStep().get(nodeIndex);
/**
* public static class DrivingRouteLine.DrivingStep extends RouteStep
* 表示一个驾车路段
*
* public RouteNode getEntrace()
* 路段入口信息
* 返回:路段入口信息
*
* public LatLng getLocation()
* 获取位置
* 返回:位置
*
* public java.lang.String getInstructions()
* 路段总体指示信息
* 返回: 路段总体指示信息
* */
if (step instanceof DrivingRouteLine.DrivingStep) {
nodeLocation = ((DrivingRouteLine.DrivingStep) step).getEntrace().getLocation();
nodeTitle = ((DrivingRouteLine.DrivingStep) step).getInstructions();
/**
* public static class WalkingRouteLine.WalkingStep extends RouteStep
* 描述一个步行路段
* */
} else if (step instanceof WalkingRouteLine.WalkingStep) {
nodeLocation = ((WalkingRouteLine.WalkingStep) step).getEntrace().getLocation();
nodeTitle = ((WalkingRouteLine.WalkingStep) step).getInstructions();
/**
* public static class TransitRouteLine.TransitStep extends RouteStep
* 表示一个换乘路段
* */
} else if (step instanceof TransitRouteLine.TransitStep) {
nodeLocation = ((TransitRouteLine.TransitStep) step).getEntrace().getLocation();
nodeTitle = ((TransitRouteLine.TransitStep) step).getInstructions();
}
if (nodeLocation == null || nodeTitle == null) {
return;
}
//移动节点至中心
mBaidumap.setMapStatus(MapStatusUpdateFactory.newLatLng(nodeLocation));
//显示弹出窗口
popupText = new TextView(RoutePlanDemo.this);
popupText.setBackgroundResource(R.drawable.popup);
popupText.setTextColor(0xFF000000);
popupText.setText(nodeTitle);
/**
* public void showInfoWindow(InfoWindow infoWindow)
* 显示 InfoWindow
* 参数:infoWindow - 要显示的 InfoWindow 对象
*
* InfoWindow:在地图中显示一个信息窗口,可以设置一个View作为该窗口的内容,
* 也可以设置一个 BitmapDescriptor作为该窗口的内容。
*
* public InfoWindow(View view,LatLng position,int yOffset)
通过传入的 view 构造一个 InfoWindow, 此时只是利用该view生成一个Bitmap绘制在地图中。
参数:
view - InfoWindow 展示的 view
position - InfoWindow 显示的地理位置
yOffset - InfoWindow Y 轴偏移量
listener - InfoWindow 点击监听者
* */
mBaidumap.showInfoWindow(new InfoWindow(popupText, nodeLocation, 0));
}
/**
* 自定义起终点图标点击事件
*
* 切换路线图标,刷新地图使其生效
* 注意: 起终点图标使用中心对齐.
*/
public void changeRouteIcon(View v) {
if (routeOverlay == null) {
return;
}
if (useDefaultIcon) {
((Button) v).setText("自定义起终点图标");
Toast.makeText(this,"将使用系统起终点图标",Toast.LENGTH_SHORT).show();
} else {
((Button) v).setText("系统起终点图标");
Toast.makeText(this,"将使用自定义起终点图标",Toast.LENGTH_SHORT).show();
}
useDefaultIcon = !useDefaultIcon;
/**
* public final void removeFromMap()
* 将所有Overlay 从 地图上消除
* */
routeOverlay.removeFromMap();
/**
* public final void addToMap()
* 将所有Overlay 添加到地图上
* */
routeOverlay.addToMap();
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
///BaiduMap.OnMapClickListener
@Override
public void onGetWalkingRouteResult(WalkingRouteResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(RoutePlanDemo.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
}
if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
//起终点或途经点地址有岐义,通过以下接口获取建议查询信息
//result.getSuggestAddrInfo()
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
nodeIndex = -1;
mBtnPre.setVisibility(View.VISIBLE);
mBtnNext.setVisibility(View.VISIBLE);
/**
* public java.util.List<WalkingRouteLine> getRouteLines()
* 获取所有步行规划路线
* 返回:所有步行规划路线
* */
route = result.getRouteLines().get(0);
WalkingRouteOverlay overlay = new MyWalkingRouteOverlay(mBaidumap);
/**
* 设置地图 Marker 覆盖物点击事件监听者
* 需要实现的方法: onMarkerClick(Marker marker)
* */
mBaidumap.setOnMarkerClickListener(overlay);
routeOverlay = overlay;
/**
* public void setData(WalkingRouteLine line)设置路线数据。
* 参数:line - 路线数据
* */
overlay.setData(result.getRouteLines().get(0));
/**
* public final void addToMap()将所有Overlay 添加到地图上
* */
overlay.addToMap();
/**
* public void zoomToSpan()
* 缩放地图,使所有Overlay都在合适的视野内
* 注: 该方法只对Marker类型的overlay有效
* */
overlay.zoomToSpan();
}
}
@Override
public void onGetTransitRouteResult(TransitRouteResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(RoutePlanDemo.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
}
if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
//起终点或途经点地址有岐义,通过以下接口获取建议查询信息
//result.getSuggestAddrInfo()
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
nodeIndex = -1;
mBtnPre.setVisibility(View.VISIBLE);
mBtnNext.setVisibility(View.VISIBLE);
route = result.getRouteLines().get(0);
TransitRouteOverlay overlay = new MyTransitRouteOverlay(mBaidumap);
mBaidumap.setOnMarkerClickListener(overlay);
routeOverlay = overlay;
overlay.setData(result.getRouteLines().get(0));
overlay.addToMap();
overlay.zoomToSpan();
}
}
@Override
public void onGetDrivingRouteResult(DrivingRouteResult result) {
if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(RoutePlanDemo.this, "抱歉,未找到结果", Toast.LENGTH_SHORT).show();
}
if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
//起终点或途经点地址有岐义,通过以下接口获取建议查询信息
//result.getSuggestAddrInfo()
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
nodeIndex = -1;
mBtnPre.setVisibility(View.VISIBLE);
mBtnNext.setVisibility(View.VISIBLE);
route = result.getRouteLines().get(0);
DrivingRouteOverlay overlay = new MyDrivingRouteOverlay(mBaidumap);
routeOverlay = overlay;
mBaidumap.setOnMarkerClickListener(overlay);
overlay.setData(result.getRouteLines().get(0));
overlay.addToMap();
overlay.zoomToSpan();
}
}
//定制RouteOverly
/**
* DrivingRouteOverlay已经实现了BaiduMap.OnMarkerClickListener接口
* */
private class MyDrivingRouteOverlay extends DrivingRouteOverlay {
public MyDrivingRouteOverlay(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public BitmapDescriptor getStartMarker() {
if (useDefaultIcon) {
return BitmapDescriptorFactory.fromResource(R.drawable.icon_st);
}
return null;
}
@Override
public BitmapDescriptor getTerminalMarker() {
if (useDefaultIcon) {
return BitmapDescriptorFactory.fromResource(R.drawable.icon_en);
}
return null;
}
}
/**
* WalkingRouteOverlay已经实现了BaiduMap.OnMarkerClickListener接口
* */
private class MyWalkingRouteOverlay extends WalkingRouteOverlay {
public MyWalkingRouteOverlay(BaiduMap baiduMap) {
super(baiduMap);
}
/**
* public BitmapDescriptor getStartMarker()
* 覆写此方法以改变默认起点图标
* 返回:起点图标
* */
@Override
public BitmapDescriptor getStartMarker() {
if (useDefaultIcon) {
return BitmapDescriptorFactory.fromResource(R.drawable.icon_st);
}
return null;
}
/**
* public BitmapDescriptor getTerminalMarker()
* 覆写此方法以改变默认终点图标
* 返回:终点图标
* */
@Override
public BitmapDescriptor getTerminalMarker() {
if (useDefaultIcon) {
return BitmapDescriptorFactory.fromResource(R.drawable.icon_en);
}
return null;
}
}
/**
* TransitRouteOverlay已经实现了BaiduMap.OnMarkerClickListener接口
* */
private class MyTransitRouteOverlay extends TransitRouteOverlay {
public MyTransitRouteOverlay(BaiduMap baiduMap) {
super(baiduMap);
}
@Override
public BitmapDescriptor getStartMarker() {
if (useDefaultIcon) {
return BitmapDescriptorFactory.fromResource(R.drawable.icon_st);
}
return null;
}
@Override
public BitmapDescriptor getTerminalMarker() {
if (useDefaultIcon) {
return BitmapDescriptorFactory.fromResource(R.drawable.icon_en);
}
return null;
}
}
BaiduMap.OnMapClickListener/
@Override
public void onMapClick(LatLng point) {
/**
* 隐藏当前 InfoWindow
* */
mBaidumap.hideInfoWindow();
}
/**
* 地图内 Poi 单击事件回调函数
* */
@Override
public boolean onMapPoiClick(MapPoi poi) {
return false;
}
@Override
protected void onPause() {
mMapView.onPause();
super.onPause();
}
@Override
protected void onResume() {
mMapView.onResume();
super.onResume();
}
@Override
protected void onDestroy() {
/**
* 释放检索实例,当不再使用时检索时,用户需要手动调用此接口.
* */
mSearch.destroy();
mMapView.onDestroy();
super.onDestroy();
}
}