Waarom bewaar je x,y in gescheiden kolommen? Ik raad je ten zeerste aan om ze op te slaan als geometry
of geography
om onnodige castingoverhead in de querytijd te voorkomen.
Dat gezegd hebbende, kunt u afstanden in mijlen berekenen en controleren met ST_DWithin
of ST_Distance
:
(Testgegevens)
CREATE TABLE building (name text, long numeric, lat numeric);
INSERT INTO building VALUES ('Kirk Michael',-4.5896,54.2835);
INSERT INTO building VALUES ('Baldrine',-4.4077,54.2011);
INSERT INTO building VALUES ('Isle of Man Airport',-4.6283,54.0804);
ST_DWithin
ST_DWithin
geeft true terug als de gegeven geometrieën binnen de gespecificeerde afstand van elkaar liggen. De volgende zoekopdracht zoekt naar geometrieën die zich in een straal van 5 mijl van POINT(-4.6314 54.0887)
bevinden :
SELECT name,long,lat,
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 AS distance
FROM building
WHERE
ST_DWithin('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat),8046.72); -- 8046.72 metres = 5 miles;
name | long | lat | distance
---------------------+---------+---------+-------------------
Isle of Man Airport | -4.6283 | 54.0804 | 0.587728347062174
(1 row)
ST_Distance
De functie ST_Distance
(met geography
type parameters) retourneert de afstand in meters . Met deze functie hoef je alleen maar meters om te zetten in mijlen.
Let op :Afstanden in zoekopdrachten met ST_Distance
worden in realtime berekend en daarom gebruik geen ruimtelijke index . Het wordt dus niet aanbevolen om deze functie te gebruiken in de WHERE
clausule! Gebruik het liever in de SELECT
clausule. Niettemin laat het onderstaande voorbeeld zien hoe het zou kunnen:
SELECT name,long,lat,
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 AS distance
FROM building
WHERE
ST_Distance('POINT(-4.6314 54.0887)'::geography,
ST_MakePoint(long,lat)) * 0.000621371 <= 5;
name | long | lat | distance
---------------------+---------+---------+-------------------
Isle of Man Airport | -4.6283 | 54.0804 | 0.587728347062174
(1 row)
- Let op de volgorde van de parameters met
ST_MakePoint
:Het is lengtegraad, breedtegraad.. niet andersom.
Demo:db<>fiddle
Amazon Athena-equivalent (afstand in graden):
SELECT *, ST_DISTANCE(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
ST_POINT(long,lat)) AS distance
FROM building
WHERE
ST_Distance(ST_GEOMETRY_FROM_TEXT('POINT(-84.386330 33.753746)'),
ST_POINT(long,lat)) <= 5;