Frage

In PHP habe ich den folgenden Code zur Berechnung der Entfernung zwischen zwei Orten:

<?php
function distance($lat1, $long1, $lat2, $long2) {
    // DEGREE TO RADIAN
    $latitude1 = $lat1/180*pi();
    $longitude1 = $long1/180*pi();
    $latitude2 = $lat2/180*pi();
    $longitude2 = $long2/180*pi();
    // FORMULA: e = ARCCOS ( SIN(Latitude1) * SIN(Latitude2) + COS(Latitude1) * COS(Latitude2) * COS(Longitude2-Longitude1) ) * EARTH_RADIUS
    $distance = acos(sin($latitude1)*sin($latitude2)+cos($latitude1)*cos($latitude2)*cos($longitude2-$longitude1))*6371;
    return $distance;
}
echo distance(9.9921962, 53.5534074, 9.1807688, 48.7771056); // Hamburg, DE - Stuttgart, DE
?>

Aber jetzt möchte ich über PHP aus meiner MySQL-Datenbank Standorte in der Nähe eines bestimmten Standorts auswählen:

  • Der Benutzer gibt seinen Heimatort ein
  • Mein Skript ruft die Breiten-/Längengrade über die Google API ab
  • In meiner Datenbank habe ich etwa 200 Standorte mit einem Feld für den Breitengradwert und einem Feld für den Längengradwert
  • Ich benötige einen Code für PHP und MySQL, um die 10 Standorte auszuwählen, die der Heimatstadt des Benutzers am nächsten liegen

Ich hoffe ihr könnt mir helfen.Dank im Voraus!

War es hilfreich?

Lösung

MySQL Großkreisentfernung (Haversine Formel) genau das tut, was Sie brauchen .

200 Datensätze mit, aber Sie können auch laden Sie sie einfach alle und überprüfen Sie sie mit dem Code. Der Datensatz ist wirklich viel zu klein zu viel vs Code oder jede andere solche Optimierungen über Datenbank besorgniserregend zu sein.

Berechnung Abstand zwischen Postleitzahlen in PHP ein paar hat von PHP-Implementierungen dieses Algorithmus.

Geo Proximity Search ist so ziemlich genau das gleiche Problem, das Sie haben.

Andere Tipps

Vielleicht so etwas wie

SELECT field1, field2, ...,
    ACOS(SIN(latitude / 180 * PI()) * SIN(:1) + COS(latitude / 180 * PI()) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

oder

SELECT field1, field2, ...,
    ACOS(SIN(RADIANS(latitude)) * SIN(:1) + COS(RADIANS(latitude)) * COS(:2) * COS(:2 - longtidude)) * 6371 AS distance
    ORDER BY distance ASC;

(direkt aus dem PHP-Code übersetzt)

:1 Und :2 Ist $lat2/180*pi() Und $long2/180*pi() jeweils.

Das ist die Haversine Formel. Sie können die PHP direkt in SQL übersetzen, so dass Sie die Datenbank räumlich abfragen können (die Alternative ist, jeden Datensatz aus der DB zu ziehen und die Daten durch PHP laufen). MySQL bietet alle Funktionen Mathematik, die Sie benötigen.

Ich tue dies für eine kommerzielle Website, die post / zipcode bereitgestellt basierten Fern Lookups, so seine durchaus möglich, ohne spezielle GIS-Funktionen.

Es gibt MySQL-Funktionen zur Verfügung zu tun genau dies.

http://dev.mysql.com/doc /refman/5.0/en/gis-introduction.html

MySQL hat die Fähigkeit, Indexzeilen georäumlich. Sie werden vielleicht nicht selbst diese Mathe tun müssen (man kann nur MySQL fragen Sie den Abstand zwischen zwei geo-Objekte und sortieren nach, dass zu berechnen ..).

Siehe auch: http://forums.mysql.com/read.php ? 23,159205,159205

Ich bin gerade ein Quer dieses Thema. Vielleicht wird jemand in dieser Funktion interessiert sein, getestet in MySql 5.7:

    create function GetDistance(lat1 real, lng1 real, lat2 real, lng2 real) returns real no sql
    return ATAN2(SQRT(POW(COS(RADIANS(lat2)) * SIN(RADIANS(lng1 - lng2)), 2) + 
                POW(COS(RADIANS(lat1)) * SIN(RADIANS(lat2)) - SIN(RADIANS(lat1)) *
                COS(RADIANS(lat2)) *  COS(RADIANS(lng1 - lng2)), 2)), 
                (SIN(RADIANS(lat1)) * SIN(RADIANS(lat2)) + COS(RADIANS(lat1)) *
                COS(RADIANS(lat2)) * COS(RADIANS(lng1 - lng2)))) * 6372.795;

Berufung:

select GetDistance(your_latitude, your_longitude, table_field_lat,
                   table_field_lng) as dist from [your_table] limit 5;

Warum Sie nicht verwenden MySQL Geospatial-Funktionen ...? Nein, nur ein Scherz.

Wenn die 200 Datensätze sind tatsächliche Orte wie Städte, etc dann als Alternative könnten Sie GeoNames' API verwenden?

Die folgenden WebService werden die 10 am nächsten Stellen mit dem lat und lng liefern zu finden:

http://ws.geonames.org/findNearby?lat=47.3&lng = 9

Quelle: http://www.geonames.org/export/web -services.html # findNearbyPlaceName

Die ganze Liste: http://www.geonames.org/export/ws- overview.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top