Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> [android] 百度地圖開發 (二).定位城市位置和城市POI搜索

[android] 百度地圖開發 (二).定位城市位置和城市POI搜索

編輯:關於Android編程

一. 百度地圖城市定位和POI搜索知識

上一篇文章百度地圖開發(一)中講述了如何申請百度APIKey及解決顯示空白網格的問題.該篇文章主要講述如何定位城市位置、定位自己的位置和進行城市興趣點POI(Point of Interest)搜索.那麼如何在百度地圖上定位某一個位置呢?
通過類GeoPoint可以定義經緯度,它存放著緯度值和經度值,通過getLastKnownLocation()方法可以獲取Location對象,再定位經緯度設置其為地圖中心即可顯示當前位置.
其中Geopoint(緯度值,經度值)以微度為單位,需要乘以10的6次方.核心代碼如下:

//通過網絡獲取當前位置
String provider = LocationManager.NeTWORK_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
Geopoint point = new Geopoint((int)(location.getLatitude*1E6), 
	(int)(location.getLongitude*1E6));
mMapController.setCenter(point);
同樣的道理,如果知道了城市的經緯度就可以設置其為當前地圖中心,這樣就實現了定位城市位置的功能.那麼怎樣獲取城市的經緯度呢?
百度Map API提供MKSearch.geocode(String address, String city)方法進行GEO地理編碼檢索,它的意思就是搜索某個城市具體地址的位置,而如果只搜索城市使用geocode(city, city)即可.同時逆地址解析函數MKSearch.reverseGeocode(new GeoPoint(latitude, longitude))可以實現通過輸入經緯度查詢具體地址.
其中核心代碼如下(代碼放置位置不同,詳見後面實例):

//初始化MKSearch
mMKSearch = new MKSearch();
mMKSearch.init(mBMapManager, new MySearchListener()); 
//搜索城市
mMKSearch.geocode(city, city);
//內部類實現MKSearchListener接口,實現異步搜索服務
public class MySearchListener implements MKSearchListener {  

	@Override  
    public void onGetAddrResult(MKAddrInfo result, int iError) { 
    	//經緯度與地址搜索
    	...
    	mMapController.setCenter(result.geoPt);
    }
}
其中百度地圖API搜索主要通過初始化MKSearch類,同時其結果監聽對象MKSearchListener類來實現一部搜索服務.在該類中有很多方法實現不同功能,其中onGetAddrResult()方法可以根據經緯度搜索地址信息,而我們需要實現的POI興趣點搜索是通過onGetPoiResult()實現的,同樣公交路線等搜索都可以通過它實現.
具體核心代碼如下:
//內部類實現MKSearchListener接口,實現異步搜索服務
public class MySearchListener implements MKSearchListener {  
    //經緯度與地址搜索結果
    public void onGetAddrResult(MKAddrInfo result, int iError) {
    }
    //POI搜索結果(范圍檢索、城市POI檢索、周邊檢索)
    public void onGetPoiResult(MKPoiResult result, int type, int iError) {  
    }
    //駕車路線搜索結果 
    public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
    }
    //公交換乘路線搜索結果
    public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) {  
	} 
    //步行路線搜索結果
    public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {  
    }
    //獲取詳細信息
    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使用百度地圖中可以添加地圖覆蓋物,那麼什麼是覆蓋物呢?
所有疊加或覆蓋到地圖的內容,我們統稱為地圖覆蓋物.如標注、矢量圖形元素(包括:折線和多邊形和圓)、定位圖標等.覆蓋物擁有自己的地理坐標,當您拖動或縮放地圖時,它們會相應的移動.
地圖API提供了如下幾種覆蓋物:
1.Overlay 覆蓋物的抽象基類,所有的覆蓋物均繼承此類的方法,實現用戶自定義圖層顯示.
2.MyLocationOverlay 一個負責顯示用戶當前位置的Overlay.
3.ItemizedOverlay 它是Overlay的一個基類,包含了一個OverlayItem列表,相當於一組分條的Overlay,通過繼承此類將一組興趣點顯示在地圖上.
4.PoiOverlay 本地搜索圖層,提供某一特定地區的位置搜索服務,比如在北京市搜索“公園”,通過此圖層將公園顯示在地圖上.
5.RouteOverlay 步行駕車導航線路圖層,將步行駕車出行方案的路線及關鍵點顯示在地圖上.
6.TransitOverlay 公交換乘線路圖層,將某一特定地區的公交出行方案的路線及換乘位置顯示在地圖上.
我們這裡可以使用MyLocationOverlay定位自己當前位置添加覆蓋物,也可以在POI搜索過程中通過PoiOverlay添加搜索的興趣點覆蓋物.下面講述代碼及實現.


