百度地圖API Android SDK 常見問題
1 使用須知
在使用百度地圖SDK(Android版)之前,請仔細閱讀使用條款,一旦您使用了百度地圖SDK(Android版),即表明您已閱讀並接受使用條款中的全部內容。百度地圖SDK(Android版)可幫助您在應用中以豐富的形式展示地圖,實現興趣點搜尋、線路規劃等操作。 您只可使用在百度地圖SDK(Android版)開發文件中所列明開放的功能來對相關服務資料的結果進行展示,不得直接存取、使用內部資料、圖片、程式、模組或是任何其他百度地圖的服務或功能。在接受使用條款約束的情況下,您可以在向終端使用者提供其他資訊的同時,使用 API 獲取相關服務資料。
2 百度使用者和Key
2.1 如何註冊百度使用者?
公眾使用者請在百度個人中心註冊使用者。企業使用者請聯絡我們。
2.2 如何申請百度地圖移動版API Key?
公眾使用者在獲取金鑰中自行申請,可以每個應用申請一個Key,可以用在不同移動平臺上的相同應用中。申請的Key個數目前沒有限制。企業使用者請聯絡我們。
2.3 忘記申請過的Key怎麼辦?
公眾使用者在獲取金鑰側邊欄中,點選“我的KEY”檢視已申請過的Key和對應的應用名稱。
3 Android問題集錦
3.1 定位、座標相關
3.1.1 API如何獲取定位資訊?
說明:此部分是針對1.3.5及以前版本的說明,自2.0.0版本以後,定位功能已從Android SDK中分離,開發者在使用定位功能時,請具體參考定位SDK。
在百度地圖移動版API中,我們提供一個重要的特色功能:定位,通過這個功能,能獲取到使用者當前所在位置。
在程式中,如果使用此功能,必須註冊GPS和網路的使用許可權。
在獲取使用者位置時,優先使用GPS進行定位;如果GPS定位沒有開啟或者沒有可用位置資訊,則會通過判斷網路是否連線(即確認手機是否能上網,不論是連線2G/3G或Wi-Fi網路),如果是,則通過請求百度網路定位服務,返回網路定位結果。為了使獲得的網路定位結果更加精確,請開啟手機的Wi-Fi開關。
目前系統自帶的網路定位服務精度低,且服務不穩定、精度低,並且從未來的趨勢看,基站定位是不可控的(移動公司隨時可能更改基站編號以壟斷定位服務),而Wi-Fi定位則不然,它是一種精度更高、不受管制的定位方法。國內其它使用Wi-Fi定位的地圖軟體,Wi-Fi定位基本不可用,百度的定位服務量化指標優秀,網路介面返回速度快(服務端每次定位響應時間50毫秒以內),平均精度70米,其中Wi-Fi精度40米左右,基站定位精度200米左右,覆蓋率98%,在國內處於一枝獨秀的地位。
3.1.2 如何得到定位的座標和地址?
說明: 自2.0.0版本開始,獲取定位座標的方法請參考定位SDK中的說明,如下獲取定位座標的方法只針對1.3.5及以前的版本有效。
使用MKLocationManager 類的requestLocationUpdates 註冊位置監聽事件,在重寫的回撥函式onLocationChanged中,可獲得定位的座標(詳見BMapApiDemoMain例程的MyLocation.java),通過呼叫MKSearch類的reverseGeocode介面,得到地址。
- 1. @Override
- 2. publicvoid onLocationChanged( Location location ){
- 3. if( location != null ){
- 4. pt.setLatitudeE6( ( int ) (location.getLatitude()*1e6));
- 5. pt.setLongtitudeE6( ( int ) (location.getLongtitude()*1e6));
- 6. mSearch.reverseGeocode(pt);
- 7. }
- 8. }
- 9. publicvoid onGetAddrResult( MKAddrInfo res, int error ){
- 10. if( error != 0){
- 11. String str = String.format("錯誤號:%d",error);
- 12. return;
- 13. }
- 14. String strInfo = String.format("緯度:%f 經度:%f 地址:%s\r\n",
- 15. res.geoPt.getlatitudeE6() / 1e6,
- 16. res.geoPt.getLongtitudeE6 / 1e6,
- 17. res.addressComponents.city +
- 18. res.addressComponents.district +
- 19. res.addressComponents.street );
- 20. }
3.1.3 如何讓我的地圖自動定位?
說明: 此部分是針對1.3.5及以前版本的說明,自2.0.0版本以後,定位功能已從Android SDK中分離,開發者在實現自動定位操作時,請參考定位SDK中的具體說明
首先在程式中開啟相關的許可權,然後將MyLocationOverlay例項新增到MapView中,並呼叫enableMyLocation方法,即可實現當前位置的顯示,如果想讓地圖跟隨當前位置移動,需要繼承MyLocationOverlay並實現其onLocationChanged方法,呼叫MapView.getController().animateTo()方法移動地圖位置。
3.1.4 如何計算兩點之間距離?
路線規劃提供了獲取路線距離的方法,見MKRoutePlan 類的 getDistance 方法。
如果是計算任意兩點的距離,自2.0.0版本開始,Android SDK為開發者提供了計算距離的介面(DistanceUtil),具體使用方法如下:
1.GeoPoint p1LL = new GeoPoint(39971802, 116347927);
2.GeoPoint p2LL = new GeoPoint(39892131, 116498555);
3.double distance = DistanceUtil.getDistance(p1LL, p2LL);
如果開發者使用的是1.3.5及以前的版本,在計算任意兩點之前的距離時,有如下兩種方法:一種利用勾股定理計算,適用於兩點距離很近的情況;一種按標準的球面大圓劣弧長度計算,適用於距離較遠的情況。
- 1. static double DEF_PI = 3.14159265359; // PI
- 2. staticdouble DEF_2PI=6.28318530712;// 2*PI
- 3. staticdouble DEF_PI180=0.01745329252;// PI/180.0
- 4. staticdouble DEF_R =6370693.5;// radius of earth
- 5. publicdouble GetShortDistance(double lon1, double lat1, double lon2, double lat2)
- 6. {
- 7. double ew1, ns1, ew2, ns2;
- 8. double dx, dy, dew;
- 9. double distance;
- 10. // 角度轉換為弧度
- 11. ew1= lon1 * DEF_PI180;
- 12. ns1= lat1 * DEF_PI180;
- 13. ew2= lon2 * DEF_PI180;
- 14. ns2= lat2 * DEF_PI180;
- 15. // 經度差
- 16. dew= ew1 - ew2;
- 17. // 若跨東經和西經180 度,進行調整
- 18. if(dew > DEF_PI)
- 19. dew= DEF_2PI - dew;
- 20. elseif(dew <-DEF_PI)
- 21. dew= DEF_2PI + dew;
- 22. dx= DEF_R *Math.cos(ns1)* dew;// 東西方向長度(在緯度圈上的投影長度)
- 23. dy= DEF_R *(ns1 - ns2);// 南北方向長度(在經度圈上的投影長度)
- 24. // 勾股定理求斜邊長
- 25. distance=Math.sqrt(dx * dx + dy * dy);
- 26. return distance;
- 27. }
- 28. publicdouble GetLongDistance(double lon1, double lat1, double lon2, double lat2)
- 29. {
- 30. double ew1, ns1, ew2, ns2;
- 31. double distance;
- 32. // 角度轉換為弧度
- 33. ew1= lon1 * DEF_PI180;
- 34. ns1= lat1 * DEF_PI180;
- 35. ew2= lon2 * DEF_PI180;
- 36. ns2= lat2 * DEF_PI180;
- 37. // 求大圓劣弧與球心所夾的角(弧度)
- 38. distance=Math.sin(ns1)*Math.sin(ns2)+Math.cos(ns1)*Math.cos(ns2)*Math.cos(ew1 - ew2);
- 39. // 調整到[-1..1]範圍內,避免溢位
- 40. if(distance >1.0)
- 41. distance=1.0;
- 42. elseif(distance <-1.0)
- 43. distance=-1.0;
- 44. // 求大圓劣弧長度
- 45. distance= DEF_R *Math.acos(distance);
- 46. return distance;
- 47. }
- 48. double mLat1 =39.90923;// point1緯度
- 49. double mLon1 =116.357428;// point1經度
- 50. double mLat2 =39.90923;// point2緯度
- 51. double mLon2 =116.397428;// point2經度
- 52. double distance = GetShortDistance(mLon1, mLat1, mLon2, mLat2);
3.1.5 點選MapView上一點,如何獲取該點座標?
通過繼承MapView類重寫onTouchEvent方法來獲取點選螢幕的位置,再通過介面Projection的 fromPixels 方法將點選位置轉換為該點的地址座標,並且將地圖空間bMapView的型別由com.baidu.mapapi.MapView改為子類型別,本例中為com.baidu.mapapi.demo.MapViewTest具體程式碼如下:
- 1. MapViewTest mapView=(MapViewTest)findViewById(R.id.bmapView);
- 2. class MapViewTest extends MapView
- 3. {
- 4. public MapViewTest(Context context)
- 5. {
- 6. super(context);
- 7. }
- 8. public MapViewTest(Context context, AttributeSet attrs)
- 9. {
- 10. super( context, attrs);
- 11. }
- 12. public MapViewTest(Context context,AttributeSet attrs,int defStyle)
- 13. {
- 14. super( context, attrs,defStyle);
- 15. }
- 16. @Override
- 17. publicboolean onTouchEvent(MotionEvent event)
- 18. {
- 19. //獲得螢幕點選的位置
- 20. int x =(int)event.getX();
- 21. int y =(int)event.getY();
- 22. //將畫素座標轉為地址座標
- 23. GeoPoint pt =this.getProjection().fromPixels(x,y);
- 24. returnsuper.onTouchEvent(event);
- 25. }
- 26. }
3.1.6 百度地圖地址解析服務Geocoder如何使用?
地址解析服務在MKSearch類中有兩個介面:reverseGeocode、geocode。 初始化搜尋類MKSearch並註冊結構監聽物件MKSearchListener:
- 1. //初始化搜尋模組,註冊事件監聽
- 2. mSearch=new MKSearch();
- 3. mSearch.init(app.mBMapMan, new MySearchListener());
實現MySearchListener的onGetAddrResult獲取得到的地址資訊
- 1. @Override
- 2. publicvoid onGetAddrResult( MKAddrInfo res, int error ){
- 3. if( error != 0){
- 4. String str = String.format("錯誤號:%d",error);
- 5. return;
- 6. }
- 7. String strInfo = String.format("緯度:%f 經度:%f 地址:%s\r\n",
- 8. res.geoPt.getlatitudeE6() / 1e6,
- 9. res.geoPt.getLongtitudeE6 / 1e6,
- 10. res.addressComponents.city +
- 11. res.addressComponents.district +
- 12. res.addressComponents.street );
- 13. }
geocode:根據地址名稱獲取地址資訊:
- 1. mSearch.geocode("天安門","北京");
reverseGeocode:根據地理座標點獲取地址: