Finden Sie mit MySQL Punkte in einiger Entfernung


20

Ich habe eine mySQL-Tabelle mit Benutzername, Breite und Länge des Benutzers. Ich möchte eine Liste von Benutzern erhalten, die sich innerhalb des Kreises oder Quadrats eines bestimmten Breiten- und Längengrads mit einem bestimmten Abstand befinden. Zum Beispiel meine Eingabe Lat = 78,3232 und Long = 65,3234 und Entfernung = 30 Meilen. Ich möchte die Liste der Benutzer erhalten, die sich innerhalb von 30 Meilen Entfernung von den Punkten 78.3232 und 65.3234 befinden. Ist es möglich, dies mit einer einzigen Abfrage zu lösen? Oder können Sie mir einen Tipp geben, wie ich diese Frage lösen kann? Ich bin neu in den geobasierten Informationen.


Warum nicht PostGIS? Wenn Sie ein Geo-Projekt starten, können Sie Ihren Stack trotzdem ändern
simplexio

stackoverflow.com/a/40272394/1281385 Sollte hilfreich sein, um diese Abfrage zu beschleunigen (falls erforderlich)
exussum

Antworten:


32

Die SQL-Anweisung, mit der die nächsten 20 Positionen innerhalb eines Radius von 30 Meilen zur Koordinate 78.3232, 65.3234 gefunden werden. Es berechnet die Entfernung basierend auf der Breite / Länge dieser Zeile und der geografischen Breite / Länge des Ziels und fragt dann nur Zeilen ab, in denen der Entfernungswert weniger als 30 Meilen beträgt, ordnet die gesamte Abfrage nach Entfernung und begrenzt sie auf 20 Ergebnisse. Um nach Kilometern anstatt nach Meilen zu suchen, ersetzen Sie 3959 durch 6371.

SELECT
  id, (
    3959 * acos (
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
  ) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;

Hierbei wird die Google Maps API v3 mit einem MySQL-Backend verwendet, über das Sie bereits verfügen.

https://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql


Ich erhalte einen Syntaxfehler in meiner Auswahl, wenn ich dies verwende. "# 1582 - Falsche Parameteranzahl beim Aufruf der nativen Funktion 'radians', was könnte das sein?
bluantinoo

Gefunden: Ich hatte die Variable lng leer! Es tut uns leid!
Bluantinoo

Genau das, was ich wollte, aber was ist die Überlastung der Abfrageleistung für Tausende von Datensätzen? und wie steht es mit der Genauigkeit?
Amit Shah

1
viel besser, es zu 6371392.896 für die Suche nach Metern zu ersetzen
Vasilii Suricov

34

Die Antwort von Mapperz ist ungültig. Der Sinus muss aus dem Breitengrad und NICHT aus dem Längengrad berechnet werden. Die korrekte SQL-Anweisung lautet also:

SELECT
    id, (
      3959 * acos (
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
LIMIT 0 , 20;

Ihre Antwort sollte zuerst bestellt werden.
Amit Shah

@AmitShah Wenn Sie der Meinung sind, dass Sie den Fragesteller (@shihabK, der seit fast 6 Jahren nicht mehr auf der Website aktiv ist) anpingen
PolyGeo

Dies sollte die akzeptierte Antwort sein.
catbadger

2

Es kann eine Basis sein, um eine Funktion zu erstellen, damit Sie sie in anderen Bereichen wiederverwenden können. Würde auch deine Abfrage ein bisschen sauberer machen ... Zumindest sind das meine 2 Cent.

DELIMITER $$

create function calcDistance(lat float, lng float, pnt_lat float, pnt_lng float)

Returns float
BEGIN

Declare dist float;
SET dist =
  3959 * acos (
  cos ( radians(pnt_lat) )
  * cos( radians( lat ) )
  * cos( radians( lng ) - radians(pnt_lng) )
  + sin ( radians(pnt_lat) )
  * sin( radians( lat ) )
);

RETURN dist;

END

Die Antwort wird positiv bewertet, wenn Sie den Codestyle korrigieren. es ist der richtige Weg
Vasilii Suricov

0

Hier ist meine Variante der Abfrage, scheint ein bisschen einfacher ( http://dexxtr.com/post/83498801191/how-to-determine-point-inside-circle-using-mysql )

SELECT 
    *
FROM 
    `locator`
WHERE
    SQRT(POW(X(`center`) - 49.843317 , 2) + POW(Y(`center`) - 24.026642, 2)) * 100 < `radius`

4
Es ist einfacher, ignoriert aber die Tatsache, dass die Erde gekrümmt ist.
Tim Rijavec,

Benötigen Sie eine Formel, um genau zu sein. Vielleicht wäre das nur auf kurzen Strecken gut: D
Jethro

Wirst du eine Rakete abschießen oder so?
Dennis Braga

1
@DennisBraga - wenn ja, dann ist diese Frage vielleicht nicht zum Thema, besser geeignet für http://globalthermonuclearwar.stackexchange.com ...?
Ashleedawg
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.