百度地圖 SDK(4)---- 檢索功能

不知不覺研究百度地圖也已經3,4天了,雖然我們一直停留在MainActivty上,但是也已經取得很不錯的成果了(有些圖標,UI細節沒有在簡書文章上指出)


演示圖片

可以看到我們的演示效果,雖然畫質渣渣(壓縮gif的緣故)但是也是有點樣子的對吧。
這也算我們實現的第一個階段吧,下一個階段會實現其他的功能,但是可能更新頻率不會很快,我要修養一段時間(開玩笑啦,其實是轉Php去了,不能落下任何一個不是嘛。)不過這個我是不會放棄的,我會堅持把他做到我期待的樣子,并把我開發的全過程用簡書記錄下來。

1.開始今天的旅行

目前百度地圖SDK所集成的檢索服務包括:POI檢索、公交信息查詢、線路規劃、地理編碼、行政區邊界數據檢索、在線建議查詢、短串分享(包括POI搜索結果分享、駕車/公交/騎行/步行路線規劃分享、反向地理編碼結果分享)

POI(Point of Interest)

中文可以翻譯為“興趣點”。在地理信息系統中,一個POI可以是一棟房子、一個商鋪、一個郵筒、一個公交站等。
首先我們看一下我們百度提供的說明,
http://lbsyun.baidu.com/index.php?title=androidsdk/guide/retrieval

BAIDU.PNG

這里的檢索主要分為五個步驟,主要有3個類型
下面是百度demo里的一段代碼,主要是顯示在線搜索結果,那么這都是什么意思呢,這里我詳細說一下。

SUGGESTION.PNG

大家可以拿著百度地圖對照,首先我們點擊首頁的搜索框進入一個單獨的頁面,輸入搜索詞,比如說北京大學,這時候下面立馬顯示一排搜索結果,并顯示一些信息,那么本應該就是我們的SuggestionSearch,中文可以譯作搜索建議,這個建議包含了很多數據,包括名稱,地理位置等
但是百度這里用的是onGetPoiResult,(可以看到他每一條都帶有詳細的介紹)我們也打算用這個,
那么我們點擊搜索按鈕的話


圖片發自簡書App

可以看到,這里有一個列表,一個地圖,地圖上還有標注。
這里就是我們的onGetPoiResult獲取的結果。
最后還有一個onGetPoiDetailResult,從名字看當然是詳情啦。
梳理結束之后,我們要思考設計一個頁面。

……一個非專業的UI正在苦癟界面……請稍后……

兩天之后……
我終于回來了,那么我回來帶來了什么呢?


演示效果

個人認為這個界面還是看的過去的,因為畢竟不是專業的UI,所以有些細節還得推敲一下。

當然如果今天我在這里將UI設計的代碼那可能就跑偏了,我最多只會說說這個UI界面是怎么實現的。

首先我們回到首頁

2.UI分析

點擊首頁的toolbar進入搜索頁面,這里的搜索頁面可以看到分為三部分,上方的toolbar,中間的tablayout,下面的viewpager,viewpager中在推薦這個頁面是一個fragment,包含一個列表和一個下拉刷新,后期會添加一些歷史紀錄啥的。

那么我們輸入關鍵字 “天安門廣場” 是怎么出來這個列表的呢?
下面直接上代碼

    //這是poi搜索的準備,進行一個初始化,在onCreate()里開始調用
        // 初始化搜索模塊,注冊搜索事件監聽
        mPoiSearch = PoiSearch.newInstance();
        mPoiSearch.setOnGetPoiSearchResultListener(this);

然后他會要求activity實現他的接口里的方法,一共3個

  /**
     * 獲取POI搜索結果,包括searchInCity,searchNearby,searchInBound返回的搜索結果
     * @param result
     */
    public void onGetPoiResult(PoiResult result) {

    }

    /**
     * 獲取POI詳情搜索結果,得到searchPoiDetail返回的搜索結果
     * @param result
     */
    public void onGetPoiDetailResult(PoiDetailResult result) {
    
    }
      //暫時先不管這個
    @Override
    public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

    }

