MySQL: Afstand-berekeningen met longitude en latitude

MySQL: Afstand-berekeningen met longitude en latitude

Dit artikel is ouder dan vier jaar. De inhoud kan verouderd zijn, vooral bij technische voorbeelden of verwijzingen naar tooling.

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

Reacties

Er zijn nog geen reacties, laat je reactie achter.

Laat een reactie achter

Heb je een aanvulling, vraag of eigen ervaring bij dit artikel? Deel hem hieronder.

Reacties worden eerst kort gecontroleerd voordat ze zichtbaar zijn.

Bekijk alle artikelen

The bullshit of code coverage

A test suite can reach 100% coverage and still charge the wrong shipping fee or take a payment twice. Through boundary cases, misleading mocks and missing requirements, I examine what coverage actually proves. The useful question is not whether the code ran, but whether the tests would catch the mistakes your customers care about.

Continue reading

When a monorepo slows you down

Nx can make builds faster while shared code leaves your team waiting for someone else's priorities. Drawing on my experience, I examine the coordination cost behind a tidy monorepo, the difference between useful reuse and forced abstractions, and how DRY can work against simplicity. The question is whether the architecture helps teams deliver, not just share code.

Continue reading

Security by design in Angular

Security by design in Angular

A route guard and a green pipeline do not stop one customer reading another customer's invoice. Using Angular and a .NET API, I turn a security requirement into server-side ownership checks and tests. Security by design starts with boundaries and evidence, before choosing a scanner.

Continue reading