我是第一次在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一點點來,本人也是新手如果有什麼不對的或者是批評建議還請高手指出。下面是截圖,我專門找了一個用名字找不到必須得用座標找的。