1. 程式人生 > >百度地圖開發之實現運動軌跡

百度地圖開發之實現運動軌跡

近日想在android平臺下進行一個基於地理位置的APP開發,於是想到了利用百度地圖的API進行開發。於是參考了網上的一些程式碼以及相關知識的分享,現在記錄一下在百度地圖上描繪出運動軌跡的開發過程!
首先,百度地圖定位功能的一個重要的類就是 LocationClient。
此處需要注意:LocationClient類必須在主執行緒中宣告。需要Context型別的引數。
Context需要時全程序有效的context,推薦用getApplicationConext獲取全程序有效的context

public LocationClient mLocationClient = null;
public
BDLocationListener myListener = new MyLocationListener(); public void onCreate() { mLocationClient = new LocationClient(getApplicationContext()); //宣告LocationClient類 mLocationClient.registerLocationListener( myListener ); //註冊監聽函式 }

LocationClient類是定位SDK的核心類,具體方法如下: 構造類:

public LocationClient ( Context ) //須在主執行緒中宣告

設定引數:
public void setLocOption ( LocationClientOption )
引數:配置定位SDK,詳見LocationClientOption類。 說明:2.x版本以後的定位提供API介面,用以在API執行過程中,支援熱切換配置引數。

註冊監聽函式:
public void registerLocationListener ( BDLocationListener )
引數:詳見BDLocationListener類。 說明:當沒有註冊監聽函式時,無法發起網路請求。

註冊位置提醒監聽事件:
public void registerNotify ( BDNotifyListener mNotify )


開啟/關閉:
public void start();
public void stop();
start:啟動定位SDK。
stop:關閉定位SDK。呼叫stop之後,設定的引數LocationClientOption仍然保留。
發起定位:
public int requestLocation()
發起定位,非同步獲取當前位置。因為是非同步的,所以立即返回,不會引起阻塞。定位結果在ReceiveListener的方法OnReceive方法的引數中返回。
需要注意:當定位SDK從定位依據判定,位置和上一次沒發生變化,而且上一次定位結果可用時,則不會發起網路請求,而是返回上一次的定位結果。 返回值:

0:正常發起了定位。

1:服務沒有啟動。

2:沒有監聽函式。

6:請求間隔過短。 前後兩次請求定位時間間隔不能小於1000ms。

請求離線定位:

離線定位功能:使用者請求過得基站定位結果會快取在本地檔案。離線定位結果為快取結果,精度低於線上的定位結果。

離線定位結果沒有地址資訊。

public int requestOfflineLocation()

發起離線定位,非同步獲取當前位置。因為是非同步的,所以立即返回,不會引起阻塞。定位結果在ReceiveListener的方法OnReceive方法的引數中返回。

返回值:

0:正常發起了定位。

1:服務沒有啟動。

2:沒有監聽函式。

取消監聽函式:

public void unRegisterLocationListener(BDLocationListener listener)

取消監聽函式。

位置提醒相關函式:

//註冊位置提醒監聽事件
public void registerNotify(BDNotifyListener mNotify)
//取消位置提醒監聽事件
public void removeNotifyEvent(BDNotifyListener mNotify)

實現BDLocationListener介面

BDLocationListener介面有2個方法需要實現: 1.接收非同步返回的定位結果,引數是BDLocation型別引數。

public class MyLocationListener implements BDLocationListener {
    @Override
    public void onReceiveLocation(BDLocation location) {
        if (location == null)
                return ;
        StringBuffer sb = new StringBuffer(256);
        sb.append("time : ");
        sb.append(location.getTime());
        sb.append("\nerror code : ");
        sb.append(location.getLocType());
        sb.append("\nlatitude : ");
        sb.append(location.getLatitude());
        sb.append("\nlontitude : ");
        sb.append(location.getLongitude());
        sb.append("\nradius : ");
        sb.append(location.getRadius());
        if (location.getLocType() == BDLocation.TypeGpsLocation){
            sb.append("\nspeed : ");
            sb.append(location.getSpeed());
            sb.append("\nsatellite : ");
            sb.append(location.getSatelliteNumber());
        } else if (location.getLocType() == BDLocation.TypeNetWorkLocation){
            sb.append("\naddr : ");
            sb.append(location.getAddrStr());
        } 

        logMsg(sb.toString());
    }
}

BDLocation類,封裝了定位SDK的定位結果,在BDLocationListener的onReceive方法中獲取。通過該類使用者可以獲取error code,位置的座標,精度半徑等資訊。具體方法如下:

獲取error code:

public int getLocType ( )

返回值:

61 : GPS定位結果

62 : 掃描整合定位依據失敗。此時定位結果無效。

63 : 網路異常,沒有成功向伺服器發起請求。此時定位結果無效。

65 : 定位快取的結果。

66 : 離線定位結果。通過requestOfflineLocaiton呼叫時對應的返回結果

67 : 離線定位失敗。通過requestOfflineLocaiton呼叫時對應的返回結果

68 : 網路連線失敗時,查詢本地離線定位時對應的返回結果

161: 表示網路定位結果

162~167: 服務端定位失敗

502:key引數錯誤

505:key不存在或者非法

601:key服務被開發者自己禁用

602:key mcode不匹配

501~700:key驗證失敗

如果不能定位,請記住這個返回值,併到我們的hi群或者貼吧中交流。若返回值是162~167,請傳送郵件至[email protected]反饋。

獲取經緯度座標:

public double getLatitude ( ) //獲取維度
public double getLongitude ( ) //獲取經度

獲取定位的座標。座標的型別在setLocationClientOption方法中設定。

獲取定位精度:

public boolean hasRadius ( ) //判斷是否有定位精度半徑
public float getRadius ( ) //獲取定位精度半徑,單位是米

獲取文字描述的地址(反地理編碼):

public String getAddrStr ( ) //獲取反地理編碼

只有使用網路定位的情況下,才能獲取當前位置的反地理編碼描述。

自定位SDK2.6版本之後,支援獲取省/市/區分級地理資訊:

public String getProvince ( ) //獲取省份資訊
public String getCity ( ) //獲取城市資訊
public String getDistrict ( ) //獲取區縣資訊

獲取手機方向資訊:

public float getDirection()
//獲得手機方向,範圍【0-360】,手機上部正朝向北的方向為0°方向

設定定位引數

設定定位引數包括:定位模式(高精度定位模式,低功耗定位模式和僅用裝置定位模式),返回座標型別,是否開啟GPS等等。

高精度定位模式:這種定位模式下,會同時使用網路定位和GPS定位,優先返回最高精度的定位結果;

低功耗定位模式:這種定位模式下,不會使用GPS,只會使用網路定位(Wi-Fi和基站定位)

僅用裝置定位模式:這種定位模式下,不需要連線網路,只使用GPS進行定位,這種模式下不支援室內環境的定位

eg:

LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationMode.Hight_Accuracy);//設定定位模式
option.setCoorType(“bd09ll”);//返回的定位結果是百度經緯度,預設值gcj02
option.setScanSpan(5000);//設定發起定位請求的間隔時間為5000ms
option.setIsNeedAddress(true);//返回的定位結果包含地址資訊
option.setNeedDeviceDirect(true);//返回的定位結果包含手機機頭的方向
mLocClient.setLocOption(option);

LocationClientOption類,該類用來設定定位SDK的定位方式,具體方法如下:

設定定位模式:

//Hight_Accuracy高精度、Battery_Saving低功耗、Device_Sensors僅裝置(GPS)
public void setLocationMode(LocationMode mode)

設定開啟GPS:

setOpenGps( boolean )

設定是否開啟gps,使用gps前提是使用者硬體開啟gps。預設是不開啟gps的。

設定是否需要裝置方向資訊:

//在網路定位中,獲取手機機頭所指的方向
public void setNeedDeviceDirect(boolean)

設定是否需要地址資訊:

使用setIsNeedAddress(boolean)

設定是否要返回地址資訊,預設為無地址資訊。

public void setAddrType ( String )

String 值為 all時,表示返回地址資訊,其他值都表示不返回地址資訊。

設定座標型別:

設定返回值的座標型別。

public void setCoorType ( String )

我們支援返回若干種座標系,包括國測局座標系、百度座標系,需要更多座標系請聯絡我們,需要深度合作。目前這些引數的程式碼為。因此需要在請求時指定型別,如果不指定,預設返回百度座標系。注意當僅輸入IP時,不會返回座標。目前這些引數的程式碼為

返回國測局經緯度座標系 coor=gcj02

返回百度墨卡託座標系 coor=bd09

返回百度經緯度座標系 coor=bd09ll

百度手機地圖對外介面中的座標系預設是bd09ll,如果配合百度地圖產品的話,需要注意座標系對應問題。

有關座標系的更多問題,請看常見問題

設定產品線名稱:

public void setProdName ( String )

設定產品線名稱。強烈建議您使用自定義的產品線名稱,方便我們以後為您提供更高效準確的定位服務。

設定定位時間間隔:

public void setScanSpan ( int ) //設定定時定位的時間間隔。單位ms

說明:

當所設的整數值大於等於1000(ms)時,定位SDK內部使用定時定位模式。呼叫requestLocation( )後,每隔設定的時間,定位SDK就會進行一次定位。如果定位SDK根據定位依據發現位置沒有發生變化,就不會發起網路請求,返回上一次定位的結果;如果發現位置改變,就進行網路請求進行定位,得到新的定位結果。定時定位時,呼叫一次requestLocation,會定時監聽到定位結果。

當不設此項,或者所設的整數值小於1000(ms)時,採用一次定位模式。每呼叫一次requestLocation( ),定位SDK會發起一次定位。請求定位與監聽結果一一對應。

設定了定時定位後,可以熱切換成一次定位,需要重新設定時間間隔小於1000(ms)即可。locationClient物件stop後,將不再進行定位。如果設定了定時定位模式後,多次呼叫requestLocation(),則是每隔一段時間進行一次定位,同時額外的定位請求也會進行定位,但頻率不會超過1秒一次。

設定位置提醒介面:

public void registerNotify( BDNotifyListener mNotify )
LocationClient註冊位置提醒監聽事件
public void removeNotifyEvent( BDNotifyListener mNotify )
LocationClient取消位置提醒監聽事件

發起定位請求

發起定位請求。請求過程是非同步的,定位結果在上面的監聽函式onReceiveLocation中獲取。

if (mLocClient != null && mLocClient.isStarted())
mLocClient.requestLocation();
else
Log.d(“LocSDK5”, “locClient is null or not started”);

發起離線定位請求

發起離線定位請求。請求過程是非同步的,定位結果在上面的監聽函式onReceiveLocation中獲取。

getLocTypte = BDLocation.TypteOfflineLocation || BDLocation.TypeOfflineLocationFail

表示是離線定位請求返回的定位結果

if (mLocClient != null && mLocClient.isStarted())
mLocClient.requestOfflineLocation();

位置提醒使用

位置提醒最多提醒3次,3次過後將不再提醒。 假如需要再次提醒,或者要修改提醒點座標,都可通過函式SetNotifyLocation()來實現。

//位置提醒相關程式碼
mNotifyer = new NotifyLister();
mNotifyer.SetNotifyLocation(42.03249652949337,113.3129895882556,3000,”gps”);//4個引數代表要位置提醒的點的座標,具體含義依次為:緯度,經度,距離範圍,座標系型別(gcj02,gps,bd09,bd09ll)
mLocationClient.registerNotify(mNotifyer);
//註冊位置提醒監聽事件後,可以通過SetNotifyLocation 來修改位置提醒設定,修改後立刻生效。
//BDNotifyListner實現
public class NotifyLister extends BDNotifyListener{
public void onNotify(BDLocation mlocation, float distance){
mVibrator01.vibrate(1000);//振動提醒已到設定位置附近
}
}
//取消位置提醒
mLocationClient.removeNotifyEvent(mNotifyer);

