最近使用高德地图用来记录轨迹的运动距离,使用的是api中的
原始点359个点,在经过纠偏后得到了了两个点,如下所示,是我整段轨迹,红色点是纠偏之后高德地图给我的点。经过测试几次之后我对这个api有点失望了,决定自己写纠偏,然后再做距离求解。
算法过程:
1. 我们的计算过程滞后运动过程,在经过点检验之后将有效点加入我们的距离计算过程。
2. 有效点的判断是根据与权重点的距离进行判断的。
3. 权重点的获取是通过前一个权威点与新的轨迹点根据一定权重得到的(一开始权威点选为首个轨迹点)
4. 轨迹的运行过程中,有效权重点只有一个,代表的是一段有效轨迹的稳定点,如果出现疑似偏移点的点,则再生成一个,代表新的这个疑似偏移点为开始的点的权重,如果这个新的疑似偏移点之后的5个点都没有偏移,则说明这段轨迹有效,则加入有效轨迹点中并更新权重点诶该点。
5. 权重点代表着一段轨迹的最终稳定点,当它代表的轨迹点数小于5个则表明那段点可能是偏移点。则要被干掉。
我们这里先选取全重为0.8。
w1= p1*0.2 + p2*0.8
这里我们设置5个单位各自为可接受范围。超过5个格子就要弃点。每个格子代表单位时间2s。我们这里的定位间隔为2s。
我们通过权重点慢慢修复到正常的过程。绿色圈为各个定位时刻的权重点。
起始超过很多单位格子为要过滤的偏移点。P1、p2为不可接受偏移点,但是在起始不知道,当p3出现之后,发现距离有点大,则为p3生成新的权重点w2,连续判断5个点没有偏差,说明这几个点的轨迹是正确的则采用,将w1代表的点干掉,并将w1更新到w2这里。
因为没有成功定位所以被分隔的两段的定位都是有效数据
这里有一个跳点p5,判定为可疑跳点之后,我们给他一个新的权重点w2,在接下来判断中发现p6相对于w2来说也是跳点,则把w2代表的点干掉,然后重新让他代表p6。在接下来的5次定位稳定,则将权重点更新为w1。此时w1代表的是p1到当前定位点。
在有段时间失去坐标之后又重新获取,但是在判断的时候突然又有跳点,则我们只能按照算法舍去p6,从p8开始重新设置为新的记录点。
红色为计算的距离。
我们这里做的是车辆的轨迹记录,所以我们在判断偏移点的距离的时候按照车辆80km/h(22m/s)来计算的。则2s的定位间隔来算的话应该是下一个定位点距离权重点44m之外就算作偏移点。在有一段时间没有成功获取定位点的时候先计算两点间隔时间再计算最大偏移点范围。
注意:在高德地图中如果位置没有改变的话,返回的是缓存定位结果,定位时间也是缓存的。所以说如果定位坐标不改变,那么定位时间不会改变
/**
* @param aMapLocation
* @return 是否获得有效点,需要存储和计算距离
*/
private BooleanfilterPos(AMapLocationaMapLocation) {
SimpleDateFormat df= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
Date date= new Date(aMapLocation.getTime());
String time= df.format(date);//定位时间
filterString =time + "开始虑点"+ "\r\n";
try {
// 获取的第一个定位点不进行过滤
if (isFirst) {
isFirst =false;
weight1.setLatitude(aMapLocation.getLatitude());
weight1.setLongitude(aMapLocation.getLongitude());
weight1.setTime(aMapLocation.getTime());
weight1.setSpeed(aMapLocation.getSpeed());
/****************存储数据到文件中,后面好分析******************/
filterString +="第一次定位"+ "\r\n";
/**********************************/
// 将得到的第一个点存储入w1的缓存集合
final TraceLocationtraceLocation =new TraceLocation();
traceLocation.setLatitude(aMapLocation.getLatitude());
traceLocation.setLongitude(aMapLocation.getLongitude());
traceLocation.setTime(aMapLocation.getTime());
traceLocation.setSpeed(aMapLocation.getSpeed());
w1TempList.add(traceLocation);
w1Count++;
return true;
} else{
filterString +="非第一次定位"+ "\r\n";
// 过滤静止时的偏点,在静止时速度小于1米就算做静止状态
if (aMapLocation.getSpeed() <1) {
return false;
}
/****************存储数据到文件中,后面好分析******************/
SimpleDateFormat df1= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
Date date1= new Date(aMapLocation.getTime());
String time1= df1.format(date1);// 定位时间
String testString=time1 + ":" + aMapLocation.getTime() +"_" + aMapLocation.getLocationType() +"," + aMapLocation.getLatitude() +"," + aMapLocation.getLongitude() +"," + aMapLocation.getAccuracy() +"," + aMapLocation.getSpeed() +"\r\n";
FileWriteUtil.getInstance().save("tutu_driver_true.txt",testString);
if (weight2== null) {
filterString +="weight2 == null" +"\r\n";
// 计算w1与当前定位点p1的时间差并得到最大偏移距离D
long offsetTimeMils= aMapLocation.getTime() -weight1.getTime();
long offsetTimes = (offsetTimeMils/ 1000);
long MaxDistance =offsetTimes *CAR_MAX_SPEED;
float distance =AMapUtils.calculateLineDistance(
new LatLng(weight1.getLatitude(),weight1.getLongitude()),
new LatLng(aMapLocation.getLatitude(),aMapLocation.getLongitude()));
filterString +="distance = " +distance + ",MaxDistance =" +MaxDistance +"\r\n";
if (distance> MaxDistance) {
filterString +="distance > MaxDistance" +"\r\n";
// 将设置w2位新的点,并存储入w2临时缓存
weight2 =new TraceLocation();
weight2.setLatitude(aMapLocation.getLatitude());
weight2.setLongitude(aMapLocation.getLongitude());
weight2.setTime(aMapLocation.getTime());
weight2.setSpeed(aMapLocation.getSpeed());
w2TempList.add(weight2);
return false;
} else{
filterString +="distance < MaxDistance" +"\r\n";
// 将p1加入到做坐标集合w1TempList
TraceLocation traceLocation=new TraceLocation();
traceLocation.setLatitude(aMapLocation.getLatitude());
traceLocation.setLongitude(aMapLocation.getLongitude());
traceLocation.setTime(aMapLocation.getTime());
traceLocation.setSpeed(aMapLocation.getSpeed());
w1TempList.add(traceLocation);
w1Count++;
// 更新w1权值点
weight1.setLatitude(weight1.getLatitude() * 0.2 + aMapLocation.getLatitude() *0.8);
weight1.setLongitude(weight1.getLongitude() * 0.2 + aMapLocation.getLongitude() *0.8);
weight1.setTime(aMapLocation.getTime());
weight1.setSpeed(aMapLocation.getSpeed());
if (w1TempList.size() >3) {
filterString += "d1TempList.size() > 3"+ "\r\n";
// 将w1TempList中的数据放入finalList,并将w1TempList清空
mListPoint.addAll(w1TempList);
w1TempList.clear();
return true;
} else{
filterString += "d1TempList.size() < 3"+ "\r\n";
return false;
}
}
} else {
filterString +="weight2 != null" +"\r\n";
// 计算w1与当前定位点p1的时间差并得到最大偏移距离D
long offsetTimeMils= aMapLocation.getTime() -weight2.getTime();
long offsetTimes = (offsetTimeMils/ 1000);
long MaxDistance =offsetTimes *16;
float distance =AMapUtils.calculateLineDistance(
new LatLng(weight2.getLatitude(),weight2.getLongitude()),
new LatLng(aMapLocation.getLatitude(),aMapLocation.getLongitude()));
filterString+="distance= " +distance + ",MaxDistance = " +MaxDistance +"\r\n";
if (distance> MaxDistance) {
filterString +="distance > MaxDistance" +"\r\n";
w2TempList.clear();
// 将设置w2位新的点,并存储入w2临时缓存
weight2 =new TraceLocation();
weight2.setLatitude(aMapLocation.getLatitude());
weight2.setLongitude(aMapLocation.getLongitude());
weight2.setTime(aMapLocation.getTime());
weight2.setSpeed(aMapLocation.getSpeed());
w2TempList.add(weight2);
return false;
} else{
filterString +="distance < MaxDistance" +"\r\n";
// 将p1加入到做坐标集合w2TempList
TraceLocation traceLocation=new TraceLocation();
traceLocation.setLatitude(aMapLocation.getLatitude());
traceLocation.setLongitude(aMapLocation.getLongitude());
traceLocation.setTime(aMapLocation.getTime());
traceLocation.setSpeed(aMapLocation.getSpeed());
w2TempList.add(traceLocation);
// 更新w2权值点
weight2.setLatitude(weight2.getLatitude() * 0.2 + aMapLocation.getLatitude() *0.8);
weight2.setLongitude(weight2.getLongitude() * 0.2 + aMapLocation.getLongitude() *0.8);
weight2.setTime(aMapLocation.getTime());
weight2.setSpeed(aMapLocation.getSpeed());
if (w2TempList.size() >4) {
filterString+="w2TempList.size()> 4" +"\r\n";
// 判断w1所代表的定位点数是否>4,小于说明w1之前的点为从一开始就有偏移的点
if (w1Count> 4) {
filterString += "w1Count > 4" + "\r\n";
mListPoint.addAll(w1TempList);
} else{
filterString += "w1Count < 4" + "\r\n";
w1TempList.clear();
}
// 将w2TempList集合中数据放入finalList中
mListPoint.addAll(w2TempList);
// 1、清空w2TempList集合 2、更新w1的权值点为w2的值 3、将w2置为null
w2TempList.clear();
weight1 =weight2;
weight2 =null;
return true;
} else{
filterString += "w2TempList.size() > 4"+ "\r\n";
return false;
}
}
}
}
} finally {
FileWriteUtil.getInstance().save("tutu_driver_filter.txt",filterString);
// Log.d("hhh","finnaly");
}
}
这里的验证是基于上面讨论的几种可能的偏移点进行的。
这段正常轨迹是通过虑点之后存储的可信点绘制的一串轨迹坐标。 |
红色点是我手动让第一个点偏移了3km之后得到了偏移点,按照算法该点是被过滤了的 |
这是模拟起始点成功定位,之后有段时间没有定位成功,过了很久才又定位成功的情况 |
|
连续3点在一段有效范围之内就算做有效定位。
|
这里设定了第200个点是偏点,则出现之后过滤直接被过滤掉了 |
模拟在运行到一半突然定位失效,然后有定位有效了5个点,然后又定位失效的,最后有有效的情况
设置了从200个点到205个点为一段有效的定位点。因为在5个点内这段定位没有被判偏,则视为有效定位 |
因为是时时定位没有办法,所以只能将原始点通过文件的方式存储起来。过滤之后的有效点通过json的形式存储在sp中。在分析数据时候借助excel进行数据整理和分析。
1、在算法的每个关键步骤和判断加入String,记录此时的状态。在进行测试之后拿出文件进行分析,具体的文件拿出过程参考我的安卓文件存储与取出:
http://blog.csdn.net/u011486491/article/details/69257436
2、通过分析步骤之后确保算法大概的正确性。
3、通过算法获取有效的定位数据点并通过sp进行存储。
4、通过定时任务模拟运动过程,重现轨迹运行过程,这时候因为有了真实数据,我们就可以将文件存储的结果,变成log打印来分析。
5、通过改变真实数据的各个值去模拟我们可能遇到的偏移点
原始数据:
过滤后的数据:
定位过程流程数据:
从过滤数据导入excel的数据
public class ShowLocationActivity extends BaseActivity implements TraceListener { MapView mMapView = null; //初始化地图控制器对象 AMap aMap; ActivityShowLocationBinding mDataBinding; private List<TraceLocation> mListPoint = new ArrayList<>(); private List<TraceLocation> originPosList; private LBSTraceClient lbsTraceClient; private Gson mGson = new Gson(); final int CAR_MAX_SPEED = 22; // 80km/h private Boolean isFirst = true; // 是否是第一次定位点 private TraceLocation weight1 = new TraceLocation(); // 权重点1 private TraceLocation weight2; // 权重点2 private List<TraceLocation> w1TempList = new ArrayList<>(); // w1的临时定位点集合 private List<TraceLocation> w2TempList = new ArrayList<>(); // w2的临时定位点集合 private int w1Count = 0; // 统计w1Count所统计过的点数 private String filterString; private int posCount = 0; private TraceLocation posTraceLocation; private int beginPos = 0; private final Timer timer = new Timer(); TimerTask task = new TimerTask() { private MarkerOptions markerOption; @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { //处理延时任务 if (posCount == 200) { // 创建跳点 TraceLocation traceLocation = originPosList.get(posCount); LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160100, traceLocation.getLongitude() - 0.0160000); traceLocation.setLatitude(latLng.latitude); traceLocation.setLongitude(latLng.longitude); // 绘制跳点 markerOption = new MarkerOptions(); markerOption.position(latLng); markerOption.draggable(false);//设置Marker可拖动 markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(), R.mipmap.icon_red_point))); // 将Marker设置为贴地显示,可以双指下拉地图查看效果 markerOption.setFlat(true);//设置marker平贴地图效果 aMap.addMarker(markerOption); posTraceLocation = traceLocation; } else if (posCount == 201) { // 创建跳点 TraceLocation traceLocation = originPosList.get(posCount); LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160300, traceLocation.getLongitude() - 0.0160000); traceLocation.setLatitude(latLng.latitude); traceLocation.setLongitude(latLng.longitude); // 绘制跳点 markerOption = new MarkerOptions(); markerOption.position(latLng); markerOption.draggable(false);//设置Marker可拖动 markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(), R.mipmap.icon_red_point))); // 将Marker设置为贴地显示,可以双指下拉地图查看效果 markerOption.setFlat(true);//设置marker平贴地图效果 aMap.addMarker(markerOption); posTraceLocation = traceLocation; } else if (posCount == 202) { // 创建跳点 TraceLocation traceLocation = originPosList.get(posCount); LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160500, traceLocation.getLongitude() - 0.0160000); traceLocation.setLatitude(latLng.latitude); traceLocation.setLongitude(latLng.longitude); // 绘制跳点 markerOption = new MarkerOptions(); markerOption.position(latLng); markerOption.draggable(false);//设置Marker可拖动 markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(), R.mipmap.icon_red_point))); // 将Marker设置为贴地显示,可以双指下拉地图查看效果 markerOption.setFlat(true);//设置marker平贴地图效果 aMap.addMarker(markerOption); posTraceLocation = traceLocation; } else if (posCount == 203) { // 创建跳点 TraceLocation traceLocation = originPosList.get(posCount); LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160700, traceLocation.getLongitude() - 0.0160000); traceLocation.setLatitude(latLng.latitude); traceLocation.setLongitude(latLng.longitude); // 绘制跳点 markerOption = new MarkerOptions(); markerOption.position(latLng); markerOption.draggable(false);//设置Marker可拖动 markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(), R.mipmap.icon_red_point))); // 将Marker设置为贴地显示,可以双指下拉地图查看效果 markerOption.setFlat(true);//设置marker平贴地图效果 aMap.addMarker(markerOption); posTraceLocation = traceLocation; } else if (posCount == 204) { // 创建跳点 TraceLocation traceLocation = originPosList.get(posCount); LatLng latLng = new LatLng(traceLocation.getLatitude()+0.0160900, traceLocation.getLongitude() - 0.0160000); traceLocation.setLatitude(latLng.latitude); traceLocation.setLongitude(latLng.longitude); // 绘制跳点 markerOption = new MarkerOptions(); markerOption.position(latLng); markerOption.draggable(false);//设置Marker可拖动 markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(), R.mipmap.icon_red_point))); // 将Marker设置为贴地显示,可以双指下拉地图查看效果 markerOption.setFlat(true);//设置marker平贴地图效果 aMap.addMarker(markerOption); posTraceLocation = traceLocation; } else { // 绘制点得到正常点 posTraceLocation = originPosList.get(posCount); } Boolean isSHow = filterPos(posTraceLocation); if (isSHow) { // LatLng startLocation_gps = new LatLng(posTraceLocation.getLatitude(), posTraceLocation.getLongitude()); // markerOption.position(startLocation_gps); // markerOption.draggable(false);//设置Marker可拖动 // markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.icon_point))); // // 将Marker设置为贴地显示,可以双指下拉地图查看效果 // markerOption.setFlat(true);//设置marker平贴地图效果 // aMap.addMarker(markerOption); for (int i = beginPos; i < mListPoint.size(); i++) { TraceLocation traceLocation = mListPoint.get(i); LatLng startLocation_gps = new LatLng(traceLocation.getLatitude(), traceLocation.getLongitude()); MarkerOptions markerOption = new MarkerOptions(); markerOption.position(startLocation_gps); markerOption.draggable(false);//设置Marker可拖动 markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(), R.mipmap.icon_point))); // 将Marker设置为贴地显示,可以双指下拉地图查看效果 markerOption.setFlat(true);//设置marker平贴地图效果 aMap.addMarker(markerOption); } beginPos = mListPoint.size(); } posCount++; if (posCount == 320) { timer.cancel(); } } }); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(); //获取地图控件引用 mMapView = (MapView) findViewById(R.id.map); //在activity执行onCreate时执行mMapView.onCreate(savedInstanceState),创建地图 mMapView.onCreate(savedInstanceState); if (aMap == null) { aMap = mMapView.getMap(); } } @Override public int setContentView() { return R.layout.activity_show_location; } @Override public void initTitle() { } @Override public void initView() { mDataBinding = getDataBinding(); BitmapDescriptor mPoint = BitmapDescriptorFactory.fromResource(R.mipmap.icon_point); // 设置司机定位点 MyLocationStyle myLocationStyle; myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类 myLocationStyle.myLocationIcon(mPoint); myLocationStyle.myLocationType(LOCATION_TYPE_LOCATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。 myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。 aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style aMap.getUiSettings().setMyLocationButtonEnabled(true); // 设置默认定位按钮是否显示,非必需设置。 aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。 lbsTraceClient = LBSTraceClient.getInstance(APP.getInstance()); } @Override public void initData() { // from local json string final String jsonString = ShareData.getShareStringData(ShareData.BACK_UP_POINTS); Type type = new TypeToken<ArrayList<TraceLocation>>() { }.getType(); try { originPosList = new Gson().fromJson(jsonString, type); } catch (JsonSyntaxException e) { e.printStackTrace(); } if (originPosList == null) { originPosList = new ArrayList<>(); } } @Override public void processing() { timer.schedule(task, 20, 100); // // for (int i = 0; i < originPosList.size(); i++) { // // TraceLocation traceLocation = originPosList.get(i); // LatLng startLocation_gps = new LatLng(traceLocation.getLatitude(), traceLocation.getLongitude()); // MarkerOptions markerOption = new MarkerOptions(); // markerOption.position(startLocation_gps); // markerOption.draggable(false);//设置Marker可拖动 // markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory // .decodeResource(getResources(), R.mipmap.icon_point))); // // 将Marker设置为贴地显示,可以双指下拉地图查看效果 // markerOption.setFlat(true);//设置marker平贴地图效果 // aMap.addMarker(markerOption); // } // int distance = 0; // // int size = mListPoint.size(); // for (int pos=0; pos < size - 1; pos++) { // distance += AMapUtils.calculateLineDistance( // new LatLng(mListPoint.get(pos).getLatitude(), mListPoint.get(pos).getLongitude()), // new LatLng(mListPoint.get(pos+1).getLatitude(), mListPoint.get(pos+1).getLongitude()) // ); // } } @Override protected void onDestroy() { super.onDestroy(); //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图 mMapView.onDestroy(); timer.cancel(); } @Override protected void onResume() { super.onResume(); //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图 if (mMapView != null) { mMapView.onResume(); } } @Override protected void onPause() { super.onPause(); //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制 mMapView.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态 mMapView.onSaveInstanceState(outState); } @Override public void onRequestFailed(int i, String s) { } @Override public void onTraceProcessing(int i, int i1, List<LatLng> list) { } @Override public void onFinished(int i, List<LatLng> list, int i1, int i2) { for (int k = 0; k < list.size(); k++) { LatLng latLng = list.get(i); MarkerOptions markerOption = new MarkerOptions(); markerOption.position(latLng); markerOption.draggable(false);//设置Marker可拖动 markerOption.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory .decodeResource(getResources(), R.mipmap.icon_red_point))); // 将Marker设置为贴地显示,可以双指下拉地图查看效果 markerOption.setFlat(true);//设置marker平贴地图效果 aMap.addMarker(markerOption); } } /** * @param aMapLocation * @return 是否获得有效点,需要存储和计算距离 */ private Boolean filterPos(TraceLocation aMapLocation) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA); Date date = new Date(aMapLocation.getTime()); String time = df.format(date);//定位时间 filterString = time + "开始虑点" + "\r\n"; try { // 获取的第一个定位点不进行过滤 if (isFirst) { isFirst = false; weight1.setLatitude(aMapLocation.getLatitude()); weight1.setLongitude(aMapLocation.getLongitude()); weight1.setTime(aMapLocation.getTime()); /****************存储数据到文件中,后面好分析******************/ filterString += "第一次定位" + "\r\n"; /**********************************/ // 将得到的第一个点存储入w1的缓存集合 final TraceLocation traceLocation = new TraceLocation(); traceLocation.setLatitude(aMapLocation.getLatitude()); traceLocation.setLongitude(aMapLocation.getLongitude()); traceLocation.setTime(aMapLocation.getTime()); w1TempList.add(traceLocation); w1Count++; return true; } else { filterString += "非第一次定位" + "\r\n"; // // 过滤静止时的偏点,在静止时速度小于1米就算做静止状态 // if (aMapLocation.getSpeed() < 1) { // return false; // } /****************存储数据到文件中,后面好分析******************/ SimpleDateFormat df1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA); Date date1 = new Date(aMapLocation.getTime()); String time1 = df1.format(date1); // 定位时间 String testString = time1 + ":" + aMapLocation.getTime() + "," + aMapLocation.getLatitude() + "," + aMapLocation.getLongitude() + "," + aMapLocation.getSpeed() + "\r\n"; FileWriteUtil.getInstance().save("tutu_driver_true.txt", testString); if (weight2 == null) { filterString += "weight2 == null" + "\r\n"; // 计算w1与当前定位点p1的时间差并得到最大偏移距离D long offsetTimeMils = aMapLocation.getTime() - weight1.getTime(); long offsetTimes = (offsetTimeMils / 1000); long MaxDistance = offsetTimes * CAR_MAX_SPEED; float distance = AMapUtils.calculateLineDistance( new LatLng(weight1.getLatitude(), weight1.getLongitude()), new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude())); filterString += "distance = " + distance + ",MaxDistance = " + MaxDistance + "\r\n"; if (distance > MaxDistance) { filterString += "distance > MaxDistance" + "\r\n"; // 将设置w2位新的点,并存储入w2临时缓存 weight2 = new TraceLocation(); weight2.setLatitude(aMapLocation.getLatitude()); weight2.setLongitude(aMapLocation.getLongitude()); weight2.setTime(aMapLocation.getTime()); w2TempList.add(weight2); return false; } else { filterString += "distance < MaxDistance" + "\r\n"; // 将p1加入到做坐标集合w1TempList TraceLocation traceLocation = new TraceLocation(); traceLocation.setLatitude(aMapLocation.getLatitude()); traceLocation.setLongitude(aMapLocation.getLongitude()); traceLocation.setTime(aMapLocation.getTime()); w1TempList.add(traceLocation); w1Count++; // 更新w1权值点 weight1.setLatitude(weight1.getLatitude() * 0.2 + aMapLocation.getLatitude() * 0.8); weight1.setLongitude(weight1.getLongitude() * 0.2 + aMapLocation.getLongitude() * 0.8); weight1.setTime(aMapLocation.getTime()); weight1.setSpeed(aMapLocation.getSpeed()); if (w1TempList.size() > 3) { filterString += "d1TempList.size() > 3" + "\r\n"; // 将w1TempList中的数据放入finalList,并将w1TempList清空 mListPoint.addAll(w1TempList); w1TempList.clear(); return true; } else { filterString += "d1TempList.size() < 3" + "\r\n"; return false; } } } else { filterString += "weight2 != null" + "\r\n"; // 计算w2与当前定位点p1的时间差并得到最大偏移距离D long offsetTimeMils = aMapLocation.getTime() - weight2.getTime(); long offsetTimes = (offsetTimeMils / 1000); long MaxDistance = offsetTimes * 16; float distance = AMapUtils.calculateLineDistance( new LatLng(weight2.getLatitude(), weight2.getLongitude()), new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude())); filterString += "distance = " + distance + ",MaxDistance = " + MaxDistance + "\r\n"; if (distance > MaxDistance) { filterString += "distance > MaxDistance" + "\r\n"; w2TempList.clear(); // 将设置w2位新的点,并存储入w2临时缓存 weight2 = new TraceLocation(); weight2.setLatitude(aMapLocation.getLatitude()); weight2.setLongitude(aMapLocation.getLongitude()); weight2.setTime(aMapLocation.getTime()); w2TempList.add(weight2); return false; } else { filterString += "distance < MaxDistance" + "\r\n"; // 将p1加入到做坐标集合w2TempList TraceLocation traceLocation = new TraceLocation(); traceLocation.setLatitude(aMapLocation.getLatitude()); traceLocation.setLongitude(aMapLocation.getLongitude()); traceLocation.setTime(aMapLocation.getTime()); w2TempList.add(traceLocation); // 更新w2权值点 weight2.setLatitude(weight2.getLatitude() * 0.2 + aMapLocation.getLatitude() * 0.8); weight2.setLongitude(weight2.getLongitude() * 0.2 + aMapLocation.getLongitude() * 0.8); weight2.setTime(aMapLocation.getTime()); weight2.setSpeed(aMapLocation.getSpeed()); if (w2TempList.size() > 4) { filterString += "w2TempList.size() > 4" + "\r\n"; // 判断w1所代表的定位点数是否>4,小于说明w1之前的点为从一开始就有偏移的点 if (w1Count > 4) { filterString += "w1Count > 4" + "\r\n"; mListPoint.addAll(w1TempList); } else { filterString += "w1Count < 4" + "\r\n"; w1TempList.clear(); } // 将w2TempList集合中数据放入finalList中 mListPoint.addAll(w2TempList); // 1、清空w2TempList集合 2、更新w1的权值点为w2的值 3、将w2置为null w2TempList.clear(); weight1 = weight2; weight2 = null; return true; } else { filterString += "w2TempList.size() < 4" + "\r\n"; return false; } } } } } finally { // FileWriteUtil.getInstance().save("tutu_driver_filter.txt", filterString); // Log.d("hhh","finnaly"); Log.d("hhh",filterString); } } }