我知道這是一個古老的問題,但也許它會對某人有用。
這是一個更簡單的方法,所需的計算量更少。這不會在用戶第一次進入閾值區域時觸發,它只會得到用戶在檢查點附近通過的最近點,以及他已經接近的最近點。
這個想法是爲每個檢查點維護一個3個項目的距離列表,其中最後三個距離(所以它應該是[d(t),d(t-1),d(t-2) ])。這個列表應該在每個距離計算中旋轉。如果在任何距離計算中先前的d(t-1)距離小於當前的d(t)並且大於先前的d(t-2),則移動點已經通過檢查點。通過檢查實際距離d(t-1)可以確定這是否是真正的通過,或者這只是一個小故障。
private long DISTANCE_THRESHOLD = 2000;
private Checkpoint calculateCheckpoint(Map<Checkpoint, List<Double>> checkpointDistances)
{
Map<Checkpoint, Double> candidates = new LinkedHashMap<Checkpoint, Double>();
for (Checkpoint checkpoint: checkpointDistances.keySet())
{
List<Double> distances = checkpointDistances.get(checkpoint);
if (distances == null || distances.size() < 3)
continue;
if (distances.get(0) > distances.get(1) && distances.get(1) < distances.get(2) && distances.get(1) < (DISTANCE_THRESHOLD)) //TODO: make this depend on current speed
candidates.put(checkpoint, distances.get(1));
}
List<Entry<Checkpoint, Double>> list = new LinkedList<Entry<Checkpoint,Double>>(candidates.entrySet());
Collections.sort(list, comp);
if (list.size() > 0)
return list.get(0).getKey();
else
return null;
}
Comparator<Entry<Checkpoint, Double>> comp = new Comparator<Entry<Checkpoint,Double>>()
{
@Override
public int compare(Entry<Checkpoint, Double> o1, Entry<Checkpoint, Double> o2)
{
return o1.getValue().compareTo(o2.getValue());
}
};
的函數獲取一個參數 - 一個Map<Checkpoint, List<Double>>
與檢查站和最後三個距離的列表。它輸出最近的Checkpoint
通過或null
(如果沒有)。 應該明智地選擇DISTANCE_THRESHOLD
。 Comparator
只是爲了能夠根據檢查點距離用戶的距離來排序檢查點以獲取最近的檢查點。
當然這有一些小缺陷,例如,如果移動點移動十字交叉,或者GPS精度的誤差移動與用戶的實際速度相稱,則會產生多個合格標記,但這幾乎會碰到任何算法。
爲什麼你需要一個多邊形而不是使用內圈? – SERPRO 2011-12-19 16:51:21