最后別忘記銷毀釋放資源

   @Override
    protected void onDestroy() {
//銷毀,釋放資源
        mPoiSearch.destroy();
        super.onDestroy();
    }

這樣我們的一個搜索框架就搭建好了,有建立,監聽和銷毀
下面我們來填充一下。
下面是我們的搜索框的TextWatcher

mpoi_se.addTextChangedListener(new TextWatcher() {
             @Override
             public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

             }

             @Override
             public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                 //先清空列表,這個列表是儲存著onGetPoiResult結果
                //的列表,也就是說我們一旦改變了輸入框內容,那么
                //以前的數據也就沒用了,必須清空
                 poi_list.clear();
               
                //這里的判斷也就是說如果獲取到的內容不為空就開始
                //搜索,為空就直接調用更新UI的方法更新一個空列表。
                 if(!mpoi_se.getText().toString().equals("")){
                     //s_page角色是搜索頁碼,因為搜索結果很多,
                    //肯定是分頁加載,默認是加載第0頁
                      s_page = 0;

                       //這里主要控制著,搜附近還是搜城市
                       //假如說我們從主頁面進入搜索頁,那就是搜城市
                       //從搜城市搜出來的結果item項進入它的附近就是搜
                       //附近,那其實這兩個方法都大同小異,一會在下面貼
                     if(getIntent().getStringExtra("KEY")!=null){
                         search_nearby(0);
                         Log.d("SESO", "GetMessage key: 附近");
                     }else{
                         search(0);
                         Log.d("SESO", "GetMessage key: 城市");
                     }
                     //這里我寫了一個通知開始刷新的方法,主要是
                    //UI上的,如果要寫這個poi搜素,UI可以自己寫
                    //我就不貼UI相關的代碼了
                     sendRefreshNotify("START");
                 }else{
                     //如果查詢空串自動復位,這就是更新UI的方法
                    //同樣不貼了
                     LoadSuggestFragment();
                 }

             }

             @Override
             public void afterTextChanged(Editable editable) {

             }
         });

可以看到我們的邏輯還是相當簡單的

1.清空上次搜索的舊數據
2.搜索頁面s_page置為0
3.根據從某個頁面來的intent攜帶的值來判斷是搜城市還是搜附近

那么搜城市的代碼是這樣的

 private void search(int i) {
        try {
//1.city方法當然填入你現在所在的城市,從主頁面可以獲取到,通
//過Intent傳過來就好
//2.keyword是你的搜索關鍵字也就是輸入框里打的內容
//3.isReturnAddr返回地址為真
//4.pagenum是請求第幾頁啦
            mPoiSearch.searchInCity((new PoiCitySearchOption())
                    .city(getIntent().getStringExtra("CITY")).keyword(mpoi_se.getText().toString())
                    .isReturnAddr(true)
                    .pageNum(i));
        } catch (Exception e) {
            e.printStackTrace();
        }

        Log.d("SE", "onClick: 開始搜索");
    }

搜附近也類似

 private void search_nearby(int i) {
        Double lati_ = getIntent().getDoubleExtra("LOCATION_latitude",39.92235);
        Double long_ = getIntent().getDoubleExtra("LOCATION_longitude",116.380338);
       //搜索附近
       //keyword不啰嗦
       //sortType是一個排序規則,從我們傳遞的參數來看,這個一
      //個由近到遠的排序規則
      //location是一個坐標點,也就是從誰附近搜這個location就是誰
      //radius是一個搜索半徑,單位是m
      //pagenum不啰嗦
        LatLng latLng = new LatLng(lati_,long_);
                    PoiNearbySearchOption nearbySearchOption = new PoiNearbySearchOption().keyword(mpoi_se.getText()
                    .toString()).sortType(PoiSortType.distance_from_near_to_far).location(latLng)
                    .radius(10000).pageNum(i);
            mPoiSearch.searchNearby(nearbySearchOption);
    }

