[android] 百度地图开发 (二).定位城市位置和城市POI搜索
生活随笔
收集整理的這篇文章主要介紹了
[android] 百度地图开发 (二).定位城市位置和城市POI搜索
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一. 百度地圖城市定位和POI搜索知識
? ? ? 上一篇文章"百度地圖開發(fā)(一)"中講述了如何申請百度APIKey及解決顯示空白網(wǎng)格的問題.該篇文章主要講述如何定位城市位置、定位自己的位置和進行城市興趣點POI(Point of Interest)搜索.那么如何在百度地圖上定位某一個位置呢?
? ? ??通過類GeoPoint可以定義經(jīng)緯度,它存放著緯度值和經(jīng)度值,通過getLastKnownLocation()方法可以獲取Location對象,再定位經(jīng)緯度設(shè)置其為地圖中心即可顯示當(dāng)前位置.
? ? ? 其中Geopoint(緯度值,經(jīng)度值)以微度為單位,需要乘以10的6次方.核心代碼如下:
? ? ? 百度Map API提供MKSearch.geocode(String address, String city)方法進行GEO地理編碼檢索,它的意思就是搜索某個城市具體地址的位置,而如果只搜索城市使用geocode(city, city)即可.同時逆地址解析函數(shù)MKSearch.reverseGeocode(new GeoPoint(latitude, longitude))可以實現(xiàn)通過輸入經(jīng)緯度查詢具體地址.
? ? ? 其中核心代碼如下(代碼放置位置不同,詳見后面實例):
//初始化MKSearch mMKSearch = new MKSearch(); mMKSearch.init(mBMapManager, new MySearchListener()); //搜索城市 mMKSearch.geocode(city, city); //內(nèi)部類實現(xiàn)MKSearchListener接口,實現(xiàn)異步搜索服務(wù) public class MySearchListener implements MKSearchListener { @Override public void onGetAddrResult(MKAddrInfo result, int iError) { //經(jīng)緯度與地址搜索...mMapController.setCenter(result.geoPt);} } ? ? ?其中百度地圖API搜索主要通過初始化MKSearch類,同時其結(jié)果監(jiān)聽對象MKSearchListener類來實現(xiàn)一部搜索服務(wù).在該類中有很多方法實現(xiàn)不同功能,其中onGetAddrResult()方法可以根據(jù)經(jīng)緯度搜索地址信息,而我們需要實現(xiàn)的POI興趣點搜索是通過onGetPoiResult()實現(xiàn)的,同樣公交路線等搜索都可以通過它實現(xiàn).
? ? ? 具體核心代碼如下:
//內(nèi)部類實現(xiàn)MKSearchListener接口,實現(xiàn)異步搜索服務(wù) public class MySearchListener implements MKSearchListener { //經(jīng)緯度與地址搜索結(jié)果public void onGetAddrResult(MKAddrInfo result, int iError) {}//POI搜索結(jié)果(范圍檢索、城市POI檢索、周邊檢索)public void onGetPoiResult(MKPoiResult result, int type, int iError) { }//駕車路線搜索結(jié)果 public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {}//公交換乘路線搜索結(jié)果public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) { } //步行路線搜索結(jié)果public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) { }//獲取詳細(xì)信息public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {}public void onGetPoiDetailSearchResult(int arg0, int arg1) {}public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1,int arg2) {}public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {} } ? ? ??在android使用百度地圖中可以添加地圖覆蓋物,那么什么是覆蓋物呢?
? ? ? 所有疊加或覆蓋到地圖的內(nèi)容,我們統(tǒng)稱為地圖覆蓋物.如標(biāo)注、矢量圖形元素(包括:折線和多邊形和圓)、定位圖標(biāo)等.覆蓋物擁有自己的地理坐標(biāo),當(dāng)您拖動或縮放地圖時,它們會相應(yīng)的移動.
????? 地圖API提供了如下幾種覆蓋物:
? ? ? 1.Overlay?覆蓋物的抽象基類,所有的覆蓋物均繼承此類的方法,實現(xiàn)用戶自定義圖層顯示.
? ? ? 2.MyLocationOverlay?一個負(fù)責(zé)顯示用戶當(dāng)前位置的Overlay.
? ? ? 3.ItemizedOverlay<Item extends OverlayItem>?它是Overlay的一個基類,包含了一個OverlayItem列表,相當(dāng)于一組分條的Overlay,通過繼承此類將一組興趣點顯示在地圖上.
? ? ? 4.PoiOverlay?本地搜索圖層,提供某一特定地區(qū)的位置搜索服務(wù),比如在北京市搜索“公園”,通過此圖層將公園顯示在地圖上.
? ? ? 5.RouteOverlay?步行駕車導(dǎo)航線路圖層,將步行駕車出行方案的路線及關(guān)鍵點顯示在地圖上.
? ? ? 6.TransitOverlay?公交換乘線路圖層,將某一特定地區(qū)的公交出行方案的路線及換乘位置顯示在地圖上.
? ? ??我們這里可以使用MyLocationOverlay定位自己當(dāng)前位置添加覆蓋物,也可以在POI搜索過程中通過PoiOverlay添加搜索的興趣點覆蓋物.下面講述代碼及實現(xiàn).
二. 源碼實現(xiàn)
? ? ? 下載地址:http://download.csdn.net/detail/eastmount/8292969? ? ? 首先,設(shè)置其activity_main.xml布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/container"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#000000"tools:context="com.example.baidumapshow.MainActivity"tools:ignore="MergeRootFrame" ><!-- 頂部路徑 --><RelativeLayout android:id="@+id/MyLayout_top"android:orientation="horizontal" android:layout_width="fill_parent"android:layout_height="40dp" android:layout_alignParentTop="true"android:gravity="center"><LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@null" android:padding="0dip" > <EditText android:id="@+id/city_edittext" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical"android:layout_marginLeft="5dp"android:background="#ffffff" android:textSize="22dp" android:hint="輸入城市"android:layout_weight="15" /><EditText android:id="@+id/keyword_edittext" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical"android:layout_marginLeft="5dp"android:background="#ffffff" android:textSize="22dp" android:hint="輸入關(guān)鍵詞"android:layout_weight="25" /> <Button android:id="@+id/query_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textColor="#ffffff"android:textSize="20dp"android:text="搜索" /> </LinearLayout> </RelativeLayout><!-- 底部添加按鈕 --> <RelativeLayout android:id="@+id/MyLayout_bottom" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="50dp" android:layout_alignParentBottom="true" android:gravity="center"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:layout_alignParentBottom="true" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:textColor="#ffffff"android:text="定位" /> </LinearLayout> </RelativeLayout> <!-- 中部顯示圖片 --><RelativeLayoutandroid:id="@+id/Content_Layout" android:orientation="horizontal"android:layout_width="fill_parent" android:layout_height="fill_parent"android:layout_above="@id/MyLayout_bottom" android:layout_below="@id/MyLayout_top"android:gravity="center"><com.baidu.mapapi.map.MapView android:id="@+id/map_view"android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" /></RelativeLayout> </RelativeLayout>
? ? ? 然后是MainActivity.java源碼
public class MainActivity extends Activity {//BMapManager 對象管理地圖、定位、搜索功能private BMapManager mBMapManager; private MapView mapView = null; //地圖主控件 private MapController mMapController = null; //地圖控制 MKMapViewListener mMapListener = null; //處理地圖事件回調(diào) private MKSearch mMKSearch; //定義搜索服務(wù)類//搜索private EditText keyWordEditText; private EditText cityEditText;private Button queryButton; private static StringBuilder sb; private MyLocationOverlay myLocationOverlay;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);/*** 創(chuàng)建對象BMapManager并初始化操作* V2.3.1中init(APIKey,null) V2.4.1在AndroidManifest中賦值A(chǔ)K* 注意 初始化操作在setContentView()前*/mBMapManager = new BMapManager(getApplication()); mBMapManager.init(null); setContentView(R.layout.activity_main); mapView = (MapView) findViewById(R.id.map_view); cityEditText = (EditText) findViewById(R.id.city_edittext);keyWordEditText = (EditText) findViewById(R.id.keyword_edittext);queryButton = (Button) findViewById(R.id.query_button);mMapController = mapView.getController(); //獲取地圖控制器mMapController.enableClick(true); //設(shè)置地圖是否響應(yīng)點擊事mMapController.setZoom(16); //地圖縮放級別(3-19級) 級別越高信息越詳細(xì)mapView.setBuiltInZoomControls(true); //顯示內(nèi)置縮放控件/*** 獲取學(xué)校經(jīng)緯度 設(shè)置地圖中心點*/GeoPoint point = new GeoPoint((int)(39.96703 * 1E6), (int)(116.323772 * 1E6)); mMapController.setCenter(point); mapView.regMapViewListener(mBMapManager, new MKMapViewListener() { /** * 地圖移動完成時會回調(diào)此接口方法 */ @Override public void onMapMoveFinish() { //Toast.makeText(MainActivity.this, "地圖移動", Toast.LENGTH_SHORT).show();} /** * 地圖加載完畢回調(diào)此接口方法 */ @Override public void onMapLoadFinish() { Toast.makeText(MainActivity.this, "地圖載入", Toast.LENGTH_SHORT).show();} /** * 地圖完成帶動畫的操作(如: animationTo())后,此回調(diào)被觸發(fā) */ @Override public void onMapAnimationFinish() { } /** * 當(dāng)調(diào)用過 mMapView.getCurrentMap()后,此回調(diào)會被觸發(fā) * 可在此保存截圖至存儲設(shè)備 */ @Override public void onGetCurrentMap(Bitmap arg0) { } /** * 點擊地圖上被標(biāo)記的點回調(diào)此方法*/ @Override public void onClickMapPoi(MapPoi arg0) { if (arg0 != null){ Toast.makeText(MainActivity.this, arg0.strText, Toast.LENGTH_SHORT).show();} } }); /*** 初始化MKSearch 調(diào)用城市和POI搜索 */mMKSearch = new MKSearch();mMKSearch.init(mBMapManager, new MySearchListener()); queryButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mMapController = mapView.getController();mMapController.setZoom(10); sb = new StringBuilder(); //內(nèi)容清空 //輸入正確城市關(guān)鍵字String city = cityEditText.getText().toString().trim(); String keyWord = keyWordEditText.getText().toString().trim(); if(city.isEmpty()) { //默認(rèn)城市設(shè)置為貴陽city="貴陽";}//如果關(guān)鍵字為空只搜索城市 GEO搜索 geocode(adress,city) 具體地址和城市if(keyWord.isEmpty()) {mMKSearch.geocode(city, city); } else {//搜索城市+關(guān)鍵字 mMKSearch.setPoiPageCapacity(10); //每頁返回POI數(shù)mMKSearch.poiSearchInCity(city, keyWord); }} }); }@Overrideprotected void onResume() {mapView.onResume();if (mBMapManager != null) {mBMapManager.start();}super.onResume();}@Overrideprotected void onDestroy() {mapView.destroy();if (mBMapManager != null) {mBMapManager.destroy();mBMapManager = null;}super.onDestroy();}@Overrideprotected void onPause() {mapView.onPause();if (mBMapManager != null) {mBMapManager.stop();}super.onPause();} /** * 內(nèi)部類實現(xiàn)MKSearchListener接口,用于實現(xiàn)異步搜索服務(wù) */ public class MySearchListener implements MKSearchListener { /** * 根據(jù)經(jīng)緯度搜索地址信息結(jié)果 * 同時mMKSearch.geocode(city, city)搜索城市返回至該函數(shù)* * @param result 搜索結(jié)果 * @param iError 錯誤號(0表示正確返回) */ @Override public void onGetAddrResult(MKAddrInfo result, int iError) { if (result == null) { return; } StringBuffer sbcity = new StringBuffer(); sbcity.append(result.strAddr).append("\n"); //經(jīng)緯度所對應(yīng)的位置 mapView.getOverlays().clear(); //清除地圖上已有的所有覆蓋物 mMapController.setCenter(result.geoPt); //置為地圖中心//添加原點并刷新LocationData locationData = new LocationData();locationData.latitude = result.geoPt.getLatitudeE6();locationData.longitude = result.geoPt.getLongitudeE6();myLocationOverlay = new MyLocationOverlay(mapView);myLocationOverlay.setData(locationData);mapView.getOverlays().add(myLocationOverlay);mapView.refresh();// 通過AlertDialog顯示地址信息new AlertDialog.Builder(MainActivity.this) .setTitle("顯示當(dāng)前城市地圖") .setMessage(sbcity.toString()) .setPositiveButton("關(guān)閉", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.dismiss(); } }).create().show();} /** * POI搜索結(jié)果(范圍檢索、城市POI檢索、周邊檢索) * * @param result 搜索結(jié)果 * @param type 返回結(jié)果類型(11,12,21:poi列表 7:城市列表) * @param iError 錯誤號(0表示正確返回) */ @Override public void onGetPoiResult(MKPoiResult result, int type, int iError) { if (result == null) { return; } //獲取POI并顯示mapView.getOverlays().clear(); PoiOverlay poioverlay = new PoiOverlay(MainActivity.this, mapView);poioverlay.setData(result.getAllPoi()); //設(shè)置搜索到的POI數(shù)據(jù) mapView.getOverlays().add(poioverlay); //興趣點標(biāo)注在地圖上mapView.refresh(); //設(shè)置其中一個搜索結(jié)果所在地理坐標(biāo)為地圖的中心 if(result.getNumPois() > 0) { MKPoiInfo poiInfo = result.getPoi(0); mMapController.setCenter(poiInfo.pt); } //添加StringBuffer 遍歷當(dāng)前頁返回的POI (默認(rèn)只返回10個)sb.append("共搜索到").append(result.getNumPois()).append("個POI\n"); for (MKPoiInfo poiInfo : result.getAllPoi()) { sb.append("名稱:").append(poiInfo.name).append("\n");}// 通過AlertDialog顯示當(dāng)前頁搜索到的POI new AlertDialog.Builder(MainActivity.this) .setTitle("搜索到的POI信息") .setMessage(sb.toString()) .setPositiveButton("關(guān)閉", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.dismiss(); } }).create().show();} /** * 駕車路線搜索結(jié)果 * * @param result 搜索結(jié)果 * @param iError 錯誤號(0表示正確返回) */ @Override public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) { } /** * 公交換乘路線搜索結(jié)果 * * @param result 搜索結(jié)果 * @param iError 錯誤號(0表示正確返回) */ @Override public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) { } /** * 步行路線搜索結(jié)果 * * @param result 搜索結(jié)果 * @param iError 錯誤號(0表示正確返回) */ @Override public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) { }@Overridepublic void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {// TODO Auto-generated method stub}@Overridepublic void onGetPoiDetailSearchResult(int arg0, int arg1) {// TODO Auto-generated method stub}@Overridepublic void onGetShareUrlResult(MKShareUrlResult arg0, int arg1, int arg2) {// TODO Auto-generated method stub}@Overridepublic void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {// TODO Auto-generated method stub }} } ? ? ?最后設(shè)置AndroidManifest.xml文件,主要是申請網(wǎng)絡(luò)權(quán)限和設(shè)置APIKey
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.baidumapshow"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="19"android:targetSdkVersion="19" /><!-- 獲取網(wǎng)絡(luò)狀態(tài) --><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><!-- 訪問網(wǎng)絡(luò) --><uses-permission android:name="android.permission.INTERNET" /><!-- 獲取WiFi狀態(tài) --><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><!-- 允許程序?qū)懭胪獠看鎯?如SD卡上寫文件 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_SETTINGS" /><!-- 讀取電話狀態(tài) --><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.CALL_PHONE" /><!-- 獲取精確位置 GPS芯片接收衛(wèi)星的定位信息,定位精度達(dá)10米以內(nèi) --><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><!-- 通過WiFi或移動基站的方式獲取用戶錯略的經(jīng)緯度信息 --><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!-- 獲取模擬定位信息 --><uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /><uses-permission android:name="android.permission.ACCESS_GPS" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="QwaNhFQ0ty2QmdYh3Nrr0gQx"></meta-data> <activityandroid:name="com.example.baidumapshow.MainActivity"android:label="@string/app_name" ><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest> ? ? ? 程序運行結(jié)果如下圖所示:
? ? ? 當(dāng)只輸入城市名的時候顯示的是城市對應(yīng)的地圖.如下圖貴陽.
??
? ? ? 當(dāng)輸入城市+關(guān)鍵字時顯示POI興趣點,如北京的大學(xué).這里設(shè)置只顯示10個POI.
? ??
?????最后我測試了下縣份同樣可以顯示,但是城市名錯誤處理我沒做,如施秉縣.說明百度地圖的API還是非常強大的,希望后面接著學(xué)習(xí)吧!
? ?? ? ? ? 最后希望文章對大家有所幫助,剛剛接觸android開發(fā)百度地圖,而且還是使用V2.4.1版本,同時搜索城市時沒有顯示覆蓋物不知道其原因.如果有錯誤或不足之處,還請海涵!建議大家看看官方文檔和百度提供的Demo.文章主要參考百度官方文檔、柳峰大神博客和《Android第一行代碼》.
? ? ?下載地址:http://download.csdn.net/detail/eastmount/8292969
? ? ? (By:Eastmount 2014-12-24 半夜3點 http://blog.csdn.net/eastmount/ )
參考資料及在線筆記:
? ? ? 百度官方文檔 ? http://developer.baidu.com/map/sdkandev-4.htm
? ? ? 百度官方文檔? Android SDK開發(fā)指南之覆蓋物
? ? ? 百度地圖相關(guān)Demo下載? Demo v3.2.0?
? ? ? 柳峰博客? [010]百度地圖API之根據(jù)經(jīng)緯度查詢地址信息(Android
? ? ?柳峰博客?[013] 百度地圖API之城市POI搜索-獲取所有結(jié)果(Android)
總結(jié)
以上是生活随笔為你收集整理的[android] 百度地图开发 (二).定位城市位置和城市POI搜索的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [android] 百度地图开发 (一)
- 下一篇: [android] 解决DatePick