由於移動設備特別像android開發的流行。其中一個特定方向或者領域就是gps位置服務相關的開發。以arcgis android環境爲例
研究一下gps採集點的精度問題, 對於民用類的gps,像手機,平板等設備。
我們可以測試,如果調用手機的gps功能,獲取Location對象。同一個位置取到的點,並不相同。
精度可能在2米 5米 10米等範圍浮動,但是對於這些設備,我們很難提高它的精度怎麼辦呢。
軟件人員常用的辦法就是一個時間段內的平均值統計。最簡單的代碼如下:
import com.esri.core.geometry.Point;
public class GpsUtil {
public static Point getAvg(List<Point> listPoints) {
int count = 0;
double xAll = 0d, yAll = 0d;
for (Point p : listPoints) {
double x = p.getX();
double y = p.getY();
xAll = xAll + x;
yAll = yAll + y;
count = count + 1;
}
double xAvg = xAll / count;
double yAvg = yAll / count;
return new Point(xAvg, yAvg);
}
}
但是上面算法太簡單, 如果gps採集的點出現了奇異點怎麼辦呢,比如採集了10個點比較好,誤差不過2、3米。忽然有個點出現了10米(也有可能偏00米都有)以上的誤差,那取到的
平均值也就不準了。 爲了去除奇異點,我們設計一個算法,找出偏離平均值最大的移除。 對於左邊來說,可以認爲有兩個點是可能的奇異點
就是最大點 和最小點是奇異點。 如果移除這兩個可能的點,再計算均值,gps偏移可以得到一定的糾正。
當然如果站在高樓大廈下等地點,由於衛星信號受影響,可能永遠偏100多米,糾正也沒有意義.
移除 最高最低分的代碼如下:
public static Point getAvg(List<Point> listPoints) {
int count = 0;
double xAll = 0d, yAll = 0d;
for (int i = 0; i < listPoints.size(); i++) {
double x = p.getX();
double y = p.getY();
xAll = xAll + x;
yAll = yAll + y;
count = count + 1;
if (x > maxX) {
maxX = x;
maxIdx = i;
}
if (y > maxY) {
maxY = y;
mayIdx = i;
}
if (x < mixX) {
mixX = x;
mixIdx = i;
}
if (y < mixY) {
mixY = y;
miyIdx = i;
}
}
double xAvg = xAll / count;
double yAvg = yAll / count;
double maxX = xAvg;
double maxY = yAvg;
double mixX = xAvg;
double mixY = yAvg;
int maxIdx = -1, mayIdx = -1;
int mixIdx = -1, miyIdx = -1;
int maxNeedIdx=-1,minNeedIdx=-1;
if(Math.abs(xAvg-maxX)> Math.abs(yAvg-maxY)){
maxNeedIdx=maxIdx;
}else{
maxNeedIdx=mayIdx;
}
if(Math.abs(xAvg-mixX)> Math.abs(yAvg-mixY)){
minNeedIdx=mixIdx;
}else{
minNeedIdx=miyIdx;
}
if (maxNeedIdx > minNeedIdx) {
if(maxNeedIdx>=0)
listPoints.remove(maxNeedIdx);
if(minNeedIdx>=0)
listPoints.remove(minNeedIdx);
} else if (maxNeedIdx == minNeedIdx) {
if(maxNeedIdx>=0)
listPoints.remove(maxNeedIdx);
} else {
if(minNeedIdx>=0)
listPoints.remove(minNeedIdx);
if(maxNeedIdx>=0)
listPoints.remove(maxNeedIdx);
}
return getAvg0(listPoints);
}