這是兩種搜索方法,搜區域我就不說了,如果有人需要的話可以參考百度demo

那么我們的搜索結果在三個重寫的方法里接受,這里主要是第一個方法,其余的都沒有用到

 public void onGetPoiResult(PoiResult result) {

        //得到結果后,通知停止刷新
        sendRefreshNotify("STOP");

        //搜索結果,為空或者空錯誤
        if (result == null || result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
            Toast.makeText(SeActivity.this, "未找到結果", Toast.LENGTH_LONG)
                    .show();
            return;
        }

        if (result.error == SearchResult.ERRORNO.NO_ERROR) {
              //用一個foreach語句將結果傳遞給我們的列表
                for (PoiInfo poiInfo : result.getAllPoi()) {
                    poi_list.add(0,poiInfo);
                }
       
            //有了數據,當然是通知ui,加載列表
           LoadSuggestFragment();
        }
    }

那么其實我們的PoiInfo已經包含了這個地方的名字,地址,電話,位置坐標等等,如果你想計算他到某個點的位置還可以通過下面的語法來計算

 dis = DistanceUtil.getDistance(latLng, poiInfo.location);

其實一個簡單的poi搜索就這么點東西,初始化,搜索,接收數據,銷毀。

那可能有朋友就會問了,我們重寫的三個方法,只用了一個方法,另外兩個呢?
其實第二個onGetPoiDetailResult是獲取詳情結果,第三個是onGetPoiIndoorResult是獲取室內的結果(我們這里沒考慮室內的情況),我們來看看第二種情況。

首先還是我們的初始化,銷毀,重寫的方法還是那些,只不過我們的搜索變成了這個樣子,這里的poiUid接受一個uid參數,這個參數是onGetPoiResult獲取的結果里的PoiInfo的一個屬性,也就是說我們只要得到onGetPoiResult結果才能使用onGetPoiDetailResult

 //查看詳情
                mPoiSearch.searchPoiDetail((new PoiDetailSearchOption())
                        .poiUid(getIntent().getStringExtra("UID")));

那么我們來看一下搜索結果
這里我們直接將搜索結果的detailUrl屬性傳出去了,其實這里還有很多屬性,包括店鋪評價啥的,這里我們就不一一展示了。

  @Override
    public void onGetPoiDetailResult(PoiDetailResult result) {
        if (result.error != SearchResult.ERRORNO.NO_ERROR) {
            Toast.makeText(PoiInfoActivity.this, "抱歉,未找到詳情結果", Toast.LENGTH_SHORT)
                    .show();
        } else {
            startActivity(new Intent(PoiInfoActivity.this,PoiDetailActivity.class).putExtra("URL",result.detailUrl));
        }
    }

那么poi檢索到這里也就算結束了

總結

百度地圖檢索功能包含的內容還是很多的,這里我只拿poi舉個栗子,當然還有更多的我也不會丟下的,可能在以后的學習過程中會補充上去。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 各位小伙伴們大家好,今天我向大家介紹一下蘋果百度地圖的使用方法,因為做過一些想關的APP,感覺百度地圖還是挺方便的...
    Lee0528閱讀 14,777評論 18 46
  • 檢索功能 1. 簡介 百度地圖SDK提供的檢索服務包括以下功能模塊:POI檢索,公交方案檢索,駕車路線檢索,步行路...
    DestinyFighter_閱讀 4,006評論 1 7
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,466評論 25 708
  • 寫在前面本來想使用百度定位的SDK把定位功能實現了,可無奈遇上個坑到寫這篇blog為止都還沒有解決。故所以把使用百...
    Vane_Subin閱讀 8,864評論 8 14
  • 由于某些歷史和技術原因,創建泛類型數組在Java中是不允許的。我們需要使用類型轉換: 《算法第四版》 P83
    風亡小窩閱讀 142評論 0 0