sql >> Database >  >> RDS >> Mysql

MySQL-query sorteren op breedtegraad/lengtegraad

Herinner je je Pythagoras nog?

$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 gezien is dat het kwadraat van de afstand in plaats van de werkelijke afstand, maar aangezien je het alleen gebruikt om te sorteren, maakt dat niet uit.

Dit maakt gebruik van de planaire afstandsformule, die goed zou moeten zijn over kleine afstanden.

ECHTER:

Als je nauwkeuriger wilt zijn of langere afstanden wilt gebruiken, gebruik dan deze formule voor grote cirkelafstanden in radialen :

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

(Om de afstand in echte eenheden te krijgen in plaats van in radialen, vermenigvuldigt u deze met de straal van de aarde. Dat is echter niet nodig voor besteldoeleinden.)

Breedte- en lengtegraad wordt door de MySQL-berekeningsengine verondersteld in radialen te zijn, dus als het is opgeslagen in graden (en dat is het waarschijnlijk ook), moet je elke waarde vermenigvuldigen met pi/180, ongeveer 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))";

of zelfs:

$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))";


  1. Aggregaten en partitionering

  2. toegang geweigerd voor laadgegevensbestand in MySQL

  3. Stel het resultaat van een query in op een variabele in MySQL

  4. MySQL:Hoe kan ik het MySQL-rootwachtwoord opnieuw instellen of wijzigen?