本文主要講解如何通過百度地圖API根據某個經緯度值(地理坐標)查詢對應的地址信息以及該地址周邊的POI(Point of Interest,興趣點)信息。 百度地圖移動版API不僅包含構建地圖的基本接口,還集成了眾多搜索服務,包括:位置檢索、周邊檢索、范圍檢索、公交檢索、駕乘檢索、步行檢索、地址信息查詢等。 百度地圖移動版API提供的搜索服務主要是通過初始化MKSearch類,注冊搜索結果的監聽對象MKSearchListener來實現異步搜索服務。首先需要自定義一個MySearchListener類,它實現MKSearchListener接口,然后通過實現接口中不同的回調方法,來獲得對應的搜索結果。MySearchListener類的定義如下:
- /**
- * 實現MKSearchListener接口,用於實現異步搜索服務,得到搜索結果
- *
- * @author liufeng
- */
- publicclass MySearchListener implements MKSearchListener {
- /**
- * 根據經緯度搜索地址信息結果
- * @param result 搜索結果
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetAddrResult(MKAddrInfo result, int iError) {
- }
- /**
- * 駕車路線搜索結果
- * @param result 搜索結果
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
- }
- /**
- * POI搜索結果(范圍檢索、城市POI檢索、周邊檢索)
- * @param result 搜索結果
- * @param type 返回結果類型(11,12,21:poi列表 7:城市列表)
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetPoiResult(MKPoiResult result, int type, int iError) {
- }
- /**
- * 公交換乘路線搜索結果
- * @param result 搜索結果
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetTransitRouteResult(MKTransitRouteResult result, int iError) {
- }
- /**
- * 步行路線搜索結果
- * @param result 搜索結果
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {
- }
- }
說明:上面的類定義只是在說明MKSearchListener類的5個方法的作用,全都是空實現,並未給出具體的實現。根據你要檢索的內容,再去具體實現上面對應的方法,就能獲取到搜索結果。例如:1)你想通過一個地理坐標(經緯度值)來搜索地址信息,那么只需要具體實現上面的onGetAddrResult()方法就能得到搜索結果;2)如果你想搜索駕車路線信息,只需要具體實現onGetDrivingRouteResult()方法就能得到搜索結果。
緊接着,需要初始化MKSearch類:
- // 初始化MKSearch
- mMKSearch = new MKSearch();
- mMKSearch.init(mapManager, new MySearchListener());
經過上面兩步之后,就可以通過調用MKSearch所提供的一些檢索方法來搜索你想要的信息了。 下面給出一個具體的示例:根據某個經緯度值(地理坐標)查詢對應的地址信息以及該地址周邊的POI(Point of Interest,興趣點)信息。 1)布局文件res/layout/query_address.xml
- <?xmlversion="1.0"encoding="utf-8"?>
- <ScrollViewxmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="經度:"
- />
- <EditTextandroid:id="@+id/longitude_input"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="106.720397"
- />
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="緯度:"
- />
- <EditTextandroid:id="@+id/latitude_input"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="26.597239"
- />
- <Buttonandroid:id="@+id/query_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="right"
- android:text="地址查詢"
- />
- <TextViewandroid:id="@+id/address_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- <!--
- 雖然定義了MapView,但是設置了android:visibility="gone"將其隱藏
- 因為本示例並不需要顯示地圖,但不定義又不行(baidu map api的要求)
- -->
- <com.baidu.mapapi.MapViewandroid:id="@+id/map_View"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:clickable="true"
- android:visibility="gone"
- />
- </LinearLayout>
- </ScrollView>
2)繼承com.baidu.mapapi.MapActivity的Activity類
- package com.liufeng.baidumap;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- import com.baidu.mapapi.BMapManager;
- import com.baidu.mapapi.GeoPoint;
- import com.baidu.mapapi.MKAddrInfo;
- import com.baidu.mapapi.MKDrivingRouteResult;
- import com.baidu.mapapi.MKPoiInfo;
- import com.baidu.mapapi.MKPoiResult;
- import com.baidu.mapapi.MKSearch;
- import com.baidu.mapapi.MKSearchListener;
- import com.baidu.mapapi.MKTransitRouteResult;
- import com.baidu.mapapi.MKWalkingRouteResult;
- import com.baidu.mapapi.MapActivity;
- /**
- * 根據經緯度查詢地址信息
- *
- * @author liufeng
- * @date 2011-05-03
- */
- publicclass QueryAddressActivity extends MapActivity {
- // 定義地圖引擎管理類
- private BMapManager mapManager;
- // 定義搜索服務類
- private MKSearch mMKSearch;
- private EditText longitudeEditText;
- private EditText latitudeEditText;
- private TextView addressTextView;
- private Button queryButton;
- @Override
- publicvoid onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.query_address);
- // 初始化MapActivity
- mapManager = new BMapManager(getApplication());
- // init方法的第一個參數需填入申請的API Key
- mapManager.init("285B415EBAB2A92293E85502150ADA7F03C777C4", null);
- super.initMapActivity(mapManager);
- // 初始化MKSearch
- mMKSearch = new MKSearch();
- mMKSearch.init(mapManager, new MySearchListener());
- // 通過id查詢在布局文件中定義的控件
- longitudeEditText = (EditText) findViewById(R.id.longitude_input);
- latitudeEditText = (EditText) findViewById(R.id.latitude_input);
- addressTextView = (TextView) findViewById(R.id.address_text);
- queryButton = (Button) findViewById(R.id.query_button);
- // 給地址查詢按鈕設置單擊事件監聽器
- queryButton.setOnClickListener(new OnClickListener() {
- @Override
- publicvoid onClick(View v) {
- // 用戶輸入的經度值
- String longitudeStr = longitudeEditText.getText().toString();
- // 用戶輸入的緯度值
- String latitudeStr = latitudeEditText.getText().toString();
- try {
- // 將用戶輸入的經緯度值轉換成int類型
- int longitude = (int) (1000000 * Double.parseDouble(longitudeStr));
- int latitude = (int) (1000000 * Double.parseDouble(latitudeStr));
- // 查詢該經緯度值所對應的地址位置信息
- mMKSearch.reverseGeocode(new GeoPoint(latitude, longitude));
- } catch (Exception e) {
- addressTextView.setText("查詢出錯,請檢查您輸入的經緯度值!");
- }
- }
- });
- }
- @Override
- protectedboolean isRouteDisplayed() {
- returnfalse;
- }
- @Override
- protectedvoid onDestroy() {
- if (mapManager != null) {
- // 程序退出前需調用此方法
- mapManager.destroy();
- mapManager = null;
- }
- super.onDestroy();
- }
- @Override
- protectedvoid onPause() {
- if (mapManager != null) {
- // 終止百度地圖API
- mapManager.stop();
- }
- super.onPause();
- }
- @Override
- protectedvoid onResume() {
- if (mapManager != null) {
- // 開啟百度地圖API
- mapManager.start();
- }
- super.onResume();
- }
- /**
- * 內部類實現MKSearchListener接口,用於實現異步搜索服務
- *
- * @author liufeng
- */
- publicclass MySearchListener implements MKSearchListener {
- /**
- * 根據經緯度搜索地址信息結果
- *
- * @param result 搜索結果
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetAddrResult(MKAddrInfo result, int iError) {
- if (result == null) {
- return;
- }
- StringBuffer sb = new StringBuffer();
- // 經緯度所對應的位置
- sb.append(result.strAddr).append("/n");
- // 判斷該地址附近是否有POI(Point of Interest,即興趣點)
- if (null != result.poiList) {
- // 遍歷所有的興趣點信息
- for (MKPoiInfo poiInfo : result.poiList) {
- sb.append("----------------------------------------").append("/n");
- sb.append("名稱:").append(poiInfo.name).append("/n");
- sb.append("地址:").append(poiInfo.address).append("/n");
- sb.append("經度:").append(poiInfo.pt.getLongitudeE6() / 1000000.0f).append("/n");
- sb.append("緯度:").append(poiInfo.pt.getLatitudeE6() / 1000000.0f).append("/n");
- sb.append("電話:").append(poiInfo.phoneNum).append("/n");
- sb.append("郵編:").append(poiInfo.postCode).append("/n");
- // poi類型,0:普通點,1:公交站,2:公交線路,3:地鐵站,4:地鐵線路
- sb.append("類型:").append(poiInfo.ePoiType).append("/n");
- }
- }
- // 將地址信息、興趣點信息顯示在TextView上
- addressTextView.setText(sb.toString());
- }
- /**
- * 駕車路線搜索結果
- *
- * @param result 搜索結果
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetDrivingRouteResult(MKDrivingRouteResult result, int iError) {
- }
- /**
- * POI搜索結果(范圍檢索、城市POI檢索、周邊檢索)
- *
- * @param result 搜索結果
- * @param type 返回結果類型(11,12,21:poi列表 7:城市列表)
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetPoiResult(MKPoiResult result, int type, int iError) {
- }
- /**
- * 公交換乘路線搜索結果
- *
- * @param result 搜索結果
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetTransitRouteResult(MKTransitRouteResult result, int iError) {
- }
- /**
- * 步行路線搜索結果
- *
- * @param result 搜索結果
- * @param iError 錯誤號(0表示正確返回)
- */
- @Override
- publicvoid onGetWalkingRouteResult(MKWalkingRouteResult result, int iError) {
- }
- }
- }
3)AndroidManifest.xml中的配置
- <?xmlversion="1.0"encoding="utf-8"?>
- <manifestxmlns:android="http://schemas.android.com/apk/res/android"
- package="com.liufeng.baidumap"
- android:versionCode="1"
- android:versionName="1.0">
- <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
- <activityandroid:name=".QueryAddressActivity"android:label="@string/app_name">
- <intent-filter>
- <actionandroid:name="android.intent.action.MAIN"/>
- <categoryandroid:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
- </activity>
- </application>
- <uses-sdkandroid:minSdkVersion="4"/>
- <!-- 訪問網絡的權限 -->
- <uses-permissionandroid:name="android.permission.INTERNET"/>
- <!-- 訪問精確位置的權限 -->
- <uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"/>
- <!-- 訪問網絡狀態的權限 -->
- <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
- <!-- 訪問WIFI網絡狀態的權限 -->
- <uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>
- <!-- 改變WIFI網絡狀態的權限 -->
- <uses-permissionandroid:name="android.permission.CHANGE_WIFI_STATE"/>
- <!-- 讀寫存儲卡的權限 -->
- <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
- <!-- 讀取電話狀態的權限 -->
- <uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>
- </manifest>
4)運行結果截圖及說明
程序在模擬器上運行的初始效果如上圖所示。可以看出,地圖並沒有顯示出來,這和我們在設計時布局時所設想的一樣;另外兩個輸入框中也分別顯示了默認給出的經緯度值。 點擊“地址查詢”按鈕后,將看到如下圖所示包含了查詢結果的界面:
說明:圖上的“貴州省貴陽市雲岩區普陀路”正是我們要查詢的地理坐標(經度:106.720397,緯度:26.597239)所對應的地址信息;同時該地址信息下方還顯示出了該地址附近的10個興趣點(POI),每個興趣點分別包含了“名稱”、“地址”、“經緯度”、“電話”、“郵編”和“興趣點類型”信息。
備注:如果本文的示例繼續做下去,就應該將MapView顯示出來,同時結合第8篇文章“[008] 百度地圖API之ItemizedOverlay的使用(Android)”所介紹的內容將地址信息和興趣點標注在地圖上。我想這兩方面的內容都已做過詳細講解並給出了示例,再來實現這個應該並不是什么難事,看文章的你就動動手來完成它吧!