二. 源碼實現

下載地址:
首先,設置其activity_main.xml布局


    
    
      
        
        

然後是MainActivity.java源碼

 

public class MainActivity extends Activity {
	
	//BMapManager 對象管理地圖、定位、搜索功能
	private BMapManager mBMapManager;  
	private MapView mapView = null;               //地圖主控件 
	private MapController mMapController = null;  //地圖控制 
	MKMapViewListener mMapListener = null;        //處理地圖事件回調 
	private MKSearch mMKSearch;                   //定義搜索服務類
	//搜索
	private EditText keyWordEditText;  
	private EditText cityEditText;
	private Button queryButton; 
	private static StringBuilder sb;  
	private MyLocationOverlay myLocationOverlay;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        /**
         * 創建對象BMapManager並初始化操作
         * V2.3.1中init(APIKey,null) V2.4.1在AndroidManifest中賦值AK
         * 注意 初始化操作在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);         //設置地圖是否響應點擊事
        mMapController.setZoom(16);               //地圖縮放級別(3-19級) 級別越高信息越詳細
        mapView.setBuiltInZoomControls(true);     //顯示內置縮放控件
          
        /**
         * 獲取學校經緯度 設置地圖中心點
         */
        GeoPoint point = new GeoPoint((int)(39.96703 * 1E6), (int)(116.323772 * 1E6));  
        mMapController.setCenter(point);  
        mapView.regMapViewListener(mBMapManager, new MKMapViewListener() {  
              
            /** 
             * 地圖移動完成時會回調此接口方法 
             */  
            @Override  
            public void onMapMoveFinish() {  
            	//Toast.makeText(MainActivity.this, 地圖移動, Toast.LENGTH_SHORT).show();
            }  
              
            /** 
             * 地圖加載完畢回調此接口方法 
             */  
            @Override  
            public void onMapLoadFinish() {  
            	Toast.makeText(MainActivity.this, 地圖載入, Toast.LENGTH_SHORT).show();
            }  
              
            /** 
             *  地圖完成帶動畫的操作(如: animationTo())後,此回調被觸發 
             */  
            @Override  
            public void onMapAnimationFinish() {  
                  
            }  
              
            /** 
             *  當調用過 mMapView.getCurrentMap()後,此回調會被觸發 
             *  可在此保存截圖至存儲設備 
             */  
            @Override  
            public void onGetCurrentMap(Bitmap arg0) {  
                 
            }  
              
            /** 
             * 點擊地圖上被標記的點回調此方法
             */  
            @Override  
            public void onClickMapPoi(MapPoi arg0) {  
                if (arg0 != null){  
                    Toast.makeText(MainActivity.this, arg0.strText, Toast.LENGTH_SHORT).show();
                }  
            }  
        });  
        
        /**
         * 初始化MKSearch 調用城市和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();  //內容清空  
                //輸入正確城市關鍵字
                String city = cityEditText.getText().toString().trim();  
                String keyWord = keyWordEditText.getText().toString().trim();  
                if(city.isEmpty()) { //默認城市設置為貴陽
                	city=貴陽;
                }
                //如果關鍵字為空只搜索城市 GEO搜索 geocode(adress,city) 具體地址和城市
                if(keyWord.isEmpty()) {
                	mMKSearch.geocode(city, city);     
                } 
                else {
                	//搜索城市+關鍵字 
                    mMKSearch.setPoiPageCapacity(10);  //每頁返回POI數
                    mMKSearch.poiSearchInCity(city, keyWord); 
                }
            }  
        });  
    }
    
    @Override
	protected void onResume() {
		mapView.onResume();
		if (mBMapManager != null) {
			mBMapManager.start();
		}
		super.onResume();
	}
    
    @Override
	protected void onDestroy() {
		mapView.destroy();
		if (mBMapManager != null) {
			mBMapManager.destroy();
			mBMapManager = null;
		}
		super.onDestroy();
	}

	@Override
	protected void onPause() {
		mapView.onPause();
		if (mBMapManager != null) {
			mBMapManager.stop();
		}
		super.onPause();
	}	
	
	/** 
     * 內部類實現MKSearchListener接口,用於實現異步搜索服務 
     */  
    public class MySearchListener implements MKSearchListener {  
        
