我是第一次在CSDN写博客,是因为一起实习的学长嫌弃我总问他问题,就把一个类似于《车来了》的《班车系统》交给了我一个人,从那以后我必须要孤军奋战,自己研究不会的问题,对于我来说也是成长。每天都会遇到新问题,每天也都会解决新问题。好记忆不如烂笔头,烂笔头不如CSDN,我必须把它们都记下来,以便以后查看,也方便和你们共享。
废话不多说了,今天的成果是完成了将百度地图的poi检索跟route查找路线说简单点就是将他们结合了起来,功能就是,点击一个按钮,显示附近最近的5个站点,点击5各种的某一个标记物,立刻检索出你的位置到该标记物的换乘路径,所谓换乘就是公交车啊,打的啊,地铁啊这样子。
先上代码:(代码中间会有文字,将文字去掉就是完整的代码,xml文件就是两个按钮,一个spinner,和百度地图,此处就省略了。)
package com.zwin.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.LocationClientOption.LocationMode;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.UiSettings;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.overlayutil.PoiOverlay;
import com.baidu.mapapi.overlayutil.TransitRouteOverlay;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiDetailSearchOption;
import com.baidu.mapapi.search.poi.PoiNearbySearchOption;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;
import com.baidu.mapapi.search.route.PlanNode;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.baidu.mapapi.search.route.TransitRoutePlanOption;
import com.baidu.mapapi.search.route.TransitRoutePlanOption.TransitPolicy;
import com.baidu.mapapi.search.route.TransitRouteResult;
import com.baidu.mapapi.search.route.WalkingRouteResult;
import com.baidu.mapapi.search.share.OnGetShareUrlResultListener;
import com.baidu.mapapi.search.share.ShareUrlResult;
import com.baidu.mapapi.search.share.ShareUrlSearch;
public class PoiRouteSearch extends Activity implements OnClickListener {
// 百度地图定位相关
LocationClient mLocClient;
public MyLocationListenner myListener = new MyLocationListenner();
private LocationMode mCurrentMode;
BitmapDescriptor mCurrentMarker;
private UiSettings mUiSettings;
private MapView mapView;
private BaiduMap bdMap;
boolean isFirstLoc = true;// 是否首次定位
boolean isLocation = true;
boolean ischaxun = true;
LatLng ll;
LatLng end;
//
private PoiSearch poiSearch;
private ShareUrlSearch shareUrlSearch;
private EditText editCityEt, editSearchKeyEt;
ImageView huigui1;
ImageView zhandianchaxun1;
// 记录页标
private int page = 1;
private int totalPage = 0;
private double latitude;
private double longitude;
// 路线查询相关
private Spinner transitSpinner1;
private RoutePlanSearch routePlanSearch;// 路径规划搜索接口
private int index = -1;
private int totalLine = 0;// 记录某种搜索出的方案数量
private int drivintResultIndex = 0;// 驾车路线方案index
private int transitResultIndex = 0;// 换乘路线方案index
String endPoint = null;
int a = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_poi_search);
init();
// 不显示百度地图Logo
mapView.removeViewAt(1);
mapView.showZoomControls(true);
}
private void init() {
mapView = (MapView) findViewById(R.id.mapview);
bdMap = mapView.getMap();
// 开启定位图层
bdMap.setMyLocationEnabled(true);
bdMap.setMapStatus(MapStatusUpdateFactory.zoomTo(15.0f));
// 实例化PoiSearch对象
poiSearch = PoiSearch.newInstance();
// 设置检索监听器
poiSearch.setOnGetPoiSearchResultListener(poiSearchListener);
huigui1 = (ImageView) findViewById(R.id.huiguidingwei1);
zhandianchaxun1 = (ImageView) findViewById(R.id.zhandianchaxun);
zhandianchaxun1.setOnClickListener(this);
huigui1.setOnClickListener(this);
// 定位相关
mCurrentMarker = BitmapDescriptorFactory.fromResource(R.drawable.pin);
bdMap.setMyLocationConfigeration(new MyLocationConfiguration(null,
false, null));
// 定位初始化
mLocClient = new LocationClient(PoiRouteSearch.this);
mLocClient.registerLocationListener(myListener);
LocationClientOption option = new LocationClientOption();
option.setIsNeedAddress(true);
option.setOpenGps(true);// 打开gps
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(1000);
mLocClient.setLocOption(option);
mLocClient.start();
// bdMap.setOnMapClickListener(this);
shareUrlSearch = ShareUrlSearch.newInstance();
</pre><pre name="code" class="java">//这里是一个spinner,暂时没有什么用,在xml文件中我也将他隐藏了,看看以后会不会根据什么条件查询,如果没有到时再删掉把。
</pre><pre name="code" class="java"> transitSpinner1 = (Spinner) findViewById(R.id.transit_spinner1);
String[] transitItems = getResources().getStringArray(
R.array.transit_spinner);
ArrayAdapter<String> transitAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, transitItems);
transitSpinner1.setAdapter(transitAdapter);
transitSpinner1.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
if (index == 1) {
transitResultIndex = 0;
transitSearch1(transitResultIndex);
transitSearch2(transitResultIndex);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
routePlanSearch = RoutePlanSearch.newInstance();
routePlanSearch
.setOnGetRoutePlanResultListener(routePlanResultListener);
}
</pre><pre name="code" class="java">//这里是路径规划的监听器,分为步行,驾车和换乘,因为我做的是《班车系统》,就改动了换乘的代码
</pre><pre name="code" class="java"> OnGetRoutePlanResultListener routePlanResultListener = new OnGetRoutePlanResultListener() {
@Override
public void onGetWalkingRouteResult(WalkingRouteResult arg0) {
// TODO Auto-generated method stub
}
@Override
public void onGetTransitRouteResult(
TransitRouteResult transitRouteResult) {
// TODO Auto-generated method stub
bdMap.clear();
</pre><pre name="code" class="java">//这里设这么多if,其实是一个挺有意思的状况,我慢慢说。
//原因是,有些目标点根据名字搜索搜索不到,百度地图需要非常明确地起点和终点,所以有时可能检索不到。
//但是如果根据坐标查询,有时候目标会定位在非常不应该定位到的地方,比如说河里。
//所以我就写了两种,一个是按名字查,一个是按坐标查。首先a=0,先按名字检索,如果找到,一切OK,如果没找到,a++。
//如果a=1了,此时按照坐标检索。
//如果没有找到在没有找到的方法里a++,若a=2,显示"真的没有找到路线"。 如果再找不到我也没有办法了。
//这个方法还是挺笨的,如果那个高手有更好的办法,望指出。
</pre><pre name="code" class="java"> if (transitRouteResult == null
|| transitRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
// TODO 按坐标查询
a++;
}
if (a == 1) {
transitSearch2(transitResultIndex);
<span style="font-family: Arial, Helvetica, sans-serif;"> a = a + +;</span>
}
if (a == 2) {
Toast.makeText(PoiRouteSearch.this,<span style="font-family: Arial, Helvetica, sans-serif;">"真的没有找到路线"</span><span style="font-family: Arial, Helvetica, sans-serif;"> ,</span>Toast.LENGTH_SHORT).show();
a = 0;
}
if (transitRouteResult.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
// 起终点或途经点地址有岐义,通过以下接口获取建议查询信息
// drivingRouteResult.getSuggestAddrInfo()
return;
}
if (transitRouteResult.error == SearchResult.ERRORNO.NO_ERROR) {
TransitRouteOverlay transitRouteOverlay = new TransitRouteOverlay(
bdMap);
transitRouteOverlay.setData(transitRouteResult.getRouteLines()
.get(drivintResultIndex));// 设置一条驾车路线方案
bdMap.setOnMarkerClickListener(transitRouteOverlay);
transitRouteOverlay.addToMap();
transitRouteOverlay.zoomToSpan();
totalLine = transitRouteResult.getRouteLines().size();
}
// 通过getTaxiInfo()可以得到很多关于打车的信息
// Toast.makeText(
// PoiRouteSearch.this,
// "该路线打车总路程" + transitRouteResult.getTaxiInfo().getDistance(),
// 1000).show();
}
@Override
public void onGetDrivingRouteResult(DrivingRouteResult arg0) {
// TODO Auto-generated method stub
}
};
/**
* 兴趣点查询监听器
*/
OnGetPoiSearchResultListener poiSearchListener = new OnGetPoiSearchResultListener() {
@Override
public void onGetPoiResult(PoiResult poiResult) {
System.out.println(poiResult);
if (poiResult == null
|| poiResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {// 没有找到检索结果
Toast.makeText(PoiRouteSearch.this, "错", Toast.LENGTH_LONG)
.show();
// transitSearch2(transitResultIndex);
return;
}
</pre><pre name="code" class="java">//这个是搜索poi,将它们显示在地图上
if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {// 检索结果正常返回
bdMap.clear();
MyPoiOverlay poiOverlay = new MyPoiOverlay(bdMap);
poiOverlay.setData(poiResult);// 设置POI数据
bdMap.setOnMarkerClickListener(poiOverlay);
if (ischaxun) {
poiOverlay.addToMap();// 将所有的overlay添加到地图上
poiOverlay.zoomToSpan();
//
totalPage = poiResult.getTotalPageNum();// 获取总分页数
Toast.makeText(PoiRouteSearch.this, "最近的5个公交站",
Toast.LENGTH_SHORT).show();
ischaxun = false;
} else {
poiOverlay.removeFromMap();
Toast.makeText(PoiRouteSearch.this, "移除并回归定位",
Toast.LENGTH_SHORT).show();
ischaxun = true;
isFirstLoc = true;
}
}
}
@Override
public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
if (poiDetailResult.error != SearchResult.ERRORNO.NO_ERROR) {
Toast.makeText(PoiRouteSearch.this, "抱歉,未找到结果",
Toast.LENGTH_SHORT).show();
} else {// 正常返回结果的时候,此处可以获得很多相关信息
// TODO zheli
</pre><pre name="code" class="java">//这里获取到了目标点,也就是你点击的poi的名字跟坐标,方便之后定位
end = poiDetailResult.getLocation();
endPoint = poiDetailResult.getName();
Toast.makeText(
PoiRouteSearch.this,
poiDetailResult.getName() + ": "
+ poiDetailResult.getAddress(),
Toast.LENGTH_SHORT).show();
index = 1;
transitResultIndex = 0;
try {
transitSearch1(transitResultIndex);
} catch (Exception e) {
// TODO: handle exception
Toast.makeText(PoiRouteSearch.this, "错了",
Toast.LENGTH_SHORT).show();
}
}
}
};
/**
* 短串检索监听器
*/
OnGetShareUrlResultListener shareUrlResultListener = new OnGetShareUrlResultListener() {
@Override
public void onGetPoiDetailShareUrlResult(ShareUrlResult arg0) {
}
@Override
public void onGetLocationShareUrlResult(ShareUrlResult arg0) {
}
};
class MyPoiOverlay extends PoiOverlay {
public MyPoiOverlay(BaiduMap arg0) {
super(arg0);
}
@Override
public boolean onPoiClick(int arg0) {
super.onPoiClick(arg0);
PoiInfo poiInfo = getPoiResult().getAllPoi().get(arg0);
poiSearch.searchPoiDetail(new PoiDetailSearchOption()
.poiUid(poiInfo.uid));
return true;
}
}
/**
* 附近检索
*/
//以10000米为半径检索最近的5个
private void nearbySearch(int page) {
PoiNearbySearchOption nearbySearchOption = new PoiNearbySearchOption();
nearbySearchOption.location(new LatLng(latitude, longitude));
nearbySearchOption.keyword("公交站");
nearbySearchOption.radius(10000);// 检索半径,单位是米
nearbySearchOption.pageCapacity(5);// 默认每页5条
nearbySearchOption.pageNum(page);
poiSearch.searchNearby(nearbySearchOption);// 发起附近检索请求
}
/**
* 换乘路线查询
*/
//这个是根据名字,必须是天津的
private void transitSearch1(int index) {
TransitRoutePlanOption transitOption = new TransitRoutePlanOption();
transitOption.city("天津");// 设置换乘路线规划城市,起终点中的城市将会被忽略
transitOption.from(PlanNode.withLocation(ll));
transitOption.to(PlanNode.withCityNameAndPlaceName("天津", endPoint));// 按照名字查询
transitOption.policy(TransitPolicy.values()[transitSpinner1
.getSelectedItemPosition()]);// 设置换乘策略
routePlanSearch.transitSearch(transitOption);
}
</pre><pre name="code" class="java">//这个是根据坐标
private void transitSearch2(int index) {
TransitRoutePlanOption transitOption = new TransitRoutePlanOption();
transitOption.city("天津");// 设置换乘路线规划城市,起终点中的城市将会被忽略
transitOption.from(PlanNode.withLocation(ll));
transitOption.to(PlanNode.withLocation(end));// 按照坐标查询
transitOption.policy(TransitPolicy.values()[transitSpinner1
.getSelectedItemPosition()]);// 设置换乘策略
routePlanSearch.transitSearch(transitOption);
}
/**
* 定位SDK监听函数
*/
public class MyLocationListenner implements BDLocationListener {
@Override
public void onReceiveLocation(BDLocation location) {
// map view 销毁后不在处理新接收的位置
if (location == null || bdMap == null)
return;
MyLocationData locData = new MyLocationData.Builder()
.accuracy(location.getRadius())
// 此处设置开发者获取到的方向信息,顺时针0-360
.direction(100).latitude(location.getLatitude())
.longitude(location.getLongitude()).build();
bdMap.setMyLocationData(locData);
</pre><pre name="code" class="java">//这个是定位,如果isFirstLoc是true就重新定位,之后点击回归按钮回归定位也就是将isFirstLoc置为true而已
if (isFirstLoc) {
isFirstLoc = false;
latitude = location.getLatitude();
longitude = location.getLongitude();
ll = new LatLng(location.getLatitude(), location.getLongitude());
MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(ll);
bdMap.setMapStatus(u);
}
}
public void onReceivePoi(BDLocation poiLocation) {
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.huiguidingwei1:
isFirstLoc = true;
Toast.makeText(PoiRouteSearch.this, "回归定位", Toast.LENGTH_SHORT)
.show();
break;
case R.id.zhandianchaxun:
//点击这个按钮检索
page = 1;
bdMap.clear();
nearbySearch(page);
break;
}
}
public void onMapClick(LatLng point) {
bdMap.hideInfoWindow();
}
public boolean onMapPoiClick(MapPoi poi) {
return false;
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
poiSearch.destroy();// 释放poi检索对象
mapView.onDestroy();
super.onDestroy();
}
}
其实也不难,自己根据百度地图demo一点点来,本人也是新手如果有什么不对的或者是批评建议还请高手指出。下面是截图,我专门找了一个用名字找不到必须得用坐标找的。