地图开发
概述
基于位置的服務已經深入到了我們生活中的每一個角落,這些服務我們統稱為LBS(Location Based Service),我們常見的App(淘寶、QQ、微信、美團、大眾點評、百度糯米、餓了么等)都內置了地圖定位服務。在我們以后的程序員生涯中難免要和LBS打交道。
國內提供地圖服務的公司主要有百度地圖、高德地圖、騰訊地圖、搜狗地圖。其中百度地圖從用戶數量和服務質量上都處于領先地位,高德地圖緊隨其后,這里我們以百度地圖為例來演示如何使用第三方定位服務。
百度地圖移動版API(Android)是一套基于Android設備的應用程序接口,通過該接口,可以輕松訪問百度服務和數據,構建功能豐富、交互性強的地圖應用程序。百度地圖不僅包含構建地圖的基本接口,還提供了本地搜索、路線規劃、地圖定位等數據服務。
這篇文章使用的是百度地圖在2015年6月18日發布了Android SDK v3.5.0版本。
如今百度地圖已經將定位功能,單獨剝離出來了,因此在這篇文章中我們還要討論的第二個重要內容就是百度定位SDK的使用。
百度于2015年7月17日發布了百度定位Android SDK v6.0.3產品,該產品也是本文章所使用的版本。
百度地圖功能
百度地圖 Android SDK 是一套基于Android 2.1 及以上版本設備的應用程序接口, 您可以通過該接口實現豐富的LBS 功能:
- 地圖:提供地圖(2D、3D)的展示和縮放、平移、旋轉、改變視角等地圖操作
- POI 檢索:可根據關鍵字,對POI 數據進行周邊、區域和城市內三種檢索
- 地理編碼:提供地理坐標和地址之間相互轉換的能力
- 線路規劃:支持公交信息查詢、公交換乘查詢、駕車線路規劃和步行路徑檢索
- 覆蓋物:提供多種地圖覆蓋物(自定義標注、幾何圖形、文字繪制、地形圖圖層、熱力圖圖層等),滿足開發者的各種需求
- 定位:采用多種定位模式,使用定位SDK 獲取位置信息,使用地圖SDK 我的位置圖層進行位置展示
- 離線地圖:支持使用離線地圖,節省用戶流量,同時為用戶帶來更好的地圖體驗
- 調啟百度地圖:利用SDK 接口,直接在本地打開百度地圖客戶端或WebApp,實現地圖功能
- 周邊雷達:利用周邊雷達功能,開發者可在App 內低成本、快速實現查找周邊使用相同App 的用戶位置的功能
- LBS 云檢索:支持用戶檢索存儲在LBS 云內的自有POI 數據,并展示
- 瓦片圖層:支持開發者在地圖上添加自有瓦片數據
- 特色功能:提供短串分享、Place 詳情檢索、熱力圖等特色功能,幫助開發者搭建功能更加強大的應用
什么是百度地圖API
百度地圖移動版API(Android)是一套基于Android設備的應用程序接口,通過該接口,可以輕松訪問百度服務和數據,構建功能豐富、交互性強的地圖應用程序。
百度地圖移動版API不僅包含構建地圖的基本接口,還提供了本地搜索、路線規劃、地圖定位等數據服務。
百度地圖入門
定位需要的相關權限
<!-- 這個權限用于進行網絡定位--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <!-- 這個權限用于訪問GPS定位--> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <!-- 用于訪問wifi網絡信息,wifi信息會用于進行網絡定位--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <!-- 獲取運營商信息,用于支持提供運營商信息相關的接口--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission> <!-- 這個權限用于獲取wifi的獲取權限,wifi信息會用來進行網絡定位--> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> <!-- 用于讀取手機當前的狀態--> <uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission> <!-- 寫入擴展存儲,向擴展卡寫入數據,用于寫入離線定位數據--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <!-- 訪問網絡,網絡定位需要上網--> <uses-permission android:name="android.permission.INTERNET" /> <!-- SD卡讀取權限,用戶寫入離線定位數據--> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> <!--允許應用讀取低級別的系統日志文件 --> <uses-permission android:name="android.permission.READ_LOGS"></uses-permission>準備工作
獲取API Key
地址:http://developer.baidu.com/map/android-mobile-apply-key.htm
建立工程
添加地圖引擎到Andoid工程中
- 添加jar包: baidumapapi_v3_3_0.jar和locSDK_5.0.jar
- 添加.so文件:拷貝libBaiduMapSDK_v3_3_0_15.so 、 liblocSDK5.so到libs\armeabi目錄下
- 注: locSDK_5.0.jar和liblocSDK5.so為百度定位SDK所使用資源,開發者可根據實際需求自行添加。
添加權限
初始化地圖引擎
引入布局(地圖控件)
Hellworld
布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><com.baidu.mapapi.map.MapView android:id="@+id/mapview"android:layout_width="wrap_content"android:layout_height="wrap_content"/></RelativeLayout> public class Hellworld extends Activity {private MapView mMapView;private BaiduMap baiduMap;private BroadcastReceiver receiver;double latitude = 22.582387;//緯度double longitude = 113.927331;//經度LatLng mLatLng = new LatLng(latitude, longitude);//經緯度@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);initSDK();setContentView(R.layout.activity_main);initBaiduMap();}private void initBaiduMap() {mMapView = (MapView) findViewById(R.id.mapview);baiduMap = mMapView.getMap();baiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(17));baiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(mLatLng));}private void initSDK() {SDKInitializer.initialize(getApplicationContext());IntentFilter filter = new IntentFilter();filter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);filter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);receiver = new MyRecevier();registerReceiver(receiver, filter);}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_1: //放大一個級別MapStatusUpdate zoomInUpdate = MapStatusUpdateFactory.zoomIn();baiduMap.setMapStatus(zoomInUpdate );break;case KeyEvent.KEYCODE_2: //縮小一個級別MapStatusUpdate zoomOutUpdate = MapStatusUpdateFactory.zoomOut();baiduMap.setMapStatus(zoomOutUpdate );break;case KeyEvent.KEYCODE_3: //以一個點為中心旋轉 0~360°MapStatus mapStatu = baiduMap.getMapStatus();float rotate = mapStatu.rotate;MapStatus rotateStatus = new MapStatus.Builder().rotate(rotate+30).build();MapStatusUpdate rotateUpdate = MapStatusUpdateFactory.newMapStatus(rotateStatus );baiduMap.setMapStatus(rotateUpdate );break;case KeyEvent.KEYCODE_4: //俯角 overlook -45-0 以一條直線為軸MapStatus oldStatu = baiduMap.getMapStatus();float overlook = oldStatu.overlook;MapStatus overlookStatus = new MapStatus.Builder().overlook(overlook-5).build();MapStatusUpdate overlookUpdate = MapStatusUpdateFactory.newMapStatus(overlookStatus );baiduMap.setMapStatus(overlookUpdate );break;default:break;}return super.onKeyDown(keyCode, event);}@Overrideprotected void onDestroy() {super.onDestroy();// 在activity執行onDestroy時執行mMapView.onDestroy(),實現地圖生命周期管理mMapView.onDestroy();unregisterReceiver(receiver);}@Overrideprotected void onResume() {super.onResume();// 在activity執行onResume時執行mMapView. onResume (),實現地圖生命周期管理mMapView.onResume();}@Overrideprotected void onPause() {super.onPause();// 在activity執行onPause時執行mMapView. onPause (),實現地圖生命周期管理mMapView.onPause();}class MyRecevier extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR.equals(action)) {Toast.makeText(getApplicationContext(), "網絡錯誤", Toast.LENGTH_LONG).show();} else if (SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR.equals(action)) {Toast.makeText(getApplicationContext(), "校驗失敗", Toast.LENGTH_LONG).show();}}} }地圖圖層
什么是地圖圖層
地圖可以包含一個或多個圖層,每個圖層在每個級別都是由若干個圖塊組成的,它們覆蓋了地圖的整個表面。例如您所看到包括街道、興趣點、學校、公園等內容的地圖展現就是一個圖層,另外交通流量的展現也是通過圖層來實現的。
圖層分類
底圖
基本的地圖圖層,包括若干個縮放級別,顯示基本的地圖信息,包括道路、街道、學校、公園等內容。
實時交通信息圖
baiduMap.setTrafficEnabled(true);衛星圖
baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);衛星地圖是衛星拍攝的真實的地理面貌,所以衛星地圖可用來檢測地面的信息,你可以了解到地理位置,地形等。
百度地圖SDK為廣大開發者提供的基礎地圖和上面的各種覆蓋物元素,具有一定的層級壓蓋關系,具體如下(從下至上的順序)
1、基礎底圖(包括底圖、底圖道路、衛星圖等)
2、地形圖圖層(GroundOverlay)
3、熱力圖圖層(HeatMap)
4、實時路況圖圖層(BaiduMap.setTrafficEnabled(true);)
5、百度城市熱力圖(BaiduMap.setBaiduHeatMapEnabled(true);)
6、底圖標注(指的是底圖上面自帶的那些POI元素)
7、幾何圖形圖層(點、折線、弧線、圓、多邊形)
8、標注圖層(Marker),文字繪制圖層(Text)
9、指南針圖層(當地圖發生旋轉和視角變化時,默認出現在左上角的指南針)
10、定位圖層(BaiduMap.setMyLocationEnabled(true);)
11、彈出窗圖層(InfoWindow)
12、自定義View(MapView.addView(View);)
BaseMapActivity
public class BaseMapActivity extends Activity {protected MapView mMapView;protected BaiduMap baiduMap;protected double latitude = 22.582387;//緯度protected double longitude = 113.927331;//經度protected LatLng hmPos = new LatLng(latitude, longitude);//經緯度@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.common);initBaiduMap();}private void initBaiduMap() {mMapView = (MapView) findViewById(R.id.mapview);baiduMap = mMapView.getMap();baiduMap.setMapStatus(MapStatusUpdateFactory.zoomTo(17));baiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(hmPos));}void showToast(String msg){Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();} }LayerDemo
public class LayerDemo extends BaseMapActivity {@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_1: //普通地圖baiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);baiduMap.setTrafficEnabled(false);break;case KeyEvent.KEYCODE_2://衛星圖baiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);baiduMap.setTrafficEnabled(false);break;case KeyEvent.KEYCODE_3://實時交通圖baiduMap.setTrafficEnabled(true);break;default:break;}return super.onKeyDown(keyCode, event);} }覆蓋物
所有疊加或覆蓋到地圖的內容,我們統稱為地圖覆蓋物。如標注、矢量圖形元素(包括:折線和多邊形和圓)、定位圖標等。覆蓋物擁有自己的地理坐標,當您拖動或縮放地圖時,它們會相應的處理。
本地覆蓋物
- 本地覆蓋物的抽象基類:OverlayOptions(核心類)
- 圓形覆蓋物: CircleOptions
- 文字覆蓋物: TextOptions
- 標注覆蓋物: MarkerOptions
- 圓點覆蓋物:DotOptions
- 地形覆蓋物:GroundOverlayOptions
- 圓點覆蓋物:DotOptions
- 多邊形覆蓋物:PolygonOptions
- 折線覆蓋物:PolylineOptions
- 弧線覆蓋物:ArcOptions
搜索覆蓋物
- 搜索覆蓋物抽象類: OverlayManager (核心類)
- 本地搜索覆蓋物:PoiOverlay
- 駕車路線覆蓋物:DrivingRouteOverlay
- 步行路線覆蓋物:WalkingRouteOverlay
- 換乘路線覆蓋物:TransitOverlay
- 公交路線覆蓋物:BusLineOverlay
圓形覆蓋物CircleOptions
繪制步驟
- 創建圓形: CircleOptions()
- 設置圓心坐標:center(LatLng center)
- 設置圓填充顏色:fillColor(int color) ,16進制如:#00ff0000 透明、紅、綠、藍
- 設置圓半徑:radius(int radius)
- 設置圓邊框信息:stroke(Stroke stroke)
- 設置圓是否可見:visible(boolean visible)
- 設置圓zIndex(顯示優先級)信息:zIndex(int zIndex),值越大優先級越高
文本覆蓋物TextOptions
繪制步驟
- 創建文字覆蓋物對象, TextOptions()
- 設置文字覆蓋物地理坐標:position(LatLng position)
- 設置文字覆蓋物旋轉角度,逆時針:rotate(float rotate)
- 設置文字覆蓋物的文字內容:text(java.lang.String text)
- 設置文字覆蓋物字體:typeface(Typeface typeface)
- 設置文字覆蓋物可見性:visible(boolean visible)
- 設置文字覆蓋物 zIndex:zIndex(int zIndex)
- 設置文字覆蓋物對齊方式,默認居中對齊:align(int alignX, int alignY)
- 設置文字覆蓋物背景顏色:bgColor(int bgColor)
- 設置文字覆蓋物額外信息:extraInfo(Bundle extraInfo)
- 設置文字覆蓋物字體顏色,默認黑色:fontColor(int color)
- 設置文字覆蓋物字體大小:fontSize(int size)
標注覆蓋物MarkerOptions
某個類型的覆蓋物,包含多個類型相同、顯示方式相同、處理方式相同的項時,使用此類。或者用來標記位置。
開發步驟
- 設置 marker 覆蓋物的位置坐標:position(LatLng position)
- 設置 marker 覆蓋物的標題:title(java.lang.String title)
- 設置 Marker 覆蓋物的圖標:icon(BitmapDescriptor icon)
- 設置 marker 是否允許拖拽,默認不可拖拽:draggable(boolean draggable)
搜索
百度地圖移動版API集成搜索服務包括
位置檢索、周邊檢索、范圍檢索、公交檢索、駕乘檢索、步行檢索
核心類:
- PoiSearch和OnGetPoiSearchResultListener
- RoutePlanSearch和OnGetRoutePlanResultListener
實現思路
- 初始化PoiSearch類,通過setOnGetPoiSearchResultListener方法注冊搜索結果的監聽對象OnGetPoiSearchResultListener ,實現異步搜索服務。
- 通過自定義MySearchListener實現類,處理不同的回調方法,獲得搜索結果。
- 注意, OnGetPoiSearchResultListener只支持一個,以最后一次設置為準
結合覆蓋物展示搜索
- 本地搜索覆蓋物:PoiOverlay
- 駕車路線覆蓋物:DrivingRouteOverlay
- 步行路線覆蓋物:WalkingRouteOverlay
- 換乘路線覆蓋物:TransitOverlay
本地搜索
POI(Point of Interest興趣點)搜索有三種方式
- PoiSearch.searchInBound() 范圍搜索
- PoiSearch.searchNearby() 周邊搜索
- PoiSearch.searchInCity() 全城搜索
- PoiSearch.searchPoiDetail() 詳細信息檢索
根據范圍和檢索詞發起范圍檢索
public class PoiSearchInboundsDemo extends BaseMapActivity {private PoiSearch poiSearch;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);search();}private void search() {poiSearch = PoiSearch.newInstance();LatLngBounds bounds = new LatLngBounds.Builder().include(new LatLng(22.561179, 113.895532)) //左下點的經緯度.include(new LatLng(22.602357, 113.952448)).build();PoiBoundSearchOption inBoundSearchOption = new PoiBoundSearchOption().keyword("酒店").bound(bounds);poiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {@Overridepublic void onGetPoiResult(PoiResult result) {if (result.error == SearchResult.ERRORNO.NO_ERROR) {PoiOverlay poiOverlay = new MyPoiOverlay(baiduMap);baiduMap.setOnMarkerClickListener(poiOverlay);poiOverlay.setData(result); //設置數據poiOverlay.addToMap();//添加到地圖poiOverlay.zoomToSpan();//縮放到合適視野范圍} else {showToast("為搜索到內容");}}@Overridepublic void onGetPoiDetailResult(PoiDetailResult result) {}});poiSearch.searchInBound(inBoundSearchOption);}//結果展示class MyPoiOverlay extends PoiOverlay {public MyPoiOverlay(BaiduMap map) {super(map);}@Overridepublic boolean onPoiClick(int position) {PoiResult poiResult = getPoiResult(); //獲取到setData時的搜索結果List<PoiInfo> allPoi = poiResult.getAllPoi();PoiInfo poiInfo = allPoi.get(position); //根據點擊的位置獲取到poi信息showToast("name: " + poiInfo.name + ", address: " + poiInfo.address);return super.onPoiClick(position);}} }周邊檢索
public class PoiSearchNearByDemo extends BaseMapActivity {private PoiSearch poiSearch;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);search();}private void search() {poiSearch = PoiSearch.newInstance();poiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {@Overridepublic void onGetPoiResult(PoiResult result) {if (result.error == SearchResult.ERRORNO.NO_ERROR) {PoiOverlay poiOverlay = new MyPoiOverlay(baiduMap);baiduMap.setOnMarkerClickListener(poiOverlay);poiOverlay.setData(result); // 設置數據poiOverlay.addToMap(); // 添加到地圖poiOverlay.zoomToSpan(); // 縮放到合適視野范圍} else {showToast("未搜索到內容");}}@Overridepublic void onGetPoiDetailResult(PoiDetailResult result) {if (result.error == SearchResult.ERRORNO.NO_ERROR) {showToast("name:" + result.getName()+ "env: " + result.getEnvironmentRating()+ "price: " + result.getPrice());} else {showToast("未搜索到詳細內容");}}});PoiNearbySearchOption nearByOption = new PoiNearbySearchOption().location(hmPos).radius(3000).keyword("酒店");poiSearch.searchNearby(nearByOption);}class MyPoiOverlay extends PoiOverlay {public MyPoiOverlay(BaiduMap map) {super(map);}@Overridepublic boolean onPoiClick(int position) {PoiResult poiResult = getPoiResult(); // 獲取到setData時的搜索結果List<PoiInfo> allPoi = poiResult.getAllPoi();PoiInfo poiInfo = allPoi.get(position); // 根據點擊的位置獲取到poi信息PoiDetailSearchOption detailOption = new PoiDetailSearchOption();detailOption.poiUid(poiInfo.uid);// showToast("name: "+poiInfo.name+", address: "+poiInfo.address);poiSearch.searchPoiDetail(detailOption);return super.onPoiClick(position);}} }全城搜索
public class PoiSearchCityDemo extends BaseMapActivity {private PoiSearch poiSearch;private int curreantNum;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);search();}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_1:curreantNum++;search();break;default:break;}return super.onKeyDown(keyCode, event);}private void search() {poiSearch = PoiSearch.newInstance();poiSearch.setOnGetPoiSearchResultListener(new OnGetPoiSearchResultListener() {private PoiOverlay poiOverlay;@Overridepublic void onGetPoiResult(PoiResult result) {if (result.error == SearchResult.ERRORNO.NO_ERROR) {showToast("總共:" + result.getTotalPageNum()+ "頁,當前是第" + result.getCurrentPageNum() +"頁,第幾條:" + result.getCurrentPageCapacity());// if(poiOverlay != null){// poiOverlay.removeFromMap();// }baiduMap.clear();poiOverlay = new MyPoiOverlay(baiduMap);baiduMap.setOnMarkerClickListener(poiOverlay);poiOverlay.setData(result); // 設置數據poiOverlay.addToMap(); // 添加到地圖poiOverlay.zoomToSpan(); // 縮放到合適視野范圍} else {showToast("未搜索到內容");}}@Overridepublic void onGetPoiDetailResult(PoiDetailResult result) {if (result.error == SearchResult.ERRORNO.NO_ERROR) {showToast("name:" + result.getName()+ "env: " + result.getEnvironmentRating()+ "price: " + result.getPrice());} else {showToast("未搜索到詳細內容");}}});PoiCitySearchOption cityOption = new PoiCitySearchOption().city("深圳").keyword("酒店").pageNum(curreantNum).pageCapacity(15);poiSearch.searchInCity(cityOption);}class MyPoiOverlay extends PoiOverlay {public MyPoiOverlay(BaiduMap map) {super(map);}@Overridepublic boolean onPoiClick(int position) {PoiResult poiResult = getPoiResult(); // 獲取到setData時的搜索結果List<PoiInfo> allPoi = poiResult.getAllPoi();PoiInfo poiInfo = allPoi.get(position); // 根據點擊的位置獲取到poi信息PoiDetailSearchOption detailOption = new PoiDetailSearchOption();detailOption.poiUid(poiInfo.uid);// showToast("name: "+poiInfo.name+", address: "+poiInfo.address);poiSearch.searchPoiDetail(detailOption);return super.onPoiClick(position);}} }查詢加油站信息
多種查詢方法,但結果的處理都在OnGetPoiSearchResultListener的onGetPoiResult方法中
處理步驟:
- 判斷服務器結果返回
- 創建poi覆蓋物
- 將服務器返回數據添加到poi覆蓋物中
- 添加覆蓋物到地圖addToMap
- 縮放地圖,使所有Overlay都在合適的視野內
注意
- POI檢索結果每頁容量默認情況下為10,可以通過pageCapacity設置,支持1-50(10)
- 翻頁功能重新調用通過PoiSearch類的searchInXxx()方法并傳遞頁數角標pageNum來實現,該方法是異步函數,搜索成功后會調用注冊的事件處理函數onGetPoiResult 返回查詢頁的結果。
路線規劃
1、駕車路線
結果展示: DrivingRouteOverlay
案例:從黑馬到傳智路線查詢
- 查詢:RoutePlanSearch.drivingSearch()駕乘路線搜索,或者增加途經點.
- PlanNode內容的設置:可以使用經緯度和地名,但不支持模糊查詢,需要輸入準確的名稱
- 可以通過DrivingRoutePlanOption.policy (int policy) 來設置駕車路線規劃策略
- 結果處理:OnGetRoutePlanResultListener. onGetDrivingRouteResult(DrivingRouteResult result)
2、步行路線
結果展示: WalkingRouteOverlay
RoutePlanSearch. walkingSearch()步行路線搜索
結果處理: OnGetRoutePlanResultListener. onGetWalkingRouteResult(WalkingRouteResult result)
public class WalkingRouteDemo extends BaseMapActivity {private RoutePlanSearch routeSearch;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);search();}private void search() {routeSearch = RoutePlanSearch.newInstance();// ArrayList<PlanNode> pass = new ArrayList<PlanNode>();// pass.add(PlanNode.withCityNameAndPlaceName("深圳", "塘朗山公園"));routeSearch.setOnGetRoutePlanResultListener(new OnGetRoutePlanResultListener() {@Overridepublic void onGetWalkingRouteResult(WalkingRouteResult result) {if (result.error == SearchResult.ERRORNO.NO_ERROR) {WalkingRouteOverlay walkingRouteOverlay = new MyWalkingOverlay(baiduMap).setData(result.getRouteLines().get(0)).addToMap().zoomToSpan();} else {showToast("未搜索到相關路線");}}@Overridepublic void onGetTransitRouteResult(TransitRouteResult result) {}@Overridepublic void onGetDrivingRouteResult(DrivingRouteResult result) {}});WalkingRoutePlanOption walkingOption = new WalkingRoutePlanOption().from(PlanNode.withLocation(hmPos)).to(PlanNode.withCityNameAndPlaceName("深圳", "靈芝地鐵站"));routeSearch.walkingSearch(walkingOption);}class MyWalkingOverlay extends WalkingRouteOverlay {public MyWalkingOverlay(BaiduMap arg0) {super(arg0);}@Overridepublic BitmapDescriptor getStartMarker() {return BitmapDescriptorFactory.fromResource(R.drawable.icon_st);}@Overridepublic BitmapDescriptor getTerminalMarker() {return BitmapDescriptorFactory.fromResource(R.drawable.icon_en);}} }3、換乘路線
結果展示:TransitRouteOverlay
檢索: RoutePlanSearch. transitSearch()
通過TransitRoutePlanOption.policy (int policy) 設置路線規劃策略
結果處理: OnGetRoutePlanResultListener. onGetTransitRouteResult(TransitRouteResult result)
地址解析服務
GeoCoder.geocode(GeoCodeOption option)
根據地址名獲取地址信息 異步函數,返回結果在OnGetGeoCoderResultListener里的onGetGeoCodeResult()方法通知
GeoCoder.reverseGeoCode(ReverseGeoCodeOption option)
根據地理坐標點獲取地址信息 異步函數,返回結果在OnGetGeoCoderResultListener里的onGetReverseGeoCodeResult()方法通知
聯想詞檢索
SuggestionSearch . requestSuggestion(SuggestionSearchOption option)
查詢一系列與指定key相關的內容,結果中包括城市及包含key的名稱
結果處理OnGetSuggestionResultListener . onGetSuggestionResult(SuggestionResult result)
公交路線詳細信息搜索
檢索: BusLineSearch. searchBusLine(BusLineSearchOption option)
busLineUid()信息獲取:公交線路的uid,可以通過poi查詢返回的結果中獲取MKPoiInfo的uid。
使用poiSearchInCity查詢公交線信息,利用PoiInfo的type可以判斷poi類型,當類型為公交線路時,記錄當前的PoiInfo中的uid信息。
利用獲取的uid信息進行公交線的查詢
結果處理:在OnGetBusLineSearchResultListener. onGetBusLineResult(BusLineResult result)中進行結果的處理,此時使用到的覆蓋物是BusLineOverlay
0:普通點
1:公交站
2:公交線路
3:地鐵站
4:地鐵線路
定位
在百度地圖移動版API中,提供一個重要的特色功能:定位,通過這個功能,能獲取到用戶當前所在位置。
在程序中,如果使用此功能,必須注冊GPS和網絡的使用權限。
在獲取用戶位置時,優先使用GPS進行定位;如果GPS定位沒有打開或者沒有可用位置信息,則會通過判斷網絡是否連接(即確認手機是否能上網,不論是連接2G/3G或Wi-Fi網絡),如果是,則通過請求百度網絡定位服務,返回網絡定位結果。為了使獲得的網絡定位結果更加精確,請打開手機的Wi-Fi開關。
目前系統自帶的網絡定位服務精度低,且服務不穩定、精度低,并且從未來的趨勢看,基站定位是不可控的(移動公司隨時可能更改基站編號以壟斷定位服務),而Wi-Fi定位則不然,它是一種精度更高、不受管制的定位方法。國內其它使用Wi-Fi定位的地圖軟件,Wi-Fi定位基本不可用,百度的定位服務量化指標優秀,網絡接口返回速度快(服務端每次定位響應時間50毫秒以內),平均精度70米,其中Wi-Fi精度40米左右,基站定位精度200米左右,覆蓋率98%,在國內處于一枝獨秀的地位。
注意
關于經緯度的說明:該經緯度信息是經過加密處理,所以在其它地圖工具中測得的經緯度 信息不適合百度的坐標系統。
使用百度經緯度坐標,可以通過http://api.map.baidu.com/lbsapi/getpoint/index.html查詢地理坐標如果需要在百度地圖上顯示使用其他坐標系統的位置,請發郵件至mapapi@baidu.com申請坐標轉換接口
LocationClient和BDLocationListener
首先需要打開定位圖層BaiduMap.setMyLocationEnabled(true);
設置監聽器LocationClient. registerLocationListener(BDLocationListener)
設置定位模式baiduMap. setLocationMode(LocationMode)
Hight_Accuracy,高精度定位模式:這種定位模式下,會同時使用網絡定位和GPS定位,優先返回最高精度的定位結果;
Battery_Saving,低功耗定位模式:這種定位模式下,不會使用GPS,只會使用網絡定位(Wi-Fi和基站定位)
Device_Sensors,僅用設備定位模式:這種定位模式下,不需要連接網絡,只使用GPS進行定位,這種模式下不支持室內環境的定位
設置定位顯示模式BaiduMap.setMyLocationConfigeration(MyLocationConfiguration)
定位數據獲取:在BDLocationListener. onReceiveLocation(BDLocation result)方法中設置定位數據,
baiduMap.setMyLocationData(MyLocationData);
百度定位
public class LocationDemo extends BaseMapActivity {public LocationClient mLocationClient;public BDLocationListener myListener;private BitmapDescriptor geo;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);lacate();}private void lacate() {mLocationClient = new LocationClient(getApplicationContext());myListener = new MyListener();mLocationClient.registerLocationListener(myListener);LocationClientOption option = new LocationClientOption().setLocationMode(LocationMode.Hight_Accuracy)//設置定位模式.setCoorType("bd09ll")// 返回的定位結果是百度經緯度,默認值gcj02.setScanSpan(5000)// 設置發起定位請求的間隔時間為5000ms.setIsNeedAddress(true)// 返回的定位結果包含地址信息.setNeedDeviceDirect(true);// 返回的定位結果包含手機機頭的方向mLocationClient.setLocOption(option);geo = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo);MyLocationConfiguration configuration = new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true, geo);baiduMap.setMyLocationConfigeration(configuration);// 設置定位顯示的模式baiduMap.setMyLocationEnabled(true);// 打開定位圖層}@Overrideprotected void onStart() {mLocationClient.start();super.onStart();}@Overrideprotected void onPause() {mLocationClient.stop();super.onPause();}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {switch (keyCode) {case KeyEvent.KEYCODE_1:// 正常// 設置定位顯示的模式baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.NORMAL, true, geo));break;case KeyEvent.KEYCODE_2:// 羅盤// 設置定位顯示的模式baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.COMPASS, true, geo));break;case KeyEvent.KEYCODE_3:// 跟隨// 設置定位顯示的模式baiduMap.setMyLocationConfigeration(new MyLocationConfiguration(MyLocationConfiguration.LocationMode.FOLLOWING, true, geo));break;default:break;}return super.onKeyDown(keyCode, event);}class MyListener implements BDLocationListener {@Overridepublic void onReceiveLocation(BDLocation result) {if (result != null) {MyLocationData data = new MyLocationData.Builder().latitude(result.getLatitude()).longitude(result.getLongitude()).build();baiduMap.setMyLocationData(data);}}} }位置分享
public class ShareUrlSearchDemo extends Activity {private ShareUrlSearch mShareUrlSearch;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mShareUrlSearch = ShareUrlSearch.newInstance();mShareUrlSearch.setOnGetShareUrlResultListener(shareUrlResultListener);LocationShareURLOption locationShareURLOption = new LocationShareURLOption().location(mCurrentMarker.getPosition()).name("我的位置").snippet("這是我的位置");mShareUrlSearch.requestLocationShareUrl(locationShareURLOption);}private OnGetShareUrlResultListener shareUrlResultListener = new OnGetShareUrlResultListener() {public void onGetPoiDetailShareUrlResult(ShareUrlResult result) {//分享POI詳情 }public void onGetLocationShareUrlResult(ShareUrlResult result) {//分享位置信息 String url = result.getUrl();Intent sendIntent = new Intent();sendIntent.setAction(Intent.ACTION_SEND);sendIntent.putExtra(Intent.EXTRA_TEXT, url);sendIntent.setType("text/plain");//startActivity(Intent.createChooser(sendIntent, "位置分享"));}}; }離線地圖
/** 離線地圖初始化 **/ mOffline = new MKOfflineMap(); mOffline.init(mBMapMan, new MKOfflineMapListener() {public void onGetOfflineMapState(int type, int state) {switch (type) {case MKOfflineMap.TYPE_DOWNLOAD_UPDATE:{MKOLUpdateElement update = mOffline.getUpdateInfo(state);//mText.setText(String.format("%s : %d%%", update.cityName, update.ratio));}break;case MKOfflineMap.TYPE_NEW_OFFLINE:Log.d("OfflineDemo", String.format("add offlinemap num:%d", state));break;case MKOfflineMap.TYPE_VER_UPDATE:Log.d("OfflineDemo", String.format("new offlinemap ver"));break;} } } ); /** 離線地圖導入離線包 **/ int num = mOffline.scan();總結
- 上一篇: 登录和oauth机制
- 下一篇: Android中的设计模式-状态模式