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

Sortieren der MySQL-Abfrage nach Breitengrad/Längengrad

Erinnerst du dich an Pythagoras?

$sql = "SELECT * FROM table 
    WHERE lon BETWEEN '$minLon' AND '$maxLon' 
      AND lat BETWEEN '$minLat' AND '$maxLat'
    ORDER BY (POW((lon-$lon),2) + POW((lat-$lat),2))";

Technisch gesehen ist das das Quadrat der Entfernung anstelle der tatsächlichen Entfernung, aber da Sie es nur zum Sortieren verwenden, spielt das keine Rolle.

Dies verwendet die planare Entfernungsformel, die für kleine Entfernungen gut sein sollte.

JEDOCH:

Wenn Sie genauer sein oder längere Entfernungen verwenden möchten, verwenden Sie diese Formel für Großkreisentfernungen im Bogenmaß :

dist = acos[ sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lng1-lng2) ]

(Um die Entfernung in echten Einheiten statt in Radianten zu erhalten, multiplizieren Sie sie mit dem Radius der Erde. Dies ist jedoch für Bestellzwecke nicht erforderlich.)

Breiten- und Längengrade werden von der MySQL-Berechnungs-Engine als Bogenmaß angenommen. Wenn sie also in Grad gespeichert sind (und das ist wahrscheinlich der Fall), müssen Sie jeden Wert mit pi/180 multiplizieren, ungefähr 0,01745:

$sf = 3.14159 / 180; // scaling factor
$sql = "SELECT * FROM table 
    WHERE lon BETWEEN '$minLon' AND '$maxLon' 
      AND lat BETWEEN '$minLat' AND '$maxLat'
    ORDER BY ACOS(SIN(lat*$sf)*SIN($lat*$sf) + COS(lat*$sf)*COS($lat*$sf)*COS((lon-$lon)*$sf))";

oder sogar:

$sf = 3.14159 / 180; // scaling factor
$er = 6350; // earth radius in miles, approximate
$mr = 100; // max radius
$sql = "SELECT * FROM table 
    WHERE $mr >= $er * ACOS(SIN(lat*$sf)*SIN($lat*$sf) + COS(lat*$sf)*COS($lat*$sf)*COS((lon-$lon)*$sf))
    ORDER BY ACOS(SIN(lat*$sf)*SIN($lat*$sf) + COS(lat*$sf)*COS($lat*$sf)*COS((lon-$lon)*$sf))";