2011-12-19 10 views
5

Oto sytuacja:Sprawdź, czy użytkownik znajduje się w pobliżu punktu kontrolnego trasy z GPS

Mam wcześniej ustaloną trasę GPS, którą uruchomi użytkownik. Trasa ma kilka punktów kontrolnych, a użytkownik powinien przejść obok nich (uważać je za punkt kontrolny gry wyścigowej, który uniemożliwia użytkownikowi wykonywanie skrótów). Muszę upewnić się, że użytkownik przechodzi przez wszystkie punkty kontrolne. Chcę określić obszar, który będzie rozpatrywany w promieniu punktu kontrolnego, ale nie chcę, aby był to tylko obszar promieniowy, powinien to być obszar uwzględniający formę ścieżki. Nie rozumiem tego? Ani I. Spójrz na to źle przygotowanego obrazu, aby go lepiej zrozumieć: Route example

czarnej linii reprezentuje zadanego toru, niebieska kula jest checkpoint i niebieski wielokąt jest obszar chcieliśmy. Zielona linia jest bardziej precyzyjnym użytkownikiem, a czerwona linia jest mniej dokładnym użytkownikiem (pijany facet, który może jeździć? Lol). Obie linie powinny znajdować się wewnątrz wielokąta, ale użytkownik, który pominął całkowicie trasę, nie powinien.

Już widziałem gdzieś tutaj funkcję do sprawdzenia, czy użytkownik znajduje się w takim wieloboku, ale muszę wiedzieć, jak obliczyć wielokąt.

Wszelkie sugestie?

EDIT:

Zastanawiam przy użyciu funkcji prosty distanceTo(), aby tylko zwrócić wyimaginowany koło i sprawdzić, czy użytkownik ma. To jest dobre, ponieważ jest tak proste w implementacji i zrozumieniu, i złe, ponieważ aby upewnić się, że najbardziej eratyczny użytkownik przejdzie w punkcie kontrolnym, potrzebowałbym dużego promienia, dzięki czemu właściwy użytkownik wejdzie do obszaru kontrolnego szybciej niż oczekiwano.

Tak, aby lepiej zrozumieć sytuację, dotyczy to aplikacji, która ma być używana w ruchu drogowym (samochód lub autobus), a punkty kontrolne powinny być punktami orientacyjnymi lub miejscami, które dzielą trasę, na przykład gdzieś. w którym zaczyna się lub zatrzymuje korki.

+0

Dlaczego potrzebujesz wielokąta zamiast używać wewnętrznego koła? – SERPRO

Odpowiedz

2

Możesz po prostu sprawdzić odległość między nimi, przy założeniu, że wiesz Geolokalizacja punktu kontrolnego.

Użyj funkcji distanceTo i ustaw próg na wiele metrów, które użytkownik musi przejść z punktu kontrolnego, aby kontynuować.

Edit

Ponieważ chcesz uniknąć distanceTo, tutaj jest mały funkcja pisałem jakiś czas temu, aby sprawdzić, czy punkt jest w wielokąta:

public boolean PIP(Point point, List<Point> polygon){ 
    boolean nodepolarity=false; 
    int sides = polygon.size(); 
    int j = sides -1; 
    for(int i=0;i<sides;i++){ 
     if((polygon.get(i).y<point.y && polygon.get(j).y>=point.y) ||(polygon.get(j).y<point.y && polygon.get(i).y>=point.y)){ 
      if (polygon.get(i).x+(point.y-polygon.get(i).y)/(polygon.get(j).y-polygon.get(i).y)*(polygon.get(j).x-polygon.get(i).x)<point.x) { 
       nodepolarity=!nodepolarity; 
      } 
     } 
    j=i; 
    } 
    return nodepolarity; //FALSE=OUTSIDE, TRUE=INSIDE 
} 

List<Point> polygon jest lista punkty tworzące wielokąt.

Wykorzystuje to Ray casting algorithm do określenia liczby przecięć, które promień wykonuje przez wielokąt.

Wszystko, co musisz zrobić, to stworzyć "granicę" wokół obszaru, którego potrzebujesz, przy czym GeoPoints są tłumaczone na piksele przy użyciu metody toPixels.

Zapisz te punkty na liście <> punktów i powinieneś już wszystko ustawić.

+0

Dokładnie tego staram się unikać, jeśli to zrobię, stracę trochę precyzji, ale zajrzę do niego, jeśli nie znajdę niczego innego. –

+0

@RodrigoCastro Patrz edytuj – MrZander

+0

Thaanks, prawie skończyłem tworzyć obszar (faktycznie zmieniłem definicję tego, co chcę, po tym, jak się nad tym więcej zastanowiłem). Edytowałem pytanie nowym (i lepszym) obrazem pokazującym, czego chcę. –

1

Wiem, że to stare pytanie, ale może byłoby przydatne dla kogoś.

Jest to prostsza metoda, z mniejszą ilością obliczeń. Nie spowodowałoby to pierwszego uruchomienia użytkownika w obszarze progu, a tylko w najbliższym punkcie, w którym użytkownik przeszedł w pobliżu punktu kontrolnego ORAZ (s), który zbliżył się dostatecznie blisko.

Chodzi o to, aby zachować 3 pozycje na liście odległości dla każdego punktu kontrolnego, z trzema ostatnimi odległościami (tak, aby były to [d (t), d (t-1), d (t-2) ]). Ta lista powinna być obrócona przy każdym obliczeniu odległości.

Jeśli na dowolnym obliczeniu odległości poprzednia odległość d (t-1) jest mniejsza niż aktualna d (t) i większa niż poprzednia d (t-2), punkt ruchu minął punkt kontrolny. Czy to było prawdziwe przejście, czy to była tylko usterka, można rozstrzygnąć, sprawdzając rzeczywistą odległość 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()); 
    } 
}; 

Funkcja pobiera jeden parametr - jest Map<Checkpoint, List<Double>> z punktów kontrolnych oraz wykaz ostatnich trzech dystansach. Wyprowadza najbliższy Checkpoint przekazany lub null (jeśli nie było żadnych). Należy wybrać rozsądnie DISTANCE_THRESHOLD. The Comparator jest po to, aby móc sortować punkty kontrolne na podstawie ich odległości od użytkownika, aby uzyskać najbliższy.

Oczywiście ma to kilka drobnych wad, np. jeśli punkt ruchu porusza się w poprzek, lub ruch błędu z dokładności GPS jest współmierny do rzeczywistej prędkości użytkownika, to dałoby to wiele znaków przejścia, ale uderzyłoby to prawie w każdy algorytm.

+0

Dzięki, nie pracuję już nad oryginalnym projektem, ale to prawdopodobnie pomoże mi w nadchodzącym projekcie dotyczącym śledzenia autobusów! –

+0

I myślę, że byłoby dobrze zachować więcej niż 3 punkty pamięci w tym samym czasie, aby sprawdzić niespójności, które mogą sugerować zakłócenia GPS, zamiast prawdziwych danych wskazujących, że użytkownik opuścił obszar –

+1

@ rodrigo- Castro Yep, 3 punkty są absolutnym minimum, aby rozwiązać problem. Więcej punktów zmniejszyłoby prawdopodobieństwo błędu, ale skomplikowało kod. Być może należy to pozostawić bardziej inteligentnemu algorytmowi (może samemu układowi GPS), który odfiltrowałby drgania pomiaru i dostarczyłby tylko rzeczywiste/skuteczne dane ruchu. To kolejny problem. :) – Tylla

Powiązane problemy