android 百度地圖示註覆蓋物學習

android 百度地圖示註覆蓋物學習

介紹

最近著手做一個新的專案,其中涉及到地圖定位,以及從伺服器獲取附近的特定商家並在地圖上面標註出來。於是就研究了一下百度地圖示註覆蓋物功能,然後進行一點個人總結,以便學習交流使用,個人學習總結還請各位看官輕噴。

一、定位

百度地圖SDK從2.0.0版本起,將定位功能進行了分離,開發者在使用過程中,下載開發包的時候注意下載帶有定位功能的SDK。
定位
定位功能的具體實現這裡不過多贅述請參看官方文件
核心程式碼如下:

    /**
* 進行定位
*/
private void doLocation() {
Toast.makeText(this, "彈窗", Toast.LENGTH_SHORT).show();
mBaiduMap = mMapView.getMap();
mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
mBaiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(16));
locService = ((MyApplication) getApplication()).locationService;
LocationClientOption mOption = locService.getDefaultLocationClientOption();
mOption.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
mOption.setCoorType("bd09ll");
locService.setLocationOption(mOption);
locService.registerListener(listener);
locService.start();
}
/***
* 定位結果回撥,在此方法中處理定位結果
*/
BDLocationListener listener = new BDLocationListener() {
@Override
public void onReceiveLocation(BDLocation location) {
if (location != null && (location.getLocType() == 161 || location.getLocType() == 66)) {
Message locMsg = locHander.obtainMessage();
Bundle locData = new Bundle();
locData.putParcelable("loc", location);
locMsg.setData(locData);
locHander.sendMessage(locMsg);
}
}
};
/***
* 接收定位結果訊息,並顯示在地圖上
*/
private Handler locHander = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
try {
BDLocation location = msg.getData().getParcelable("loc");
if (location != null) {
LatLng point = new LatLng(location.getLatitude(), location.getLongitude());
// 構建Marker圖示
BitmapDescriptor bitmap = null;
bitmap = BitmapDescriptorFactory.fromResource(R.drawable.bdmap_user_loaction);
// 構建MarkerOption,用於在地圖上新增Marker
OverlayOptions option = new MarkerOptions().position(point).icon(bitmap);
// 在地圖上新增Marker,並顯示
mBaiduMap.addOverlay(option);
//設定地圖新中心點
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(point));
}
} catch (Exception e) {
// TODO: handle exception
}
}
};

以上程式碼就是開啟定位功能並在地圖上顯示出來,其實已經用到了標註覆蓋物功能。

二、標註覆蓋物功能

標註覆蓋物就是根據自己實際的業務需求,利用標註覆蓋物,在地圖指定的位置上新增標註資訊。
效果如下:

標註覆蓋物效果圖
實現的核心程式碼如下:

//定義Maker座標點  
LatLng point = new LatLng(39.963175, 116.400244);  
//構建Marker圖示  
BitmapDescriptor bitmap = BitmapDescriptorFactory  
.fromResource(R.drawable.icon_marka);  
//構建MarkerOption,用於在地圖上新增Marker  
OverlayOptions option = new MarkerOptions()  
.position(point)  
.icon(bitmap);  
//在地圖上新增Marker,並顯示  
mBaiduMap.addOverlay(option);

上述程式碼可以實現在地圖上面特定位置標註出目標覆蓋物的效果,但是在實際開發中有時候需要批量的新增這些覆蓋物,並且要求能夠實現對覆蓋物的一些操作,這個時候僅僅這些程式碼是遠遠不夠的。
首先是批量新增標註覆蓋物,這裡不得不吐槽一下百度地圖的api,在升級3.0後api幾乎全部不相容。2.3的版本可以使用OverlayItem進行批量新增標註無,現在新版已經沒有這個類了。所以首先想到的辦法就是迴圈新增,其實也很簡單,程式碼如下:

         // 構建Marker圖示
BitmapDescriptor bitmap = null;
bitmap = BitmapDescriptorFactory.fromResource(R.drawable.bdmap_user_loaction);
LatLng point =null;
//這裡模擬出一些從伺服器中獲取到的座標
double[][] testNum = {{34.826574, 113.569846}, {34.825322, 113.568809}, {34.825129, 113.570525}, {34.825163, 113.567695}, {34.826759, 113.570147}, {113.571935, 34.823474}, {34.823959, 113.575093}};
//模擬從伺服器中獲取到的商店資訊
String[] shopName = {"no Name","萬州烤魚","君荷酒店","湘香烤魚","聖禧牛肉湯","中國工商銀行","蓮花公園"};
Bundle bundle = new Bundle();
for (int i = 0;i<testNum.length;i  ){
bundle.clear();
bundle.putString("shopName",shopName[i]);
point = new LatLng(testNum[i][0],testNum[i][1]);
//.title()給覆蓋物新增標題
OverlayOptions option = new MarkerOptions().position(point).icon(bitmap).title(shopName[i]);
mBaiduMap.addOverlay(option);
}

以上程式碼就是迴圈新增,實現起來很簡單,但是有一個問題就是如果獲取到的資料量很大的話,會很消耗相當的資源。
現在批量新增覆蓋物實現了,還要求能像地圖那樣點選覆蓋物能能彈出一些窗體或者一些其他操作,在官方文件中給出了一些對覆蓋物的操作有拖拽、動畫等,但是都不能很好的滿足要求。於是檢視了一些資料以後發現有一個mBaiduMap.setOnMarkerClickListener()方法,於是嘗試著實現這個方法,實驗發現要在標註覆蓋物新增完成以後,再給mBaiduMap新增監聽才可以,然後又出現一個問題就是如何才能從被點選的標註中獲取到想要的資訊,檢視文件中並沒有給出這些,檢視所有類api文件發現有public MarkerOptions title(java.lang.String title)以及getTitle()方法,於是就將一些資訊通過這個方法傳入標註中。於是程式碼如下:

 @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
try {
BDLocation location = msg.getData().getParcelable("loc");
if (location != null) {
getNearbyShop(location.getLatitude(), location.getLongitude());
LatLng point = new LatLng(location.getLatitude(), location.getLongitude());
MaintelsLogUtils.outLog(location.getLatitude()   "_____"   location.getLongitude()   "");
// 構建Marker圖示
BitmapDescriptor bitmap = null;
bitmap = BitmapDescriptorFactory.fromResource(R.drawable.bdmap_user_loaction);
// 構建MarkerOption,用於在地圖上新增Marker
OverlayOptions option = new MarkerOptions().position(point).icon(bitmap);
// 在地圖上新增Marker,並顯示
mBaiduMap.addOverlay(option);
//設定地圖新中心點 
mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(point));
//新增標註覆蓋物點選監聽
mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
String title =  marker.getTitle();
if( title != null){
Toast.makeText(BDMapActivity.this, title, Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(BDMapActivity.this, "未知位置", Toast.LENGTH_SHORT).show();
}
return false;
}
});
}
} catch (Exception e) {
// TODO: handle exception
}
}
};

後來發現還有一個方法public MarkerOptions extraInfo(Bundle extraInfo),以bundle傳入,待驗證。