    	/** 
         * 根據經緯度搜索地址信息結果 
         * 同時mMKSearch.geocode(city, city)搜索城市返回至該函數
         * 
         * @param result 搜索結果 
         * @param iError 錯誤號(0表示正確返回) 
         */  
        @Override  
        public void onGetAddrResult(MKAddrInfo result, int iError) {  
        	if (result == null) {  
                return;  
            }  
            StringBuffer sbcity = new StringBuffer();  
            sbcity.append(result.strAddr).append(
); //經緯度所對應的位置  
        	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(顯示當前城市地圖)  
            .setMessage(sbcity.toString())  
            .setPositiveButton(關閉, new DialogInterface.OnClickListener() {  
                public void onClick(DialogInterface dialog, int whichButton) {  
                    dialog.dismiss();  
                }  
            }).create().show();
        }  
  
        /** 
         * POI搜索結果(范圍檢索、城市POI檢索、周邊檢索) 
         *  
         * @param result 搜索結果 
         * @param type 返回結果類型(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());  //設置搜索到的POI數據  
            mapView.getOverlays().add(poioverlay);   //興趣點標注在地圖上
            mapView.refresh(); 
            //設置其中一個搜索結果所在地理坐標為地圖的中心  
            if(result.getNumPois() > 0) {  
                MKPoiInfo poiInfo = result.getPoi(0);  
                mMapController.setCenter(poiInfo.pt);  
            }  
            //添加StringBuffer 遍歷當前頁返回的POI (默認只返回10個)
            sb.append(共搜索到).append(result.getNumPois()).append(個POI
);  
            for (MKPoiInfo poiInfo : result.getAllPoi()) {  
                sb.append(名稱:).append(poiInfo.name).append(
);
            }
         	// 通過AlertDialog顯示當前頁搜索到的POI  
            new AlertDialog.Builder(MainActivity.this)  
            .setTitle(搜索到的POI信息)  
            .setMessage(sb.toString())  
            .setPositiveButton(關閉, new DialogInterface.OnClickListener() {  
                public void onClick(DialogInterface dialog, int whichButton) {  
                    dialog.dismiss();  
                }  
            }).create().show();
        }  
  
        /** 
         * 駕車路線搜索結果 
         *  
         * @param result 搜索結果 
         * @param iError 錯誤號(0表示正確返回) 
         */  
        @Override  
        public void onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {  
        }  
        
        /** 
         * 公交換乘路線搜索結果 
         *  
         * @param result 搜索結果 
         * @param iError 錯誤號(0表示正確返回) 
         */  
        @Override  
        public void onGetTransitRouteResult(MKTransitRouteResult result, int iError) {  
        }  
  
        /** 
         * 步行路線搜索結果 
         *  
         * @param result 搜索結果 
         * @param iError 錯誤號(0表示正確返回) 
         */  
        @Override  
        public void onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {  
        }

		@Override
		public void onGetBusDetailResult(MKBusLineResult arg0, int arg1) {
			// TODO Auto-generated method stub
		}

		@Override
		public void onGetPoiDetailSearchResult(int arg0, int arg1) {
			// TODO Auto-generated method stub
		}

		@Override
		public void onGetShareUrlResult(MKShareUrlResult arg0, int arg1, int arg2) {
			// TODO Auto-generated method stub
		}

		@Override
		public void onGetSuggestionResult(MKSuggestionResult arg0, int arg1) {
			// TODO Auto-generated method stub	
		}
    }  

}
最後設置AndroidManifest.xml文件,主要是申請網絡權限和設置APIKey



    

    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
        
         
        
            
                

                
            
        
    

程序運行結果如下圖所示:
當只輸入城市名的時候顯示的是城市對應的地圖.如下圖貴陽.
data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316124859.jpg data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316124817.jpg
當輸入城市+關鍵字時顯示POI興趣點,如北京的大學.這裡設置只顯示10個POI.
data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316124808.jpg data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316124833.jpg
最後我測試了下縣份同樣可以顯示,但是城市名錯誤處理我沒做,如施秉縣.說明百度地圖的API還是非常強大的,希望後面接著學習吧!
data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316124833.jpg data-cke-saved-src=https://www.android5.online/Android/UploadFiles_5356/201702/2017022316124837.jpg 最後希望文章對大家有所幫助,剛剛接觸android開發百度地圖,而且還是使用V2.4.1版本,同時搜索城市時沒有顯示覆蓋物不知道其原因.如果有錯誤或不足之處,還請海涵!建議大家看看官方文檔和百度提供的Demo.文章主要參考百度官方文檔、柳峰大神博客和《Android第一行代碼》.
 


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved