天天看點

Android百度地圖——搜尋服務之周邊檢索

周邊檢索:根據檢索詞、中心點地理坐标和半徑與發起周邊檢索。

實作場景:查找以上海市浦東新區為中心,半徑為1000米内所有的“浦東發展銀行”(搜周邊)。

實作步驟:

一、前提條件:

        搭建百度地圖開發環境;

        地圖引擎管理對象和顯示地圖的View對象,都已建立并初始化;

        MapView對象的相關屬性已設定,生命周期函數也已處理。

        詳見:Android 百度地圖SDK (v2.0.0)初探

二、檢索以上海市浦東新區為中心,半徑為1000米内所有的“浦東發展銀行”(搜周邊)的具體實作步驟:

        1、建立搜尋服務類對象,并初始化。代碼如下:

mMKSearch = new MKSearch();
        mMKSearch.init(mBMapManager, new MKSearchListener() {

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

            }

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

            }

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

            }

            @Override
            public void onGetPoiResult(MKPoiResult result, int type, int error) {
              
            }

            @Override
            public void onGetPoiDetailSearchResult(int type, int error) {
             
            }

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

            }

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

            }

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

            }

        });
           

           2、 調用mMKSearch對象的mMKSearch.poiSearchNearBy(arg0, arg1, arg2)方法,參數清單:關鍵詞、中心點地理坐标、半徑,機關:米。

// 根據中心點、半徑與檢索詞發起周邊檢索.
       // 參數清單:關鍵詞、中心點地理坐标、半徑,機關:米
        mMKSearch.poiSearchNearBy("浦東發展銀行", mGeoPoint, 1000);
           

           3、在onGetPoiResult()回調方法内處理檢索到的結果。

@Override
            public void onGetPoiResult(MKPoiResult result, int type, int error) {
                if (error != 0) {
                    Toast.makeText(BaiduMapPoiOverlayActivity.this, 
                            "抱歉,未查找到結果", 
                            Toast.LENGTH_SHORT).show();
                } else {
                    if (result == null) {
                        Toast.makeText(BaiduMapPoiOverlayActivity.this,
                                "抱歉,您填寫的搜尋條件,未查找到結果,換個條件試試!",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }

                    // 建立POI内置的Overlay對象 
                    PoiOverlay poiOverlay = new PoiOverlay(BaiduMapPoiOverlayActivity.this, mMapView);
                    // 符合搜尋條件的所有點
                    poiOverlay.setData(result.getAllPoi());
                    // 向覆寫物清單中添加覆寫物對象PoiOverlay
                    mMapView.getOverlays().add(poiOverlay);
                    // 重新整理地圖
                    mMapView.refresh();
                }
            }
           

           4、運作效果圖如下:

Android百度地圖——搜尋服務之周邊檢索

三、檢視檢索到的POI詳情:

1、在前面我們以上海市浦東新區為中心,半徑為1000米内所有的“浦東發展銀行”,檢索得到的是一個POI的清單。代碼如下:

ArrayList<MKPoiInfo> mkPois = result.getAllPoi();
           

注:a. result是MKPoiResult類對象的一個引用。

        b. POI是中國POI(Point of Interest)資料庫的縮寫,可以翻譯成“興趣點”, 每個POI包含四方面資訊,名稱、類别、經度、緯度。這個計劃的遠景目标是建立全國的POI資料庫,并且全部開放。

2、從POI的清單中取出一個元素:

MKPoiInfo mkPoi = mkPois.get(1);
           

3、發起檢視詳細資訊的請求:

mMKSearch.poiDetailSearch(mkPoi.uid);
           

4、需要在AndroidManifest.xml中設定如下資訊:

注:調用百度API裡的POI詳細資訊展示Activity,官方給的有錯誤。

<activity
            android:configChanges="orientation|keyboardHidden"
            android:name="com.baidu.mapapi.search.PlaceCaterActivity"
            android:theme="@android:style/Theme.NoTitleBar" >
        </activity>
           

5、處理onGetPoiDetailSearchResult()回調方法:

@Override
            public void onGetPoiDetailSearchResult(int type, int error) {
                // type - 值為GeoSearchManager.GEO_SEARCH_DETAILS
                if (error != 0) {
                    Toast.makeText(BaiduMapPoiOverlayActivity.this, "抱歉,未找到結果", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(BaiduMapPoiOverlayActivity.this, "成功,檢視詳情頁面", Toast.LENGTH_SHORT).show();
                }
            }
           

6、運作效果圖如下:

Android百度地圖——搜尋服務之周邊檢索

三、完整代碼:

1、在AndroidManifest.xml中的配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.baidu.map"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/app_name"
            android:name=".BaiduMapPoiOverlayActivity"
            android:screenOrientation="sensor" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity
            android:configChanges="orientation|keyboardHidden"
            android:name="com.baidu.mapapi.search.PlaceCaterActivity"
            android:theme="@android:style/Theme.NoTitleBar" >
        </activity>
    </application>

    <!-- 使用網絡功能所需權限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
    </uses-permission>
    <uses-permission android:name="android.permission.INTERNET" >
    </uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
    </uses-permission>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
    </uses-permission>

    <!-- 讀取手機的目前狀态權限,沒有的話會報錯,這個是使用百度地圖API必須的 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" >
    </uses-permission>

    <!-- Cache功能需要讀寫外部存儲器 ,若沒這個權限,地圖加載不出來 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
    </uses-permission>
    
    <supports-screens
        android:anyDensity="true"
        android:largeScreens="true"
        android:normalScreens="true"
        android:resizeable="true"
        android:smallScreens="true" />

</manifest>
           

2、繼承自Activity類的子類的完整代碼:

package com.android.baidu.map;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.MKGeneralListener;
import com.baidu.mapapi.map.MKEvent;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.PoiOverlay;
import com.baidu.mapapi.search.MKAddrInfo;
import com.baidu.mapapi.search.MKBusLineResult;
import com.baidu.mapapi.search.MKDrivingRouteResult;
import com.baidu.mapapi.search.MKPoiInfo;
import com.baidu.mapapi.search.MKPoiResult;
import com.baidu.mapapi.search.MKSearch;
import com.baidu.mapapi.search.MKSearchListener;
import com.baidu.mapapi.search.MKSuggestionResult;
import com.baidu.mapapi.search.MKTransitRouteResult;
import com.baidu.mapapi.search.MKWalkingRouteResult;
import com.baidu.platform.comapi.basestruct.GeoPoint;

/**
 * 根據檢索詞、中心點地理坐标和半徑與發起周邊檢索.
 * @author android_ls
 *
 */
public class BaiduMapPoiOverlayActivity extends Activity {

    /**地圖引擎管理類*/
    private BMapManager mBMapManager = null;

    /**顯示地圖的View*/
    private MapView mMapView = null;

    /**搜尋服務,用于位置檢索、周邊檢索、範圍檢索、公交檢索、駕乘檢索、步行檢索*/
    private MKSearch mMKSearch = null;

    /**
     * 經研究發現在申請KEY時:應用名稱一定要寫成my_app_應用名(也就是說"my_app_"是必須要有的)。
     * 百度地圖SDK提供的服務是免費的,接口無使用次數限制。您需先申請密鑰(key),才可使用該套SDK。
     * */
    public static final String BAIDU_MAP_KEY = "07418AEC69BAAB7104C6230A6120C580DFFAEEBB";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // 注意:請在調用setContentView前初始化BMapManager對象,否則會報錯
        mBMapManager = new BMapManager(this.getApplicationContext());
        mBMapManager.init(BAIDU_MAP_KEY, new MKGeneralListener() {

            @Override
            public void onGetNetworkState(int iError) {
                if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
                    Toast.makeText(BaiduMapPoiOverlayActivity.this.getApplicationContext(),
                            "您的網絡出錯啦!", 
                            Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onGetPermissionState(int iError) {
                if (iError == MKEvent.ERROR_PERMISSION_DENIED) {
                    // 授權Key錯誤:
                    Toast.makeText(BaiduMapPoiOverlayActivity.this.getApplicationContext(),
                            "請在 DemoApplication.java檔案輸入正确的授權Key!", 
                            Toast.LENGTH_LONG).show();
                }
            }
        });

        setContentView(R.layout.main);

        mMapView = (MapView) this.findViewById(R.id.bmapsView);
        // 設定啟用内置的縮放控件
        mMapView.setBuiltInZoomControls(true);

        MapController mapController = mMapView.getController();
        // 上海市浦東新區的GPS緯度經度值:31.224078,121.540419
        GeoPoint mGeoPoint = new GeoPoint(
                (int) (31.224078 * 1E6), 
                (int) (121.540419 * 1E6));

        // 設定地圖的中心點
        mapController.setCenter(mGeoPoint);
        mapController.setZoom(15);

        mMKSearch = new MKSearch();
        mMKSearch.init(mBMapManager, new MKSearchListener() {

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

            }

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

            }

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

            }

            @Override
            public void onGetPoiResult(MKPoiResult result, int type, int error) {
                if (error != 0) {
                    Toast.makeText(BaiduMapPoiOverlayActivity.this, 
                            "抱歉,未查找到結果", 
                            Toast.LENGTH_SHORT).show();
                } else {
                    if (result == null) {
                        Toast.makeText(BaiduMapPoiOverlayActivity.this,
                                "抱歉,您填寫的搜尋條件,未查找到結果,換個條件試試!",
                                Toast.LENGTH_SHORT).show();
                        return;
                    }

                    // 建立POI内置的Overlay對象 
                    PoiOverlay poiOverlay = new PoiOverlay(BaiduMapPoiOverlayActivity.this, mMapView);
                    // 符合搜尋條件的所有點
                    poiOverlay.setData(result.getAllPoi());
                    // 向覆寫物清單中添加覆寫物對象PoiOverlay
                    mMapView.getOverlays().add(poiOverlay);
                    // 重新整理地圖
                    mMapView.refresh();
                    
                   /* 注: POI是中國POI(Point of Interest)資料庫的縮寫,可以翻譯成“興趣點”,
                    * 每個POI包含四方面資訊,名稱、類别、經度、緯度。
                    * 這個計劃的遠景目标是建立全國的POI資料庫,并且全部開放。*/
                    
                    // 當執行完POI檢索後,我們會得到一個POI的清單。
                    ArrayList<MKPoiInfo> mkPois = result.getAllPoi();
                    // 取POI清單中的第二個元素
                    MKPoiInfo mkPoi = mkPois.get(1);
                    /* 每個POI節點都有個uid屬性,我們可以根據這個uid擷取關于這個poi的一些更詳細的資訊。
                     * 比如:評論、圖檔、商戶描述等。*/
                    
                    // 發起檢視詳細資訊的請求
                    mMKSearch.poiDetailSearch(mkPoi.uid);
                }
            }

            @Override
            public void onGetPoiDetailSearchResult(int type, int error) {
                // type - 值為GeoSearchManager.GEO_SEARCH_DETAILS
                if (error != 0) {
                    Toast.makeText(BaiduMapPoiOverlayActivity.this, "抱歉,未找到結果", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(BaiduMapPoiOverlayActivity.this, "成功,檢視詳情頁面", Toast.LENGTH_SHORT).show();
                }
            }

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

            }

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

            }

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

            }

        });
        
        // 根據中心點、半徑與檢索詞發起周邊檢索.
        // 參數清單:關鍵詞、中心點地理坐标、半徑,機關:米
        mMKSearch.poiSearchNearBy("浦東發展銀行", mGeoPoint, 1000);

    }

    // 重寫以下方法,管理API
    @Override
    protected void onResume() {
        mMapView.onResume();
        if (mBMapManager != null) {
            mBMapManager.start();
        }
        super.onResume();
    }

    @Override
    protected void onPause() {
        mMapView.onPause();
        if (mBMapManager != null) {
            mBMapManager.stop();
        }
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        mMapView.destroy();
        if (mBMapManager != null) {
            mBMapManager.destroy();
            mBMapManager = null;
        }
        super.onDestroy();
    }
}