Wie kann ich bei zwei Lat / Long feststellen, ob sie sich innerhalb einer Meile voneinander befinden?

8

Ich versuche, eine sehr effiziente Überprüfung durchzuführen, um festzustellen, ob zwei Punkte innerhalb einer Meile voneinander liegen oder nicht.

Mein aktueller Ansatz besteht darin, die Haversine-Entfernung zu berechnen und dann zu überprüfen, ob sie weniger als eine Meile beträgt .

Effizienz ist in diesem Fall wichtig, da ich dieses Ja / Nein-Flag für große Datensatzmengen berechnen muss.

Es ist mir nur wichtig, ob sie sich innerhalb einer Meile befinden - nichts anderes über die Entfernung ist mir wichtig.

Was ist also der effizienteste Weg, um festzustellen, ob zwei Lat / Long-Punkte innerhalb einer Meile voneinander liegen?

Als Antwort auf die Kommentare mache ich das in SQL Server. Mein Code ist unten.

CREATE FUNCTION dbo.USR_UFN_HAVERSINE_DISTANCE
(
  @LAT1 FLOAT(18)
 ,@LONG1 FLOAT(18)
 ,@LAT2 FLOAT(18)
 ,@LONG2 FLOAT(18)
 ,@UnitOfMeasure NVARCHAR(10) = 'KILOMETERS'
)
RETURNS FLOAT(18)
AS
BEGIN
  DECLARE
    @R FLOAT(8)
   ,@DLAT FLOAT(18)
   ,@DLON FLOAT(18)
   ,@A FLOAT(18)
   ,@C FLOAT(18)
   ,@D FLOAT(18)
   ;
  SET @R =
    CASE @UnitOfMeasure
      WHEN 'MILES'      THEN 3956.55 
      WHEN 'KILOMETERS' THEN 6367.45
      WHEN 'FEET'       THEN 20890584
      WHEN 'METERS'     THEN 6367450
      ELSE 6367.45  --km
    END
  SET @DLAT = RADIANS(@LAT2 - @LAT1);
  SET @DLON = RADIANS(@LONG2 - @LONG1);
  SET @A = SIN(@DLAT / 2) 
         * SIN(@DLAT / 2) 
         + COS(RADIANS(@LAT1))
         * COS(RADIANS(@LAT2)) 
         * SIN(@DLON / 2) 
         * SIN(@DLON / 2);
  SET @C = 2 * ASIN(MIN(SQRT(@A)));
  SET @D = @R * @C;
  RETURN @D;
END;
JosephStyons
quelle
Was hat Ihre Forschung bisher als möglichen Kandidaten ergeben?
PolyGeo
1
Suchen Sie eine Softwarelösung oder erstellen Sie Ihren eigenen Code? Was hast du bisher versucht?
MaryBeth
2
Was ist falsch daran, nur die Haversine-Entfernung zu überprüfen? Sie könnten ein wenig Verarbeitungszeit sparen, indem Sie nur die planare Entfernung überprüfen - bei einer Meile macht Haversine keinen großen Unterschied.
Tom
4
Könnten Sie einfach geomA.STDistance (geomB) <d verwenden?
Ian Turton
2
Die von @Tom vorgeschlagene Überprüfung der "planaren Entfernung" kann leicht falsch interpretiert werden: Um richtig zu funktionieren, muss sie sorgfältig interpretiert werden. Eines ist das Folgende. Angenommen, Sie müssen niemals Punkte über den 180-Grad-Meridian oder die Pole vergleichen, könnten Sie die pythagoreische Formel auf die Koordinaten (lat1, cos (lat1) * lon1), (lat2, cos (lat2) * lon2) anwenden. Mit anderen Worten, wenn Sie (lat1-lat2) ^ 2 + (cos (lat1) * lon1-cos (lat2) * lon2) ^ 2 mit 1/69 ^ 2 (alle in Grad) vergleichen, sehen Sie, ob die beiden Punkte durch getrennt sind eine Meile (mit einer Genauigkeit von einem Bruchteil eines Prozent). Ob dies schneller als Haversine ist, ist unklar.
whuber

Antworten:

2

Probieren Sie diese Methode aus - sie ist möglicherweise nicht die beste, kann jedoch Ihren Suchraum auf wenige beschränken und Ihnen so helfen, den Prozess zu beschleunigen.

  1. Erstellen Sie um jeden Punkt Puffer für eine halbe Meile
  2. Lösen Sie die resultierenden Puffer auf - stellen Sie sicher, dass keine Multipolygone vorhanden sind
  3. Jeder Punkt, der außerhalb dieses Polygons liegt, wird jetzt aus dem Suchraum ausgeschlossen

Stellen Sie sicher, dass Sie räumliche Indizes erstellt haben, und überprüfen Sie, ob durch dieses Verfahren die Antwortzeit für Abfragen verbessert wurde. Sie können den Ansatz auch verfeinern, indem Sie eine Near-Table-Tabelle (ESRI ArcGIS verfügt über ein Tool) mit 1 Meile als Kriterium erstellen.

addcolor
quelle
Puffer müssen einen Radius von einer Meile haben, nicht wahr?
Radouxju
@radouxju, zwei 1/2 Meilen von jedem Punkt ist 1 Meile Entfernung.
Addcolor
1
Ich verstehe es nicht Entweder möchten Sie eine Polygonebene basierend auf einer vordefinierten Menge von Punkten erstellen und dann dieses Polygon mit einem Algorithmus "Punkt in Polygonen" verwenden, um herauszufinden, ob neue Punkte innerhalb einer Meile liegen (dann müssen Sie einen Puffer mit einem Radius von einer Meile berechnen ... Oder arbeiten Sie direkt mit allen Punkten, mit halben Meilenpuffern, lösen Sie auf und wählen Sie dann die isolierten Puffer basierend auf der Fläche aus (die Sie berechnen müssen). Beachten Sie, dass 1) das Erstellen echter 1-Meilen-Puffer ziemlich teuer ist 2) das Auflösen ist ziemlich teuer. Nur Option 1 macht für mich Sinn, wenn Sie die Polygone mehrmals wiederverwenden.
Radouxju
2

Wenn Sie global arbeiten, können Sie durch einfaches, unkompliziertes Testen vermeiden, viele Sünden und Kosten zu berechnen:

Der erste Test zum Herausfiltern von Punkten vor der Berechnung von Haversine besteht darin, einen Punkt auszuschließen, an dem @DLAT> 0,015 Grad ist (könnte genauer sein, aber ich bevorzuge Sicherheit).

In einem zweiten Schritt können Sie dies auch mit @DLON in einem bestimmten Breitengradbereich mit einem konservativen Wert tun (z. B. zwischen -60 und 60 Grad, @DLON> 0,03 ausschließen (= 0,015 / cos (60)).

Da 1 Meilen ziemlich klein ist, müssen Sie Haversine nur selten mit diesen beiden Regeln berechnen (außer wenn Sie an Polargebieten arbeiten), und Sie können Haversine wie erwähnt durch Pythagoreisch ersetzen (2 Cosinus vs 2 Sinus und 2 Cosinus durch Haversinus) von @whuber.

Radouxju
quelle