上一篇文章介绍了地图画轨迹的基本原理和实现。不难发现,当位置处于建筑物密集区、桥梁、高架桥下,gps信号较差时,画出来的轨迹效果会比较差。即使是在空旷地带,也难免会出现gps漂移的情况而造成轨迹的偏差。这时就需要我们对位置点进行纠偏、去噪、抽稀、绑路操作。百度鹰眼sdk则提供了相应的api,本篇文章将介绍如何使用百度鹰眼sdk画出效果相对较好的轨迹。

先来看看效果图
1.百度地图(三)文章中demo取得原始位置点画出来的轨迹图:

原始位置轨迹图a

可以发现轨迹大致能反应用户所经过的路劲,效果还是不错的,说明gps信号较好,精度较高。但是除了西边的轨迹较为平滑之外,其他方位的轨迹都出现了锯齿形状,原因是gps位置有一定精度差,所以不一定会准确的定位到所行走的路劲上。如果运动范围较大(需缩小地图显示整个轨迹,轨迹将在视觉上变得平滑),而且轨迹精度要求不高,能确定用户在户外,个人觉得图a就能满足要求了

2.使用百度鹰眼sdk处理后的轨迹图:

经处理后的轨迹图

可以发现经处理的轨迹已经没有锯齿形状了,位置都落到了路劲上,这就是我们想要的效果。如果无法确定用户gps信号的优良,可能会进行网络定位,并且轨迹的精度要求很高,那么位置必须通过百度鹰眼sdk处理后再画出运动轨迹,这样才能达到图b的效果。

下面将介绍如何使用百度鹰眼sdk画出效果相对较好的轨迹,包括驾车、骑行、步行。

一 配置工程

1.申请apikey
2.创建鹰眼轨迹服务空间并获取 service_id
3.在Application标签中声明SERVICE组件,每个APP拥有自己独立的鹰眼追踪service


<serviceandroid:name="com.baidu.trace.LBSTraceService"android:enabled="true"android:exported="true"android:process=":remote" />

二 百度鹰眼sdk关键api介绍

1.轨迹数据处理流程图

流程图

2.初始化


//以下都是伪代码
/**
*  轨迹服务:通过serviceId对应服务端,用于存储、访问和管理自己的终端和轨迹serviceId:轨迹服务id,这就是配置工程申请的service_identityName:设备标识isNeedObjectStorage:是否需要对象存储服务,比如在某个点存一个图层图片,显示这里有超速摄像头,获取轨迹的时候,也可以获取这个图层图片显示在轨迹的相应位置上.这里默认为:一般为false,关闭对象存储服务。注:鹰眼 Android SDK v3.0以上版本支持随轨迹上传图像等对象数据,若需使用此功能,该参数需设为 true,且需导入bos-android-sdk-1.0.2.jar。
*/
Trace mTrace = new Trace(serviceId, entityName,isNeedObjectStorage);/**
*  轨迹客户端LBSTraceClient,主要功能:(1)内部封装了百度定位sdk的api,采集定位位置点,定位sdk不清楚的可以篇头阅读百度文章(一)(2)将采集数据打包发给服务端(3)请求服务端,查询经过处理的轨迹、位置等信息
*/
LBSTraceClient mClient = new LBSTraceClient(mContext);

3.定位当前位置显示在地图上


