轨迹记录是现在交通运输发展的今天必不可少的一项技术,从卫星上天得那一刻,运输管控等TMS类似就注定诞生!
百度知道告诉我们GPS定位不准原因: https://jingyan.baidu.com/article/48a42057084f9fa9242504de.html
以下是一个GPS误差引入简表:
l 卫星时钟误差:0-1.5米
l 卫星轨道误差:1-5米
l 电离层引入的误差:0-30米
l 大气层引入的误差:0-30米
l 接收机本身的噪音:0-10米
l 多路反射:0-1米
l 总定位误差:大约28米
什么是GPS的漂移?
用过GPS的人大概都有这种体会:当GPS终端静止的时候,其定位坐标(经纬度)经常在变,偶尔变化还比较大,甚至还会显示有速度。业内人士把这种现象称为“漂移”。
其实,GPS漂移不仅在静止的时候会产生,动态的时候也会产生,只不过漂移的程度没那么明显,产生的几率小些罢了,这是GPS的一个基本特性。(至于GPS为什么会产生漂移,了解GPS的定位原理就不难解释,在此不再详述。)
GPS漂移是GPS应用时需要处理的问题之一,漂移主要有两个方面,
第一, 速度过快,以至于GPS的响应时间短于当前运行速度,出现漂移;
第二, 在高大建筑密集或天气情况不好的地方,因为GPS信号经过多次的折、反射,造成信号误差,出现漂移。
GPS漂移的两种表现:静态位置漂移、速度(位置)漂移
以上,是对GPS相关知识的一个简单说明, 在实际开发过程中,我真实遇见了这个严峻的问题, 先后用 GPS全量收集,GPS点速度过滤,距离过滤,以及高德地图的LBS服务等, 进行了一系列对比,想到一种可行的方案:
1. 网络+GPS定位 , 通过距离对当前状态分为两种: 静止状态/移动状态.
网络定位的特点是: 相对高精度(8星10米内)的GPS定位误差偏大,没有速度/角度等( 可以使用手机传感器,但是人在原地转圈也存在高速和角度变化大问题), 但是不需要GPS信号,通过地址与前后三点平均距离对其进行二次过滤
2. 进入静止状态的条件是 : 连续多点距离变化小
进入移动状态的条件:当前处于静止状态切有多次距离较大改变量变化
3. 静止状态下, 大变化的点轨迹记录次数不处理 ,移动状态同理 , 这样是为了避免 飘逸,
因为静态飘逸数据特点: 例如,多次连续小范围内的距离在5m以内,突然存在一两次100m甚至500m的轨迹点出现(观察中, 高德API 无论GPS还是网络都存在, 特别是人在电梯内 变化尤为明显)
针对以上想法的实现效果图:
其中:
黑色-记录的原轨迹点
红色-对原轨迹点进行抽稀平滑道路纠正
蓝色及黄色-高德LBS服务
图1 - 行驶轨迹 走路+公交+地铁
部分代码片段:
private AMapLocation prev;
@Override
public boolean intercept(AMapLocation location) {
if (prev!=null){
LatLng s = new LatLng(prev.getLatitude(), prev.getLatitude());
LatLng d = new LatLng(location.getLatitude(), location.getLatitude());
float distance = AMapUtils.calculateLineDistance(s,d);//距离改变量,单位米
LLog.print("距离改变量: "+ distance+" 米");
if (distance < intervalMin ) {
// LLog.print("距离改变量过小: "+ distance+" 米");
if (distance<3) {
if (!staticFlag){
count++; //收集连续多次的距离改变量
if (count==10){
staticFlag = true;
count=0;
LLog.print("进入静止状态");
}
} else {
// LLog.print("当前处于静止");
if (count>0) count--;
}
}
//如果连续10次距离改变量==0 认为处于静止状态, 解除静止状态的条件: 连续3次大的距离改变
return true;
}
if (staticFlag) {
count++;
if (count==3){
staticFlag = false;
count = 0;
LLog.print("进入移动状态");
}
}else{
// LLog.print("当前移动正常");
if (count>0) count--;
}
if (distance < intervalMax){
float time = (location.getTime() - prev.getTime()) / 1000.0f; //两点的时间差
if (time <= 0) {
//LLog.print("时间异常: " + time);
return true;
}else{
// prev.setTime(location.getTime());
float speed = distance/time; // m/s ,车辆速度最大值 50米/秒(m/s)=180千米/时(km/h)
if (speed < 1.5){
LLog.print("速度过小: "+ speed+" 米/秒");
}else if (speed > 30){
LLog.print("速度过大: "+ speed+" 米/秒");
}
}
}
}
if (staticFlag) {
LLog.print("静止状态");
return true;
}
LLog.print("移动状态");
prev = location;
return false;
}
图2 - 部分数据截图
图3 - 部分数据截图
如今大多数智能手机系统都提供节点功能, GPS轨迹记录目前对于电量消耗是巨大的,如果在应用开发过程中,建议使用者进行如下设置: