sql >> Database >  >> RDS >> Mysql

Zoek de afstand tussen twee punten met behulp van de lengte- en breedtegraad in mysql

Ik denk dat je vraag zegt dat je de city . hebt waarden voor de twee steden waartussen u de afstand wilt berekenen.

Deze zoekopdracht zal het werk voor u doen en de afstand in km opleveren. Het gebruikt de formule van de sferische cosinuswet.

Merk op dat je de tabel met zichzelf samenvoegt, zodat je twee coördinatenparen voor de berekening kunt ophalen.

SELECT a.city AS from_city, b.city AS to_city, 
   111.111 *
    DEGREES(ACOS(LEAST(1.0, COS(RADIANS(a.Latitude))
         * COS(RADIANS(b.Latitude))
         * COS(RADIANS(a.Longitude - b.Longitude))
         + SIN(RADIANS(a.Latitude))
         * SIN(RADIANS(b.Latitude))))) AS distance_in_km
  FROM city AS a
  JOIN city AS b ON a.id <> b.id
 WHERE a.city = 3 AND b.city = 7

Merk op dat de constante 111.1111 is het aantal kilometers per breedtegraad, gebaseerd op de oude Napoleontische definitie van de meter als een tienduizendste van de afstand van de evenaar tot de pool. Die definitie is dichtbij genoeg voor locatiezoekerwerk.

Als u mijlen wilt in plaats van kilometers, gebruik dan 69.0 in plaats daarvan.

http://sqlfiddle.com/#!9/21e06/412/0

Als u op zoek bent naar punten in de buurt, kunt u in de verleiding komen om een ​​clausule als volgt te gebruiken:

   HAVING distance_in_km < 10.0    /* slow ! */
    ORDER BY distance_in_km DESC

Dat is (zoals we zeggen in de buurt van Boston MA USA) wicked slow.

In dat geval moet u een begrenzingsvakberekening gebruiken. Zie dit artikel over hoe dat te doen. http://www.plumislandmedia.net/mysql/haversine-mysql- dichtstbijzijnde-loc/

De formule bevat een LEAST() functie. Waarom? Omdat de ACOS() functie geeft een fout als zijn argument zelfs iets groter is dan 1. Wanneer de twee punten in kwestie heel dicht bij elkaar liggen, wordt de uitdrukking met de COS() en SIN() berekeningen kunnen soms een waarde opleveren die iets groter is dan 1 vanwege floating-point epsilon (onnauwkeurigheid ). De LEAST(1.0, dirty-great-expression) oproep lost dat probleem op.

Er is een betere manier, een formule door Thaddeus Vincenty . Het gebruikt ATAN2() in plaats van ACOS() dus het is minder vatbaar voor epsilon-problemen.



  1. Ik krijg een Er is een poging gedaan om een ​​programma te laden met een onjuiste indelingsfout op een SQL Server-replicatieproject

  2. Grote objecten mogen niet worden gebruikt in de modus voor automatisch vastleggen

  3. Mysqladmin flush-hosts uitvoeren op Amazon RDS

  4. Converteer 'datetimeoffset' naar 'datetime2' in SQL Server (T-SQL-voorbeelden)