MySQL: Afstand-berekeningen met longitude en latitude

Met de komst van de mogelijkheid om met de browser de locatie van een gebruiker te bepalen hebben steeds meer websites locatie ondersteuning. Om deze manier kan informatie die belangrijk is voor de gebruiker worden getoond. Denk hierbij aan slaapplaatsen in de buurt bij Airbnb en restaurants in de buurt bij Whatsfood.

Met MySQL is het mogelijk om een query te schrijven die records selecteert die binnen een bepaalde afstand vanaf een vooraf ingesteld punt liggen. Aan de hand van een voorbeeld zal in dit artikel worden laten zien hoe een MySQL query met afstand-berekening kan worden ingezet.

De database

Stel er is een database tabel "aanbiedingen" die bestaat uit de kolommen: "id", "aanbieding", "latitude" en "longitude". In deze tabel worden aanbiedingen opgeslagen en voorzien van een locatie op de kaart.

De query

Stel je wilt alle aanbiedingen vanaf de locatie van een gebruiker van de website. Aanbiedingen die verder liggen dan 5 kilometer zijn niet belangrijk en hoeven niet getoond te worden. In onderstaand voorbeeld is de gebruiker precies in het midden van Amsterdam op de coördinaten 52.370216, 4.895168 . Deze coördinaten zijn de latitude en longitude van de locatie. (breedte en lengtegraden).

Afstand in miles

SELECT aanbiedingen.*,
(((acos(sin((52.370216*pi()/180)) * 
            sin((latitude*pi()/180))+cos((52.370216*pi()/180)) * 
            cos((latitude*pi()/180)) * cos(((4.895168- longitude)* 
            pi()/180))))*180/pi())*60*1.1515
        ) as afstand 
FROM aanbiedingen
HAVING afstand < 5
ORDER BY afstand ASC

De berekening in bovenstaande query is echter nog niet volledig. De afstand tussen aanbiedingen en de locatie van de gebruiker is nu berekent in Miles in plaats van Kilometers. Door de query uit te breiden kan van de afstand in miles een afstand worden gemaakt in kilometers. 1 mile is 1.6 kilometer, de aanpassing is daarom als volgt:

Afstand in kilometers

SELECT aanbiedingen.*,
(((acos(sin((52.370216*pi()/180)) * 
            sin((latitude*pi()/180))+cos((52.370216*pi()/180)) * 
            cos((latitude*pi()/180)) * cos(((4.895168- longitude)* 
            pi()/180))))*180/pi())*60*1.1515
        ) * 1.6 as km_afstand 
FROM aanbiedingen
HAVING km_afstand < 5
ORDER BY km_afstand ASC