//定位请求参数类
LocRequest locRequest = new LocRequest(serviceId);
//时时定位设备当前位置,定位信息不会存储在轨迹服务端,即不会形成轨迹信息,只用于在MapView显示当前位置
mClient.queryRealTimeLoc(locRequest, entityListener);//这里只会一次定位,多次定位使Handler.postDelayed(Runnable, interval)实现;//Entity监听器(用于接收实时定位回调)
private OnEntityListener entityListener = new OnEntityListener() {@Overridepublic void onReceiveLocation(TraceLocation location) {//将回调的当前位置location显示在地图MapView上,地图显示位置不清楚的可以篇头阅读百度文章(二)//这里位置点的返回间隔时间为Handler.postDelayed的延时时间}
};/**
* 当轨迹服务开启,且采集数据开启之后,显示在地图上的位置点可以用服务端纠偏后的最新点,因为通过mClient.queryRealTimeLoc获取的点可能不精确,出现漂移等情况。
*/
//查询服务端纠偏后的最新轨迹点请求参数类
LatestPointRequest request = new LatestPointRequest(getTag(), serviceId, entityName);
ProcessOption processOption = new ProcessOption();//纠偏选项
processOption.setRadiusThreshold(50);//设置精度过滤,0为不需要;精度大于50米的位置点过滤掉
processOption.setTransportMode(TransportMode.walking);
processOption.setNeedDenoise(true);//去噪处理
processOption.setNeedMapMatch(true);//绑路处理
request.setProcessOption(processOption);//设置参数
mClient.queryLatestPoint(request, trackListener);//请求纠偏后的最新点//轨迹监听器(用于接收纠偏后实时位置回调)
private OnTrackListener trackListener = new OnTrackListener() {@Overridepublic void onLatestPointCallback(LatestPointResponse response) {//将纠偏后实时位置显示在地图MapView上//这里位置点的返回间隔时间为数据打包上传的频率;数据发送到服务端,才会更新最新的纠偏位置}
};

4.开启服务,开始采集数据


//设置定位模式
mClient.setLocationMode(LocationMode.High_Accuracy);/**
* 设置采集频率:这里的采集频率指的是轨迹数据的采集频率,和上面显示当前位置的定位频率要区分开
* 打包上传频率:mClient每隔packInterval时间会自动打包上传
*/
mClient.setInterval(gatherInterval, packInterval);/**
* 开启轨迹服务
*/
mClient.startTrace(mTrace, traceListener);
//开启位置点采集
mClient.startGather(traceListener);
startTime = System.currentTimeMillis()/1000;//记录开始采集时间//轨迹服务监听器
private OnTraceListener traceListener = new OnTraceListener() {/*** 绑定com.baidu.trace.LBSTraceService服务回调接口* @param errorNo  状态码,0:成功,1:失败* @param message 消息*/@Overridepublic void onBindServiceCallback(int errorNo, String message) {}/*** 开启服务回调接口* @param errorNo 状态码* 0:成功,10000:请求发送失败,10001:服务开启失败,10002:参数错误,10003:网络连接失败10004:网络未开启,10005:服务正在开启,10006:服务已开启* @param message 消息*/@Overridepublic void onStartTraceCallback(int errorNo, String message) {}/*** 停止服务回调接口* @param errorNo 状态码* 0:成功,11000:请求发送失败,11001:服务停止失败,11002:服务未开启,11003:服务正在停止* @param message 消息*/@Overridepublic void onStopTraceCallback(int errorNo, String message) {}/*** 开启采集回调接口* @param errorNo 状态码* 0:成功,12000:请求发送失败,12001:采集开启失败,12002:服务未开启* @param message 消息             */@Overridepublic void onStartGatherCallback(int errorNo, String message) {}/*** 停止采集回调接口* @param errorNo 状态码* 0:成功,13000:请求发送失败,13001:采集停止失败,13002:服务未开启* @param message 消息              */@Overridepublic void onStopGatherCallback(int errorNo, String message) {}/*** 推送消息回调接口* @param messageType 状态码* 0x01:配置下发,0x02:语音消息,0x03:服务端围栏报警消息,0x04:本地围栏报警消息,0x05~0x40:系统预留,0x41~0xFF* @param pushMessage 消息            */@Overridepublic void onPushCallback(byte messageType, PushMessage pushMessage) {//这个回调其实是比较重要的,本篇主要讲的是画轨迹,所以就不详细讲了/*** 那么这里能实现什么功能呢,我想到的两个例子* 1.到达目的地提示用户,在目的地画个圈,进入提醒实现:CreateFenceRequest创建围栏:圆形围栏、多边形围栏、线型围栏、行政区围栏,一旦进出则推送报警,pushMessage.getFenceAlarmPushInfo().getMonitoredAction()可以知道进或出,MonitoredAction.enter:进围栏,MonitoredAction.exit:出围栏* 2.用户出一定区域发出提醒,在当前位置地画个圈,出去了则提醒*  比如孩子在小区玩,拿着手机和小伙伴在树底下玩王者农药,我们为了孩子的安全,只允许他在小区范围内活动,一旦离开了小区的范围就给大人发个短信什么的,哈哈*/}
};

5.停止服务,停止采集数据


mClient.stopGather(traceListener);
endTime = System.currentTimeMillis()/1000;//记录停止采集时间
mClient.stopTrace(mTrace, traceListener);

6.请求服务端处理后的位置数据


/*** 历史轨迹请求类*/
HistoryTrackRequest historyTrackRequest = new HistoryTrackRequest();
ProcessOption processOption = new ProcessOption();//纠偏选项
processOption.setRadiusThreshold(50);//精度过滤
processOption.setTransportMode(TransportMode.walking);//交通方式,默认为驾车
processOption.setNeedDenoise(true);//去噪处理,默认为false,不处理
processOption.setNeedVacuate(true);//设置抽稀,仅在查询历史轨迹时有效,默认需要false
processOption.setNeedMapMatch(true);//绑路处理,将点移到路径上,默认不需要false
historyTrackRequest.setProcessOption(processOption);/**
* 设置里程补偿方式,当轨迹中断5分钟以上,会被认为是一段中断轨迹,默认不补充
* 比如某些原因造成两点之间的距离过大,相距100米,那么在这两点之间的轨迹如何补偿SupplementMode.driving:补偿轨迹为两点之间最短驾车路线SupplementMode.riding:补偿轨迹为两点之间最短骑车路线SupplementMode.walking:补偿轨迹为两点之间最短步行路线SupplementMode.straight:补偿轨迹为两点之间直线
*/
historyTrackRequest.setSupplementMode(SupplementMode.no_supplement);
historyTrackRequest.setSortType(SortType.asc);//设置返回结果的排序规则,默认升序排序;升序:集合中index=0代表起始点;降序:结合中index=0代表终点。
historyTrackRequest.setCoordTypeOutput(CoordType.bd09ll);//设置返回结果的坐标类型,默认为百度经纬度/**
*设置是否返回纠偏后轨迹,默认不纠偏true:打开轨迹纠偏,返回纠偏后轨迹;false:关闭轨迹纠偏,返回原始轨迹。打开纠偏时,请求时间段内轨迹点数量不能超过2万,否则将返回错误。
*/
historyTrackRequest.setProcessed(true);//请求历史轨迹
((BaseRequest)historyTrackRequest).setTag(tag);//设置请求标识,用于唯一标记本次请求,在响应结果中会返回该标识
historyTrackRequest.setServiceId(serviceId);//设置轨迹服务id,Trace中的id
historyTrackRequest.setEntityName(entityName);//Trace中的entityName/**
* 设置startTime和endTime,会请求这段时间内的轨迹数据;
* 这里查询采集开始到采集结束之间的轨迹数据
*/
historyTrackRequest.setStartTime(startTime);
historyTrackRequest.setEndTime(endTime);mClient.queryHistoryTrack(historyTrackRequest, mTrackListener);//发起请求,设置回调监听

7.历史轨迹数据回调
注:当我们记录采集的起始时间,然后在查询这段时间内的点,画在地图上,可以实现用户运动结束后,一次性画出整个运动轨迹的功能


//伪代码private List<LatLng> trackPoints = new ArrayList<>();//轨迹点集合/**
* 轨迹监听器(用于接收历史轨迹回调)
*/
private OnTrackListener mTrackListener = new OnTrackListener() {@Overridepublic void onHistoryTrackCallback(HistoryTrackResponse response) {//如果觉得轨迹点可能过多,可以多次分页查询,详细代码参见源码List<TrackPoint> points = response.getTrackPoints();//获取轨迹点for (TrackPoint trackPoint : points) {//将轨迹点转化为地图画图层的LatLng类trackPoints.add(MapUtil.convertTrace2Map(trackPoint.getLocation()));}//MapUtil封装了百度地图MapView和BaidumMap中的一些apimapUtil.drawHistoryTrack(trackPoints, sortType);//将轨迹点画在地图上,对百度地图画图层不清楚的可以阅读偏头百度地图(三)文章}};

8.里程计算


DistanceRequest distanceRequest = new DistanceRequest(tag, serviceId, entityName);
distanceRequest.setStartTime(startTime);// 设置开始时间
distanceRequest.setEndTime(endTime);// 设置结束时间
distanceRequest.setProcessed(true);// 纠偏
ProcessOption processOption = new ProcessOption();// 创建纠偏选项实例
processOption.setNeedDenoise(true);// 去噪
processOption.setNeedMapMatch(true);// 绑路
processOption.setTransportMode(TransportMode.walking);// 交通方式为步行
distanceRequest.setProcessOption(processOption);// 设置纠偏选项
distanceRequest.setSupplementMode(SupplementMode.no_supplement);// 里程填充方式为无
mTraceClient.queryDistance(distanceRequest, mTrackListener);// 查询里程// 初始化轨迹监听器
OnTrackListener mTrackListener = new OnTrackListener() {// 里程回调@Overridepublic void onDistanceCallback(DistanceResponse response) {double distance = response.getDistance()//里程,单位:米double speed = distance/(endTime-startTime);//速度:m/s}
};

三 动态时时画运动轨迹


//伪代码
/**
* 使用LatestPointRequest实现:查询服务端纠偏后的最新的点,在3中已经介绍了
* onLatestPointCallback此回调方法不仅可以画出当前的位置点,还可以将每一个最新纠偏后的点加入到位置点集合中,每返回一个点,就刷新一次轨迹图,这样就能动态画出轨迹了。
*///接收纠偏后最新位置回调
private OnTrackListener trackListener = new OnTrackListener() {@Overridepublic void onLatestPointCallback(LatestPointResponse response) {//位置点的返回间隔时间为数据打包上传的频率 LatestPoint point = response.getLatestPoint();LatLng currentLatLng = mapUtil.convertTrace2Map(point.getLocation());trackPoints.add(currentLatLng);mapUtil.drawHistoryTrack(trackPoints,false,mCurrentDirection);//显示当前位置,并时时动态的画出运动轨迹}
};

动态轨迹效果图

效果图

Android百度地图(四):百度地图运动轨迹纠偏、去噪、绑路之百度鹰眼相关推荐

  1. baidumaptrace.php,GitHub - SignalLine/BaiduMapTrace: 百度地图运动轨迹纠偏、去噪、绑路之百度鹰眼sdk服务...

    BaiduMapTrace 百度地图运动轨迹纠偏.去噪.绑路之百度鹰眼sdk服务 轨迹大致能反应用户所经过的路劲,效果还是不错的,说明gps信号较好,精度较高. 但是除了西边的轨迹较为平滑之外,其他方 ...

  2. 百度地图开发之实现运动轨迹 一

    近日想在Android平台下进行一个基于地理位置的APP开发,于是想到了利用百度地图的API进行开发.于是参考了网上的一些代码以及相关知识的分享,现在记录一下在百度地图上描绘出运动轨迹的开发过程! 首 ...

  3. 百度地图开发之实现运动轨迹 二

    上篇日志有介绍到开发百度地图的几个重要的类还有方法,现在就来实现在百度地图上描绘出运动轨迹,具体步骤如下: 一,在布局文件里声明百度地图的视图 二,在用百度地图时,先要将地图初始化: // 地图初始化 ...

  4. (百度、谷歌)地图经纬度gps偏移解决办法:gps纠偏数据库纠偏

    使用方法: 1.假设原始gps数据为(73.528888,39.368888) 2.查询数据库:SELECT * FROM offset where lng=73.52 and lat=39.36,得 ...

  5. android应用控制百度地图,Android中应用百度地图API开发地图APP实例-显示百度地图...

    场景 效果 在使用百度地图API之前需要先在百度地图开放平台中申请API_KEY 申请API_KEY 登录百度开放平台后找到控制台下的应用管理-创建应用 依次输入应用名,应用类型选择Android S ...

  6. Android app调用第三方地图(百度地图,高德地图,谷歌地图)导航

    因为公司项目需要用到外部导航,找到一些,大兄弟们凑合看...好吧反正也没人看- - 1.调用百度导航 //开启百度导航public void startNavi() {//百度地图,从起点是LatLn ...

  7. android 高德卫星地图数据,白马地图 Bmap for Android v7.3.81 强大高德百度地图应用|张小北...

    Bmap for Android 是一款集成高德地图百度地图为一体的第三方地图应用APP,Bmap for Android 又叫白马地图,采用高德/百度地图数据引擎,可任意切换百度地图.高德地图数据源 ...

  8. Android 地图导航调用百度地图、高德地图、腾讯地图,腾讯T3团队整理

    前言 ============================================================= 为什么调用第三方呢?集成在App里面不行吗? 接入导航SDK,以百度为 ...

  9. Android调用跳转百度地图、高德地图、腾讯地图进行目的地导航

    Android App跳转百度地图.高德地图.腾讯地图进行目的地导航. 先放上百度.高德.腾讯地图调起API文档地址,有些参数不懂可以参考. 百度地图:http://lbsyun.baidu.com/ ...

最新文章

  1. 机器学习里如何确定K-Means算法的K值?
  2. Leetcode 剑指 Offer 13. 机器人的运动范围 (每日一题 20210906)
  3. vs配置不依赖其他包路径
  4. 6.组函数(avg(),sum(),max(),min(),count())、多行函数,分组数据(group by,求各部门的平均工资),分组过滤(having和where),sql优化...
  5. Linux通过第三方应用提权实战总结
  6. material 项目_Web开发必备的 10 个开源项目,不用自己亲自造轮子!
  7. 爬虫结果数据完整性校验
  8. C#LeetCode刷题-位运算
  9. python花瓣长度和花瓣宽度散点图鸢尾花_Python可视化seaborn练习题
  10. 尼尔机械纪元 机器人博士_还记得章鱼博士吊打蜘蛛侠的炫酷机械臂吗?现实版已经研发出来了...
  11. 杭电acm阶段之理工大版
  12. Convolutional Neural Networks (CNNs / ConvNets)
  13. vb语言中怎样编码窗体中所有字体加粗_vb文本框字体加粗 vb字体加粗代码
  14. matlab里impz指令格式,华北电力大学Matla实验指导书.doc
  15. 编译原理(八)消除空产生式
  16. 出现Head https://registry-1.docker.io/v2/library/node/manifests/14-alpine的解决方法
  17. 人工智能欠缺对语言和情感的理解和处理能力
  18. 使用阿里云ECS服务器搭建java环境
  19. python opengl 教程_OpenGL新手和弃用
  20. 百度大脑的燎原之势:强大成标配,更深得企业拥抱AI之心

热门文章

  1. m73p黑苹果_M93P一次性拔草小主机,黑苹果,软路由。
  2. GitHub下载 无法分配请求的地址_Hexo+Github--搭建个人博客(一)准备工作amp;amp;环境搭建
  3. Redis 根据value 进行查询
  4. 零基础开发WIFI设备(esp8266)
  5. Spring Boot(三):RestTemplate提交表单数据的三种方法
  6. Android开发 mobi格式,Android MobIM的免费使用方法
  7. 如何用手机播放电脑的声音
  8. cannot find -lxxx 问题的总结
  9. logTracker错误日志跟踪组件(二)
  10. elasticsearch从入门到入门系列(二)---快速入门B