2009-08-24 10 views
2

Hintergrund: Ich erhalte eine lange und lat als Parameter zu einem Web-Service. Sie sind in der Regel bis zu 6 Dezimalstellen. Wenn eine neue Anfrage empfangen wird, berechne ich den Abstand zwischen der letzten aufgezeichneten Lok und dem Long/Lat in den Parametern der Anfrage. Wenn die Entfernung größer als ein bestimmter Schwellenwert von Meilen auseinander ist, aktualisiere ich die aktuelle Lok.Fließkommaberechnungen mit Breiten- und Längengraden unterschiedlicher Genauigkeit

Problem: Ich benutze den geokit gem/plugin, um den Abstand zwischen den locs zu berechnen. Sehr selten taucht ein Bug auf (der auf der Website des Autors erwähnte Nullabstand-Bug - ich benutze 1.4.1, der behauptet, der Bug sei behoben, aber ich sehe immer noch shrug), der bewirkt, dass der Abstand calc etwas zurückgibt sehr ungenau bei der Berechnung der Entfernung zwischen zwei identischen Punkten (dies tritt auf, wenn sich der Benutzer nicht bewegt). Dies verursacht Aktualisierungen der aktuellen Lok des Benutzers, die nicht stattfinden sollten. Du fragst dich wahrscheinlich - nun, wenn es nur darum geht, die Lok auf genau die gleichen Koordinaten zu bringen, wen interessiert das? Nun, die Antwort ist, dass eine Menge anderer Mist entsteht, wenn die Lok aktualisiert wird, was es zu einem tatsächlichen Problem macht.

Lösungsversuch: Ich habe versucht, in Logik hinzuzufügen, um manuell zu überprüfen, ob die zwei Locs identisch sind, bevor Sie den Abstand berechnen und dann nur den Calc überspringen und nicht aktualisieren, wenn das der Fall ist. Die eingehenden Parameter sind long/lats mit 6 Dezimalstellen; während ich in meiner Datenbank die Werte als Gleitkommazahlen speichert, die anscheinend nur 4 Dezimalstellen speichern. Dies führt dazu, dass mein Float-Vergleich immer fehlschlägt und die unangemessenen Lokupdates weiterhin auftreten.

Puh, ok, also die eigentliche Frage ist: Wie soll ich diesen Vergleich durchführen? Sollte ich 2 der Dezimalstellen von den eingehenden Lat/Longs abschneiden, irgendwie aufrunden, damit die vierte Ziffer korrekt ist und dann vergleichen? Oder sollte ich eine "innerhalb eines bestimmten Bereichs" Art des Vergleichs (z. B. gemeldete_Loc.Long> aktuelle_Lokation.Lange - .0001 & & gemeldete_loc.long < current_loc.long + .0001)? Auch irgendwelche Empfehlungen für existierende Rubin-Edelsteine ​​/ Plugins oder eingebaute Funktionen, um diese Art von Dingen zu tun, würden sehr geschätzt werden. Hier

Beispiel ist eine Ausgabe aus dem Protokoll:

[update_loc] Last location history record at lat: 41.5024, long: -81.6816 
[update_loc] Current loc at lat: 41.502467, long: -81.681623 
[update_loc] Distance from current loc and last loc history: 5795.10615113555 miles 
[update_loc] Locs not identical and distance greater than threshold, inserting new loc history 
[update_loc] Location update complete 

Danke

Tom

Antwort

3

Der übliche Weg zu testen, ob zwei Zahlen nahe ist abs zu verwenden, das heißt

(reported_loc.long - current_loc.long).abs <= tol 

wo tol einige vorgegebene Toleranz ist, zum Beispiel 0.0001.

2

Ein GPS-Empfänger kann mit einer Genauigkeit von vielen Dezimalstellen einen Ort geben, aber das tut nicht bedeuten, dass die Messung tatsächlich so genau ist.

Normalerweise liegen etwa 95% der Messungen innerhalb eines Kreises von einigen Metern, was etwa der Genauigkeit entspricht, die Sie mit einem 32-Bit-Float speichern können.

Sie werden jedoch deutlich Rundungsfehler feststellen, wenn Sie ein GPS-Protokoll als Floats auf einer Karte plotten.

Um diesen Vergleich durchzuführen, würde ich einen Bereich verwenden, anstatt den eingehenden Wert zu runden und diesen Wert mit dem Datenbankwert zu vergleichen. Sie werden nicht mehr in der Lage sein, die kleinsten Bewegungen zu erkennen, aber zumindest werden Sie auch keine falsch positiven Ergebnisse mehr bekommen.

Da Sie Floats verwenden, um Dinge zu speichern, ist es Ihnen ohnehin egal, ob Millimeter oder Zentimeter.

Verwandte Themen