package com.example.trace;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* GPS轨迹异常点检测与处理
*/
public class Outlier {
public static float state;
//判断巡河员巡河方式
public static void checkState(ArrayList<double[]> gpsList) {
double[] dangerBefore = null;
double distance = 0;
for (int i = 1; i < gpsList.size(); i++) {
double[] dangerVo = gpsList.get(i);
if (dangerBefore == null) {
dangerBefore = gpsList.get(i - 1);
}
distance += LocationConvert.getDistance(dangerVo[0], dangerVo[1], dangerBefore[0], dangerBefore[1]);
dangerBefore = dangerVo;
}
double disAvg = distance / (gpsList.size() - 1);
// Log.i("safe", "总距离dis: " + distance+" disavg: "+disAvg);
//假设gps采样间隔为5s,人步行的速度大约为1m/s,那么定义相邻两点间平均间隔<8m的为步行,并定义最大步行速度为1.5
//骑车与开车同理,阈值可根据实际情况作更改
if (disAvg < 8) {
state = 1.5f;//走路
} else if (disAvg >= 8 && disAvg < 30) {
state = 5;//骑车
} else {
state = 15;//开车
}
}
//获取最长的合理轨迹
public static String getSafeIndex(ArrayList<double[]> gpsList) {
int start = 0;
int end = 0;
List<String> indexList = new ArrayList<>();
double[] dangerBefore = null;
// Log.i("safe", "getGpsIndex:" + gpsList.size());
for (int i = 1; i < gpsList.size(); i++) {
double[] dangerVo = gpsList.get(i);
if (dangerBefore == null) {
dangerBefore = gpsList.get(i - 1);
}
//米
double distance = LocationConvert.getDistance(dangerVo[0], dangerVo[1], dangerBefore[0], dangerBefore[1]);
//GPS采集频率,假定5秒
long time = 5;
double speed = distance / time;
if (speed > state) {
if (end > start) {
indexList.add(end + "-" + start);
// Log.i("safe", "合理轨迹段:" + indexList.size());
}
start = i;
}
end = i;
dangerBefore = dangerVo;
}
if (end > start) {
//最后一段合理轨迹
indexList.add(end + "-" + start);
// Log.i("safe", "合理轨迹段:" + indexList.size());
}
int maxIndx = 0;
int max = 0;
for (int i = 0; i < indexList.size(); i++) {
int tmpEnd = Integer.valueOf(indexList.get(i).split("-")[0]);
int tmpStart = Integer.valueOf(indexList.get(i).split("-")[1]);
if (tmpEnd - tmpStart > max) {
max = tmpEnd - tmpStart;
maxIndx = i;
}
}
// Log.i("safe", "最长合理轨迹:" + indexList.get(maxIndx));
return indexList.get(maxIndx);
}
//从最长合理轨迹两侧遍历,寻找异常点
public static void removeErrorPoint(ArrayList<double[]> gpsList) {
checkState(gpsList);//判断巡河方式
// Log.i("safe", "阈值:" +state);
String safeIndexs = getSafeIndex(gpsList);
int startIndex = Integer.valueOf(safeIndexs.split("-")[1]);
int endIndex = Integer.valueOf(safeIndexs.split("-")[0]);
if (startIndex == 0 && endIndex == gpsList.size() - 1) {
return;//轨迹正常
}
List<Integer> deleteList = new ArrayList<>();
double[] safeVo = gpsList.get(startIndex);
for (int i = startIndex - 1; i > -1; i--) {
double[] dangerVo = gpsList.get(i);
double distance = LocationConvert.getDistance(dangerVo[0], dangerVo[1], safeVo[0], safeVo[1]);
long time = 5;
double speed = distance / time;
if (speed > state) {
deleteList.add(i);
} else {
safeVo = dangerVo;
}
}
safeVo = gpsList.get(endIndex);
for (int i = endIndex + 1; i < gpsList.size(); i++) {
double[] dangerVo = gpsList.get(i);
double distance = LocationConvert.getDistance(dangerVo[0], dangerVo[1], safeVo[0], safeVo[1]);
long time = 5;
double speed = distance / time;
if (speed > state) {
deleteList.add(i);
} else {
safeVo = dangerVo;
}
}
if (!deleteList.isEmpty()) {
// Log.i("safe", "异常点数量:" + deleteList.size());
// 删除异常点
for (int i = 0; i < deleteList.size(); i++) {
// Log.i("safe", "异常点:" + deleteList.get(i));
//删除一次size会变,所以需要-i
try{
gpsList.remove(deleteList.get(i) - i);
}
catch (Exception e){
// Log.i("safe", "异常" );
}
}
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
前往页