轉(zhuǎn)載、引用請(qǐng)標(biāo)明出處
http://www.lxweimin.com/p/db11ae2bad4f
本文出自zhh_happig的簡書博客,謝謝
Android百度地圖(一):百度地圖定位sdk 類方法參數(shù)、定位原理詳細(xì)介紹
Android百度地圖(二):百度地圖sdk顯示位置點(diǎn)、圖層繪制
Android百度地圖(三):百度地圖畫運(yùn)動(dòng)軌跡及圖層點(diǎn)擊事件處理
Android百度地圖(四):百度地圖運(yùn)動(dòng)軌跡糾偏、去噪、綁路之百度鷹眼sdk服務(wù)
Android百度地圖(六):百度地圖POI檢索,行政區(qū)邊界、公交、線路規(guī)劃查詢,地理編碼介紹
上篇文章介紹利用百度鷹眼sdk對(duì)運(yùn)動(dòng)軌跡做糾偏、去噪、綁路處理。本篇將介紹鷹眼sdk的另一個(gè)功能——圍欄,圍欄的主要功能:將根據(jù)軌跡點(diǎn)判斷手機(jī)終端是否進(jìn)出圍欄,并實(shí)時(shí)推送報(bào)警。應(yīng)用場景:如進(jìn)入目的地提醒、監(jiān)控對(duì)象離開指定活動(dòng)范圍出發(fā)警報(bào)等等。
一 圍欄簡介
圍欄類型
圓形圍欄:進(jìn)出圓形范圍則推送報(bào)警
多邊形圍欄:進(jìn)出多邊形圍欄則推送報(bào)警
線型圍欄:偏離或回到設(shè)定路線則推送報(bào)警
行政區(qū)圍欄:傳入行政區(qū)名稱,創(chuàng)建以行政區(qū)邊界為界的圍欄,進(jìn)出報(bào)警
除圍欄形狀的區(qū)分,還分為:
(1)客戶端圍欄:圍欄的創(chuàng)建、計(jì)算和報(bào)警均在本地鷹眼SDK完成,無需聯(lián)網(wǎng)即可完成圍欄運(yùn)算,注:目前客戶端圍欄只支持圓形圍欄
(2)服務(wù)端圍欄:圍欄的創(chuàng)建、計(jì)算和報(bào)警的發(fā)起都在服務(wù)端完成,依賴于軌跡點(diǎn)上傳至服務(wù)端才能進(jìn)行圍欄進(jìn)算。
創(chuàng)建圓形圍欄和多邊形圍欄在地圖上顯示的效果如下
二 創(chuàng)建圍欄api詳解
1.流程圖
2.初始化客戶端采集軌跡數(shù)據(jù)
請(qǐng)先申請(qǐng)apikey和serviceId,具體工程配置請(qǐng)見篇頭百度地圖(四)文章中描述
//以下都是偽代碼
/**
* 初始化鷹眼sdk客戶端,
*/
LBSTraceClient mClient = mClient = new LBSTraceClient(mContext);
//初始化鷹眼服務(wù)端,serviceId:服務(wù)端唯一id,entityName:監(jiān)控的對(duì)象,可以是手機(jī)設(shè)備唯一標(biāo)識(shí)
Trace mTrace = new Trace(serviceId, entityName);
mClient.startTrace(trackApp.mTrace, traceListener);//開始服務(wù)
trackApp.mClient.startGather(traceListener);//開啟采集
//軌跡服務(wù)監(jiān)聽器
private OnTraceListener traceListener = new OnTraceListener() {
/**
* 推送消息回調(diào)接口
* @param messageType 狀態(tài)碼
* 0x01:配置下發(fā),0x02:語音消息,0x03:服務(wù)端圍欄報(bào)警消息,0x04:本地圍欄報(bào)警消息
*/
@Override
public void onPushCallback(byte messageType, PushMessage pushMessage) {
if (messageType < 0x03 || messageType > 0x04) {
return;
}
/**
* 獲取報(bào)警推送消息
*/
FenceAlarmPushInfo alarmPushInfo = pushMessage.getFenceAlarmPushInfo();
alarmPushInfo.getFenceId();//獲取圍欄id
alarmPushInfo.getMonitoredPerson();//獲取監(jiān)控對(duì)象標(biāo)識(shí)
alarmPushInfo.getFenceName();//獲取圍欄名稱
alarmPushInfo.getPrePoint();//獲取上一個(gè)點(diǎn)經(jīng)度信息
AlarmPoint alarmPoin = alarmPushInfo.getCurrentPoint();//獲取報(bào)警點(diǎn)經(jīng)緯度等信息
alarmPoin.getCreateTime();//獲取此位置上傳到服務(wù)端時(shí)間
alarmPoin.getLocTime();//獲取定位產(chǎn)生的原始時(shí)間
if(alarmPushInfo.getMonitoredAction() == MonitoredAction.enter){//動(dòng)作類型
//進(jìn)入圍欄
}else if(alarmPushInfo.getMonitoredAction() == MonitoredAction.exit){
//離開圍欄
}
}
//......這里省略此接口的其他方法
};
更多軌跡采集api詳解請(qǐng)閱讀篇頭百度地圖(四)文章
3.創(chuàng)建圍欄
/**
* 創(chuàng)建客戶端圓形圍欄,注:目前客戶端圍欄只支持圓形圍欄
* tag - 這次請(qǐng)求的唯一標(biāo)識(shí)
* serviceId -軌跡服務(wù)ID
* fenceName - 圍欄名稱
* entityName- 監(jiān)控對(duì)象唯一標(biāo)識(shí),如果是手機(jī),請(qǐng)用手機(jī)的唯一id
* center - 圍欄圓心
* radius - 圍欄半徑
* denoise - 圍欄去噪精度,gps定位和網(wǎng)絡(luò)定位都存在精度誤差,會(huì)造成圍欄誤報(bào)警;
如設(shè)置denoise=30,則定位精度大于30米的軌跡點(diǎn)都不會(huì)參與圍欄計(jì)算。
平均精度參考:GPS定位精度均值為15米,WIFI定位精度均值為40米,基站定位精度均值為300米。
* coordType - 坐標(biāo)類型
*/
CreateFenceRequest request = CreateFenceRequest.buildLocalCircleRequest(tag, serviceId, fenceName,
entityName, circleCenter, radius, denoise, CoordType.bd09ll);
/**
* 創(chuàng)建服務(wù)端圓形圍欄
* 參數(shù)與客戶端圓形圍欄一樣
*/
request = CreateFenceRequest.buildServerCircleRequest(tag, serviceId, fenceName,
entityName, circleCenter, radius, denoise, CoordType.bd09ll);
/**
* 創(chuàng)建服務(wù)端多邊形圍欄
* vertexes - 頂點(diǎn)坐標(biāo)集合,List<com.baidu.trace.model.LatLng>
* 頂點(diǎn)可設(shè)置地圖點(diǎn)擊監(jiān)聽獲取,mBaiduMap.setOnMapClickListener
*/
request = CreateFenceRequest.buildServerPolygonRequest(tag,serviceId, fenceName,
entityName, vertexes, denoise, CoordType.bd09ll);
/**
* 創(chuàng)建服務(wù)端線形圍欄
* vertexes - 頂點(diǎn)坐標(biāo)集合,List<com.baidu.trace.model.LatLng>
* offset - 偏離路線的垂直距離,偏離大于offset 報(bào)警
*/
request = CreateFenceRequest.buildServerPolylineRequest(tag,serviceId, fenceName,
entityName, vertexes, offset, denoise, CoordType.bd09ll);
/**
* 創(chuàng)建服務(wù)端行政區(qū)圍欄
* district:行政區(qū)名稱,注意寫全,如北京市西城區(qū)
*/
request = CreateFenceRequest.buildServerDistrictRequest(tag,serviceId, fenceName, entityName,
district, denoise);
//發(fā)起創(chuàng)建圍欄請(qǐng)求
mClient.createFence(request, fenceListener);
4.圍欄操作的監(jiān)聽器
OnFenceListener fenceListener = new OnFenceListener() {
@Override
public void onCreateFenceCallback(CreateFenceResponse response) {
//創(chuàng)建圍欄響應(yīng)結(jié)果,能獲取圍欄的一些信息
if(StatusCodes.SUCCESS != response.getStatus()){
return;
}
response.getTag();//請(qǐng)求標(biāo)識(shí)
response.getDistrict();//獲取行政區(qū)名稱
response.getFenceId();//創(chuàng)建的圍欄id
response.getFenceShape();//圍欄形狀
response.getFenceType();//圍欄類型(本地圍欄、服務(wù)端圍欄)
//...方法不一一列舉了,比較簡單
}
@Override
public void onUpdateFenceCallback(UpdateFenceResponse response) {
//更新圍欄響應(yīng)結(jié)果
//...
}
@Override
public void onDeleteFenceCallback(DeleteFenceResponse response) {
//刪除圍欄響應(yīng)結(jié)果
response.getFenceIds();//獲取刪除的圍欄id
//...
}
@Override
public void onFenceListCallback(FenceListResponse response) {
//獲取圍欄列表響應(yīng)結(jié)果
response.getSize();//圍欄個(gè)數(shù)
List<FenceInfo> fenceInfos = response.getFenceInfos();//獲取圍欄信息列表
for (FenceInfo fenceInfo : fenceInfos) {
switch (fenceInfo.getFenceShape()) {//判斷圍欄形狀
case circle://圓形
CircleFence circleFence = fenceInfo.getCircleFence();
circleFence.getFenceId();
circleFence.getCenter();
circleFence.getRadius();
circleFence.getDenoise();//去噪精度
circleFence.getMonitoredPerson();//監(jiān)控設(shè)備的唯一標(biāo)識(shí)
//...獲取圓心和半徑就可以在地圖上畫圓形圖層
break;
case polygon://多邊形
PolygonFence polygonFence = fenceInfo.getPolygonFence();
//獲取多邊形頂點(diǎn)集合
List<com.baidu.trace.model.LatLng> polygonVertexes = polygonFence.getVertexes();
//...獲取頂點(diǎn)坐標(biāo)可以在地圖上畫多邊形圖層
break;
case polyline://線形
PolylineFence polylineFence = fenceInfo.getPolylineFence();
//獲取線形頂點(diǎn)集合
List<com.baidu.trace.model.LatLng> polylineVertexes = polylineFence.getVertexes();
//...
break;
case district:
DistrictFence districtFence = fenceInfo.getDistrictFence();
districtFence.getDistrict();//獲取行政區(qū)名稱
//...注:行政區(qū)圍欄并能像多邊形一樣返回定點(diǎn)集合,行政區(qū)范圍很大,點(diǎn)很多...,
//如果想獲取行政區(qū)的邊界點(diǎn)坐標(biāo)結(jié)合,請(qǐng)使用baidumapapi_search_v4_3_1.jar中DistrictSearch類
break;
}
}
}
@Override
public void onMonitoredStatusCallback(MonitoredStatusResponse response) {
//查詢監(jiān)控對(duì)象狀態(tài)響應(yīng)結(jié)果
List<MonitoredStatusInfo> monitoredStatusInfos = response.getMonitoredStatusInfos();
for (MonitoredStatusInfo monitoredStatusInfo : monitoredStatusInfos){
monitoredStatusInfo.getFenceId();
MonitoredStatus status = monitoredStatusInfo.getMonitoredStatus();//獲取狀態(tài)
switch (status){
case in:
//監(jiān)控的設(shè)備在圍欄內(nèi)
break;
case out:
//監(jiān)控的設(shè)備在圍欄外
break;
case unknown:
//監(jiān)控的設(shè)備狀態(tài)未知
break;
}
}
}
@Override
public void onMonitoredStatusByLocationCallback(MonitoredStatusByLocationResponse response){
//查詢監(jiān)控對(duì)象在指定位置的狀態(tài)響應(yīng)結(jié)果,api同onMonitoredStatusCallback
}
@Override
public void onHistoryAlarmCallback(HistoryAlarmResponse response) {
//查詢圍欄歷史報(bào)警信息響應(yīng)結(jié)果
//獲取報(bào)警信息列表,F(xiàn)enceAlarmInfo繼承FenceAlarmPushInfo
List<FenceAlarmInfo> fenceAlarmInfos = response.getFenceAlarmInfos();
}
};
創(chuàng)建圍欄成功后,服務(wù)端時(shí)刻計(jì)算最新采集的軌跡點(diǎn)與圍欄的地理關(guān)系,一旦進(jìn)出圍欄報(bào)警信息會(huì)通過OnTraceListener.onPushCallback方法回到給客戶端,你可以在這里進(jìn)行自己的業(yè)務(wù)了。
判斷軌跡點(diǎn)進(jìn)入圍欄、離開圍欄,推送報(bào)警效果如下
如果你沒有在地圖上畫圖層的需求,完全不必像圖a、圖b那樣,只需要?jiǎng)?chuàng)建圍欄,開啟采集數(shù)據(jù),等待報(bào)警信息的回調(diào)就可以了。
三 圍欄查詢、刪除等api詳解
以下api方法中的參數(shù)詳見3中描述,基本一樣;圍欄監(jiān)聽器同用一個(gè)fenceListener,參見4中描述。
5.更新圍欄
/**
* 以更新服務(wù)端圓形圍欄為例,其他圍欄同理
* fenceId:圍欄id
* 更新圍欄傳入新的參數(shù)即可,如圓形圍欄傳入新的半徑和圓心坐標(biāo)
*/
UpdateFenceRequest updateRequest = UpdateFenceRequest.buildServerCircleRequest(tag, serviceId, fenceId,
fenceName, entityName, center, radius, denoise, coordType);
//發(fā)起更新圍欄請(qǐng)求
mClient.updateFence(updateRequest , fenceListener);
6.刪除圍欄
/**
* 以刪除服務(wù)端圍欄為例
* deleteFenceIds:要?jiǎng)h除的服務(wù)端圍欄編號(hào)列表,List<Long>
*/
DeleteFenceRequest deleteRequest = DeleteFenceRequest.buildServerRequest(tag,serviceId, entityName, deleteFenceIds);
//發(fā)起刪除圍欄請(qǐng)求
mClient.deleteFence(deleteRequest , fenceListener);
7.查詢圍欄列表
/**
* 以查詢服務(wù)端圍欄為例
* fenceIds:服務(wù)端圍欄編號(hào)列表,List<Long>,如傳入null,表示查詢所有圍欄
*/
FenceListRequest request = FenceListRequest.buildServerRequest(tag,serviceId, entityName, fenceIds,CoordType.bd09ll);
//發(fā)起查詢圍欄請(qǐng)求
mClient.queryFenceList(request, fenceListener);
8.查詢指定監(jiān)控對(duì)象狀態(tài)
/**
* 查詢監(jiān)控對(duì)象是否在圍欄內(nèi),以查詢服務(wù)端為例
* fenceIds:服務(wù)端圍欄編號(hào)列表,List<Long>
* entityName:監(jiān)控對(duì)象標(biāo)識(shí)
*/
MonitoredStatusRequest request = MonitoredStatusRequest.buildServerRequest(tag, serviceId,entityName, fenceIds);
//發(fā)起查詢請(qǐng)求
mClient.queryMonitoredStatus(request, fenceListener);
9.查詢指定監(jiān)控對(duì)象在指定位置的狀態(tài)
/**
* 查詢監(jiān)控對(duì)象在指定位置是否在圍欄內(nèi),以查詢服務(wù)端為例
* latLng:位置點(diǎn)
*/
MonitoredStatusByLocationRequest request = MonitoredStatusByLocationRequest .buildServerRequest(tag, serviceId,
entityName, fenceIds, latLng, coordType);
//發(fā)起查詢請(qǐng)求
mClient.queryMonitoredStatusByLocation(request, fenceListener);
10.查詢圍欄歷史報(bào)警信息
/**
* 以查詢服務(wù)端為例
* startTime:開始時(shí)間
* endTime:結(jié)束時(shí)間
*/
HistoryAlarmRequest request = HistoryAlarmRequest.buildServerRequest(tag, serviceId, startTime,
endTime, entityName, fenceIds, coordType)
//發(fā)起查詢請(qǐng)求
mClient.queryFenceHistoryAlarmInfo(request, fenceListener);
好啦,到此,百度鷹眼sdk圍欄部分就講完了。
如果各位看官覺得文章不錯(cuò),別忘了點(diǎn)個(gè)喜歡。
源碼下載地址
以上文章內(nèi)容,是本人工作中的總結(jié),供大家參考,有誤的地方還請(qǐng)指正。