1. 程式人生 > >百度地圖API Android SDK 常見問題

百度地圖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. 1@Override
  2. 2publicvoid onLocationChanged( Location location ){
  3. 3.       if( location != null ){
  4. 4.           pt.setLatitudeE6( ( int ) (location.getLatitude()*1e6));
  5. 5.           pt.setLongtitudeE6( ( int ) (location.getLongtitude()*1e6));
  6. 6.           mSearch.reverseGeocode(pt);
  7. 7.        }
  8. 8}
  9. 9publicvoid onGetAddrResult( MKAddrInfo res, int error ){
  10. 10.       if( error != 0){
  11. 11.           String str = String.format("錯誤號:%d",error);
  12. 12.           return;
  13. 13.         }
  14. 14.        String strInfo = String.format("緯度:%f 經度:%f 地址:%s\r\n",
  15. 15.                    res.geoPt.getlatitudeE6() / 1e6,
  16. 16.                    res.geoPt.getLongtitudeE6 / 1e6,
  17. 17.                    res.addressComponents.city +
  18. 18.                    res.addressComponents.district +
  19. 19.                    res.addressComponents.street );
  20. 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. 1static double DEF_PI = 3.14159265359; // PI
  2. 2staticdouble DEF_2PI=6.28318530712;// 2*PI
  3. 3staticdouble DEF_PI180=0.01745329252;// PI/180.0
  4. 4staticdouble DEF_R =6370693.5;// radius of earth
  5. 5publicdouble GetShortDistance(double lon1, double lat1, double lon2, double lat2)
  6. 6{
  7. 7.  double ew1, ns1, ew2, ns2;
  8. 8.  double dx, dy, dew;
  9. 9.  double distance;
  10. 10.  // 角度轉換為弧度
  11. 11.  ew1= lon1 * DEF_PI180;
  12. 12.  ns1= lat1 * DEF_PI180;
  13. 13.  ew2= lon2 * DEF_PI180;
  14. 14.  ns2= lat2 * DEF_PI180;
  15. 15.  // 經度差
  16. 16.  dew= ew1 - ew2;
  17. 17.  // 若跨東經和西經180 度,進行調整
  18. 18.  if(dew > DEF_PI)
  19. 19.  dew= DEF_2PI - dew;
  20. 20.  elseif(dew <-DEF_PI)
  21. 21.  dew= DEF_2PI + dew;
  22. 22.  dx= DEF_R *Math.cos(ns1)* dew;// 東西方向長度(在緯度圈上的投影長度)
  23. 23.  dy= DEF_R *(ns1 - ns2);// 南北方向長度(在經度圈上的投影長度)
  24. 24.  // 勾股定理求斜邊長
  25. 25.  distance=Math.sqrt(dx * dx + dy * dy);
  26. 26.  return distance;
  27. 27}
  28. 28publicdouble GetLongDistance(double lon1, double lat1, double lon2, double lat2)
  29. 29{
  30. 30.  double ew1, ns1, ew2, ns2;
  31. 31.  double distance;
  32. 32.  // 角度轉換為弧度
  33. 33.  ew1= lon1 * DEF_PI180;
  34. 34.  ns1= lat1 * DEF_PI180;
  35. 35.  ew2= lon2 * DEF_PI180;
  36. 36.  ns2= lat2 * DEF_PI180;
  37. 37.  // 求大圓劣弧與球心所夾的角(弧度)
  38. 38.  distance=Math.sin(ns1)*Math.sin(ns2)+Math.cos(ns1)*Math.cos(ns2)*Math.cos(ew1 - ew2);
  39. 39.  // 調整到[-1..1]範圍內,避免溢位
  40. 40.  if(distance >1.0)
  41. 41.       distance=1.0;
  42. 42.  elseif(distance <-1.0)
  43. 43.        distance=-1.0;
  44. 44.  // 求大圓劣弧長度
  45. 45.  distance= DEF_R *Math.acos(distance);
  46. 46.  return distance;
  47. 47}
  48. 48double mLat1 =39.90923;// point1緯度
  49. 49double mLon1 =116.357428;// point1經度
  50. 50double mLat2 =39.90923;// point2緯度
  51. 51double mLon2 =116.397428;// point2經度
  52. 52double 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. 1MapViewTest mapView=(MapViewTest)findViewById(R.id.bmapView);
  2. 2class MapViewTest extends MapView
  3. 3{
  4. 4.       public MapViewTest(Context context)
  5. 5.       {
  6. 6.           super(context);
  7. 7.        }
  8. 8.       public MapViewTest(Context context, AttributeSet attrs)
  9. 9.       {
  10. 10.           super( context, attrs);
  11. 11.        }
  12. 12.   public MapViewTest(Context context,AttributeSet attrs,int defStyle)
  13. 13.    {
  14. 14.        super( context, attrs,defStyle);
  15. 15.     }
  16. 16.     @Override
  17. 17.     publicboolean onTouchEvent(MotionEvent event)
  18. 18.     {
  19. 19.         //獲得螢幕點選的位置
  20. 20.          int x =(int)event.getX();
  21. 21.          int y =(int)event.getY();
  22. 22.         //將畫素座標轉為地址座標
  23. 23.          GeoPoint pt =this.getProjection().fromPixels(x,y);
  24. 24.         returnsuper.onTouchEvent(event);
  25. 25.      }
  26. 26}

3.1.6 百度地圖地址解析服務Geocoder如何使用?

地址解析服務在MKSearch類中有兩個介面:reverseGeocode、geocode。 初始化搜尋類MKSearch並註冊結構監聽物件MKSearchListener:

  1. 1//初始化搜尋模組,註冊事件監聽
  2. 2mSearch=new MKSearch();
  3. 3mSearch.init(app.mBMapMan, new MySearchListener());

實現MySearchListener的onGetAddrResult獲取得到的地址資訊

  1. 1@Override
  2. 2publicvoid onGetAddrResult( MKAddrInfo res, int error ){
  3. 3.       if( error != 0){
  4. 4.           String str = String.format("錯誤號:%d",error);
  5. 5.           return;
  6. 6.         }
  7. 7.        String strInfo = String.format("緯度:%f 經度:%f 地址:%s\r\n",
  8. 8.                    res.geoPt.getlatitudeE6() / 1e6,
  9. 9.                    res.geoPt.getLongtitudeE6 / 1e6,
  10. 10.                    res.addressComponents.city +
  11. 11.                    res.addressComponents.district +
  12. 12.                    res.addressComponents.street );
  13. 13}

geocode:根據地址名稱獲取地址資訊:

  1. 1mSearch.geocode("天安門","北京");

reverseGeocode:根據地理座標點獲取地址: