Я знаю, что это старый вопрос, но, возможно, он кому-нибудь пригодится.
Это более простой метод, требующий гораздо меньших вычислений.Это не сработает при первом входе пользователя в пороговую область, оно получит только самую близкую точку, где пользователь прошел вблизи контрольной точки И (и) он достаточно близко подошел.
Идея состоит в том, чтобы поддерживатьсписок из 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 соизмерима с фактической скоростью пользователя, чем это даст несколько проходных баллов, но это затронет практически любой алгоритм.