使用地理圍欄服務Beta

地理圍欄服務提供的是基於位置的提醒服務,相對於SDK原來提供的位置提醒功能,地理圍欄服務通過SDK本身的內部邏輯,大幅度降低位置提醒服務的功耗情況。通過使用地理圍欄服務,第三方APP可以在低能耗的模式下輕鬆實現位置提醒服務。
初始化GeofecenClient類

此處需要注意:GeofenceClient類必須在主執行緒中宣告。需要Context型別的引數。

Context需要時全程序有效的context,推薦用getApplicationConext獲取全程序有效的context。
public GeofenceClient mGeofenceClient = null;
public void onCreate() {
mGeofenceClient = new GeofenceClient(getApplicationContext();
}

實現新增和刪除圍欄的回撥介面

新增圍欄回撥:OnAddBDGeofencesResultListener

實現如下:

public class AddGeofenceListener implements OnAddBDGeofencesResultListener {
@Override
public void onAddBDGeofencesResult(int statusCode, String geofenceRequestId) {
if (statusCode == BDLocationStatusCodes.SUCCESS) {
//圍欄建立成功
}}}

刪除圍欄回撥:OnRemoveBDGeofencesResultListener

實現如下:

public class RemoveFenceListener implements OnRemoveBDGeofencesResultListener {
@Override
public void onRemoveBDGeofencesByRequestIdsResult(int statusCode, String[] geofenceRequestIds) {
if (statusCode == BDLocationStatusCodes.SUCCESS) {
//圍欄刪除成功
}}}

實現並註冊OnGeofenceTriggerListener回撥介面

public class GeofenceEnterLister implements OnGeofenceTriggerListener {
@Override
public void onGeofenceTrigger(String geofenceRequestId) {
//進入圍欄,圍欄Id = geofenceRequestId
}
@Override
public void onGeofenceExit(String geofenceRequestId) {
//退出圍欄,圍欄Id = geofenceRequestId
}
//註冊並開啟圍欄掃描服務
mGeofenceClient .registerGeofenceTriggerListener(new GeofenceEnterLister());
mGeofenceClient.start();
}

設定圍欄引數

圍欄引數包括:id:圍欄Id、x,y:圍欄座標點經緯度、name、半徑型別(目前只支援半徑在500m以內的圍欄)、expir:圍欄的有效時間,單位毫秒(最長可以設定1個月)、coordType:座標型別(COORD_TYPE_BD09、COORD_TYPE_BD09LL、COORD_TYPE_GCJ)、

具體如下:

BDGeofence fence = new BDGeofence.Builder().setGeofenceId(id).
setCircularRegion(x, y, type)
. setExpirationDruation(expir)
. setCoordType(coordType)
.build();

發起圍欄新增和刪除請求

//新增一個圍欄:
mGeofenceClient.addBDGeofence(fence, new AddGeofenceListener());
//刪除,指定要刪除圍欄的名字列表
List fences = new ArrayList();
fences.add(fenceId);
mGeofenceClient. removeBDGeofences(fences, new RemoveFenceListener());

需要注意的問題

定位SDK必須註冊GPS和網路的使用許可權。

使用定位SDK請保證網路連線通暢(GPS定位方式不需要連網)。

我們強烈建議您設定自己的prodName,並保管好,這樣方便我們為您提供更好的定位服務。

若需要返回的定位結果裡包含地址資訊,請保證網路連線。

定位SDK可以返回bd09、bd09ll、gcj02三種類型座標,若需要將定位點的位置通過百度Android地圖 SDK進行地圖展示,請返回bd09ll,將無偏差的疊加在百度地圖上。

有的移動裝置鎖屏後為了省電會自動關閉網路連線,此時網路定位模式的定位失效。此外,鎖屏後移動裝置若進入cpu休眠,定時定位功能也失效。若您需要實現在cpu休眠狀態仍需定時定位,可以用alarmManager 實現1個cpu可叫醒的timer,定時請求定位。