Android studio 百度地圖開發(8)地圖已標記POI點和搜尋POI點的獲取和利用
一.簡要描述
百度地圖的POI點可以分有兩種:地圖中已經標記的點和通過關鍵詞搜尋得到的POI點。對於這兩種POI點,百度封裝成了不同的類和介面來實現監聽,下面簡單講一點。
二.地圖中已標記POI點
首先遇到的第一個問題就時如何獲取已標記點的資訊,在百度地圖點選已標記的點會有資訊的,那麼在自己的地圖上如何產生點選事件呢?
(1)介面
百度提供了一個POI點選事件的介面 BaiduMap.OnMapClickListener,該介面提供了兩個方法,如下表。
(測試下CSDN的MarkDown編輯器畫表格的功能,不會把首行的標題居中呀)
返回型別 | 方法 | 說明 |
---|---|---|
boolean | onMapClick(LatLng point) | 地圖單擊事件回撥函式 |
boolean | onMapPoiClick(MapPoi poi) | 地圖內 Poi 單擊事件回撥函式 |
(2)MapPoi 類
返回型別 | 方法 | 說明 |
---|---|---|
java.lang.String | getName() | 獲取該興趣點的名稱 |
LatLng | getPosition() | 獲取該興趣點的地理座標 |
(3)獲取POI
我們只需要重寫onMapPoiClick()就可以了。
程式碼如下:
baiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
}
@Override
public boolean onMapPoiClick(MapPoi mapPoi)
{
String POIName = mapPoi.getName();//POI點名稱
LatLng POIPosition = mapPoi.getPosition();//POI點座標
//下面就是自己隨便應用了
//根據POI點座標反向地理編碼
//reverseSearch(POIPosition);
//新增圖層顯示POI點
/*baiduMap.clear();
baiduMap.addOverlay(
new MarkerOptions()
.position(POIPosition) //座標位置
.icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_marka))
.title(POIName) //標題
);
//將該POI點設定為地圖中心
baiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(POIPosition));*/
return true;
}
});
其次,為了獲得該POI點的其他詳細資訊,因為MapPoi沒有uid,我嘗試通過對position進行反向地理編碼,結果還是不太滿意,百度地圖上直接點選已標記的POI點,是可以獲得該點的很多資訊的(可見下面的第三部分中PoiInfo),關於這一點,暫時還沒找到更好的方式解決。
三.搜尋關鍵詞獲取POI點
1.描述
該功能就是百度地圖首頁的頂端,輸入想要去的地方或者食物、店鋪等名詞進行POI搜尋,但是這部分分兩種查詢結果:
(1)根據關鍵詞直接搜尋到的相關POI,對應包為com.baidu.mapapi.search.poi;
(2)根據關鍵詞進行聯想得到的POI,對應包為com.baidu.mapapi.search.sug。
所謂聯想搜尋得到的POI,比如我們輸入上海的時候,百度會聯想搜尋將結果提示給你:上海菜、上海大眾汽車等等,如下圖
2.兩種POI有用不同的介面、回撥函式、資料型別,如下表:
(1)com.baidu.mapapi.search.poi
介面:OnGetPoiSearchResultListener
型別 | 方法 | 說明 |
---|---|---|
void | onGetPoiDetailResult(PoiDetailResult result) | poi詳情查詢結果回撥 |
void | onGetPoiResult(PoiResult result) | poi 查詢結果回撥 |
然後主要需要了解的是
PoiResult類
PoiInfo類
搜尋POI
private AutoCompleteTextView keyWorldsView;//輸入搜尋文字的AutoCompleteTextView
private PoiSearch mPoiSearch;//POI搜尋模組
mPoiSearch = PoiSearch.newInstance();//例項化
PoiSearch.setOnGetPoiSearchResultListener(this);//監聽介面
//*****
//比如在onclick事件裡新增:搜尋->進入回撥函式:onGetPoiResult(PoiResult result)
mPoiSearch.searchInCity((new PoiCitySearchOption())//
.city(currentLoction.getCity())//定位的城市為搜尋city
.keyword(keyWorldsView.getText().toString())//關鍵詞
.pageNum(loadIndex));//第幾頁:預設從0開始,分頁為10,所以如果搜尋結果大於10,要顯示多餘10的部分就需要進行loadIndex=頁碼,或者loadIndex++等來更改loadIndex顯示下一頁資料
接下來就是onGetPoiResult(PoiResult result)
public void onGetPoiResult(PoiResult result) {
if (result == null
|| result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
Toast.makeText(PoiSearchDemo.this, "未找到結果", Toast.LENGTH_LONG)
.show();
return;
}
if (result.error == SearchResult.ERRORNO.NO_ERROR) {
//成功在傳入的搜尋city中搜索到POI
//對result進行一些應用
//一般都是新增到地圖中,然後繫結一些點選事件
//官方Demo的處理如下:
mBaiduMap.clear();
PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);
mBaiduMap.setOnMarkerClickListener(overlay);
//MyPoiOverlayextends PoiOverlay;PoiOverlay extends OverlayManager
//看了這三個class之間的關係後瞬間明白咱自己也可以寫overlay,重寫OverlayManager中的一些方法就可以了
//比如重寫了點選事件,這個方法真的太好,對不同型別的圖層可能有不同的點選事件,百度地圖3.4.0之後就支援設定多個監聽物件了,只是本人還沒把這個方法徹底掌握...
overlay.setData(result);//圖層資料
overlay.addToMap();//新增到地圖中(新增的都是marker)
overlay.zoomToSpan();//保證能顯示所有marker
return;
}
if (result.error == SearchResult.ERRORNO.AMBIGUOUS_KEYWORD) {
// 當輸入關鍵字在本市沒有找到,但在其他城市找到時,返回包含該關鍵字資訊的城市列表
String strInfo = "在";
for (CityInfo cityInfo : result.getSuggestCityList()) {
strInfo += cityInfo.city;
strInfo += ",";
}
strInfo += "找到結果";
Toast.makeText(PoiSearchDemo.this, strInfo, Toast.LENGTH_LONG)
.show();
}
}
(2)com.baidu.mapapi.search.sug
介面
該包就一個void onGetSuggestionResult(SuggestionResult result)
SuggestionResult.seggestionInfo
從欄位說明中可以看到,聯想搜尋的結果都是已經標記的POI點,擁有uid
聯想搜尋
@Override
public void onGetSuggestionResult(SuggestionResult res) {
if (res == null || res.getAllSuggestions() == null) {
return;
}
suggest = new ArrayList<String>();//獲取聯想搜尋結果
for (SuggestionResult.SuggestionInfo info : res.getAllSuggestions()) {
if (info.key != null) {
suggest.add(info.key);
}
}
sugAdapter = new ArrayAdapter<String>(PoiSearchDemo.this, android.R.layout.simple_dropdown_item_1line, suggest);//介面卡,當然可以給加上item的click事件進行處理
keyWorldsView.setAdapter(sugAdapter);
keyWorldsView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SuggestionResult.SuggestionInfo info = res.getAllSuggestions().get(position);
//String uid = info.uid;
mPoiSearch.searchPoiDetail((new PoiDetailSearchOption())//去搜索該POI的詳情->onGetPoiDetailResult(PoiDetailResult result)
.poiUid(info.uid));
}
});
sugAdapter.notifyDataSetChanged();
}
四.搜尋效果
(1)聯想搜尋效果
(2)直接搜尋效果
搜尋餐廳的結果:其實這裡還可以個性化處理,比如在定位的附近搜尋等等
(3)選擇一條聯想搜尋結果
選在一條聯想搜尋結果的顯示:
五.總結
就如前面所說,OverlayManager的重寫,可以讓我們對圖層進行一些個性化的處理是非常容易的,只是自己的前期做的時候並沒有發現這一點,而且有對圖層的一些操作,所以現在想重構圖層相關的程式碼真的一時半會還完成不了。