我知道这是一个古老的问题,但也许它会对某人有用。
这是一个更简单的方法,所需的计算量更少。这不会在用户第一次进入阈值区域时触发,它只会得到用户在检查点附近通过的最近点,以及他已经接近的最近点。
这个想法是为每个检查点维护一个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