Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Finden Sie die Entfernung zwischen zwei Punkten mit Längen- und Breitengrad in mysql

Ich denke, Ihre Frage besagt, dass Sie die city haben Werte für die beiden Städte, zwischen denen Sie die Entfernung berechnen möchten.

Diese Abfrage erledigt die Arbeit für Sie und liefert die Entfernung in km. Es verwendet die Formel des sphärischen Kosinusgesetzes.

Beachten Sie, dass Sie die Tabelle mit sich selbst verknüpfen, sodass Sie zwei Koordinatenpaare für die Berechnung abrufen können.

SELECT a.city AS from_city, b.city AS to_city, 
   111.111 *
    DEGREES(ACOS(LEAST(1.0, COS(RADIANS(a.Latitude))
         * COS(RADIANS(b.Latitude))
         * COS(RADIANS(a.Longitude - b.Longitude))
         + SIN(RADIANS(a.Latitude))
         * SIN(RADIANS(b.Latitude))))) AS distance_in_km
  FROM city AS a
  JOIN city AS b ON a.id <> b.id
 WHERE a.city = 3 AND b.city = 7

Beachten Sie, dass die Konstante 111.1111 ist die Anzahl der Kilometer pro Breitengrad, basierend auf der alten napoleonischen Definition des Meters als ein Zehntausendstel der Entfernung vom Äquator zum Pol. Diese Definition ist nah genug für die Standortsuche.

Wenn Sie gesetzlich vorgeschriebene Meilen anstelle von Kilometern wünschen, verwenden Sie 69.0 stattdessen.

http://sqlfiddle.com/#!9/21e06/412/0

Wenn Sie nach Punkten in der Nähe suchen, könnten Sie versucht sein, eine Klausel wie diese zu verwenden:

   HAVING distance_in_km < 10.0    /* slow ! */
    ORDER BY distance_in_km DESC

Das ist (wie wir in der Nähe von Boston MA USA sagen) verdammt langsam.

In diesem Fall müssen Sie eine Bounding-Box-Berechnung verwenden. In diesem Artikel erfahren Sie, wie das geht. http://www.plumislandmedia.net/mysql/haversine-mysql- nächster-ort/

Die Formel enthält ein LEAST() Funktion. Wieso den? Denn der ACOS() Funktion wirft einen Fehler, wenn ihr Argument auch nur geringfügig größer als 1 ist. Wenn die beiden fraglichen Punkte sehr nahe beieinander liegen, wird der Ausdruck mit dem COS() und SIN() Berechnungen können aufgrund von Gleitkomma-Epsilon (Ungenauigkeit ) manchmal einen Wert etwas größer als 1 ergeben ). Der LEAST(1.0, dirty-great-expression) call bewältigt dieses Problem.

Es gibt einen besseren Weg, eine Formel von Thaddeus Vincenty . Es verwendet ATAN2() statt ACOS() daher ist es weniger anfällig für Epsilon-Probleme.