Ich habe ein funktionierendes PHP-Skript, das Longitude- und Latitude-Werte abruft und diese dann in eine MySQL-Abfrage eingibt. Ich möchte es nur MySQL machen. Hier ist mein aktueller PHP-Code:
if ($distance != "Any" && $customer_zip != "") { //get the great circle distance
//get the origin zip code info
$zip_sql = "SELECT * FROM zip_code WHERE zip_code = '$customer_zip'";
$result = mysql_query($zip_sql);
$row = mysql_fetch_array($result);
$origin_lat = $row['lat'];
$origin_lon = $row['lon'];
//get the range
$lat_range = $distance/69.172;
$lon_range = abs($distance/(cos($details[0]) * 69.172));
$min_lat = number_format($origin_lat - $lat_range, "4", ".", "");
$max_lat = number_format($origin_lat + $lat_range, "4", ".", "");
$min_lon = number_format($origin_lon - $lon_range, "4", ".", "");
$max_lon = number_format($origin_lon + $lon_range, "4", ".", "");
$sql .= "lat BETWEEN '$min_lat' AND '$max_lat' AND lon BETWEEN '$min_lon' AND '$max_lon' AND ";
}
Weiß jemand, wie man dies vollständig zu MySQL macht? Ich habe ein bisschen im Internet gestöbert, aber die meiste Literatur darüber ist ziemlich verwirrend.
php
mysql
great-circle
Nick Woodhams
quelle
quelle
Antworten:
Aus den häufig gestellten Fragen zu Google Code - Erstellen eines Store Locator mit PHP, MySQL und Google Maps :
quelle
markers
Tabelle mit den Feldern id, lan und lng haben.$greatCircleDistance = acos( cos($latitude0) * cos($latitude1) * cos($longitude0 - $longitude1) + sin($latitude0) * sin($latitude1));
mit Längen- und Breitengrad im Bogenmaß.
so
ist Ihre SQL-Abfrage
Um Ihre Ergebnisse in km oder Meilen zu erhalten, multiplizieren Sie das Ergebnis mit dem mittleren Radius der Erde (
3959
Meilen,6371
km oder3440
Seemeilen).Das, was Sie in Ihrem Beispiel berechnen, ist ein Begrenzungsrahmen. Wenn Sie Ihre Koordinatendaten in eine räumlich aktivierte MySQL-Spalte einfügen , können Sie die integrierten Funktionen von MySQL verwenden, um die Daten abzufragen.
quelle
Wenn Sie der Koordinatentabelle Hilfsfelder hinzufügen, können Sie die Antwortzeit der Abfrage verbessern.
So was:
Wenn Sie TokuDB verwenden, erzielen Sie eine noch bessere Leistung, wenn Sie Clustering-Indizes für eines der Prädikate hinzufügen, z. B.:
Sie benötigen für jeden Punkt das Basislat und Lon in Grad sowie sin (lat) im Bogenmaß, cos (lat) * cos (lon) im Bogenmaß und cos (lat) * sin (lon) im Bogenmaß. Dann erstellen Sie eine MySQL-Funktion, wie folgt:
Dies gibt Ihnen die Entfernung.
Vergessen Sie nicht, einen Index für lat / lon hinzuzufügen, damit das Begrenzungsfeld die Suche unterstützen kann, anstatt es zu verlangsamen (der Index wurde bereits in der obigen Abfrage CREATE TABLE hinzugefügt).
Bei einer alten Tabelle mit nur Lat / Lon-Koordinaten können Sie ein Skript einrichten, um es folgendermaßen zu aktualisieren: (PHP mit Meekrodb)
Anschließend optimieren Sie die eigentliche Abfrage so, dass die Entfernungsberechnung nur dann durchgeführt wird, wenn sie wirklich benötigt wird, indem Sie beispielsweise den Kreis (gut, oval) von innen und außen begrenzen. Dazu müssen Sie mehrere Metriken für die Abfrage selbst vorberechnen:
In Anbetracht dieser Vorbereitungen geht die Abfrage ungefähr so (php):
EXPLAIN in der obigen Abfrage könnte bedeuten, dass kein Index verwendet wird, es sei denn, es gibt genügend Ergebnisse, um einen solchen auszulösen. Der Index wird verwendet, wenn die Koordinatentabelle genügend Daten enthält. Sie können FORCE INDEX (lat_lon_idx) zum SELECT hinzufügen, damit es den Index ohne Rücksicht auf die Tabellengröße verwendet, sodass Sie mit EXPLAIN überprüfen können, ob er ordnungsgemäß funktioniert.
Mit den obigen Codebeispielen sollten Sie eine funktionierende und skalierbare Implementierung der Objektsuche nach Entfernung mit minimalem Fehler haben.
quelle
Ich musste das etwas genauer ausarbeiten, also werde ich mein Ergebnis teilen. Dies verwendet eine
zip
Tabelle mitlatitude
undlongitude
Tabellen. Es hängt nicht von Google Maps ab. Vielmehr können Sie es an jede Tabelle anpassen, die lat / long enthält.Sehen Sie sich diese Zeile in der Mitte dieser Abfrage an:
Dies sucht nach den 30 nächsten Einträgen in der
zip
Tabelle innerhalb von 50,0 Meilen vom Lat / Long-Punkt 42.81 / -70.81. Wenn Sie dies in eine App einbauen, geben Sie dort Ihren eigenen Punkt und Suchradius ein.Wenn Sie in Kilometern anstatt in Meilen arbeiten möchten, wechseln Sie in der Abfrage
69
zu111.045
und3963.17
zu6378.10
.Hier ist eine detaillierte Beschreibung. Ich hoffe es hilft jemandem. http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/
quelle
Ich habe eine Prozedur geschrieben, die dasselbe berechnen kann, aber Sie müssen den Breiten- und Längengrad in die entsprechende Tabelle eingeben.
quelle
Ich kann die obige Antwort nicht kommentieren, aber sei vorsichtig mit der Antwort von @Pavel Chuchuva. Diese Formel gibt kein Ergebnis zurück, wenn beide Koordinaten gleich sind. In diesem Fall ist der Abstand null, sodass diese Zeile nicht mit dieser Formel zurückgegeben wird.
Ich bin kein MySQL-Experte, aber das scheint für mich zu funktionieren:
quelle
ACOS(1)
0). Sie könnten sehen Probleme mit der x - Achse * xaxis + yaxis * yaxis + zaxis * zaxis gehen außerhalb des Bereichs für ACOS Runden , aber sie scheinen nicht gegen die Bewachung zu werden?für eine Entfernung von 25 km
quelle
Ich dachte, meine Javascript-Implementierung wäre ein guter Hinweis auf:
quelle
Berechnen Sie die Entfernung in MySQL
Somit wird der Entfernungswert berechnet und jeder kann sich nach Bedarf bewerben.
quelle