PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Ottenere tutti gli edifici entro un raggio di 5 miglia dalle coordinate specificate

Perché stai memorizzando x,y in colonne separate? Ti consiglio vivamente di memorizzarli come geometry o geography per evitare un sovraccarico di casting non necessario in fase di query.

Detto questo, puoi calcolare e controllare le distanze in miglia usando ST_DWithin o ST_Distance :

(Dati di prova)

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 restituisce true se le geometrie date si trovano entro la distanza specificata da un'altra. La seguente query ricerca le geometrie che si trovano in un raggio di 5 miglia da POINT(-4.6314 54.0887) :

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_Distanza

La funzione ST_Distance (con geography tipo parametri) restituirà la distanza in metri . Usando questa funzione tutto ciò che devi fare è convertire i metri in miglia alla fine.

Attenzione :Distanze nelle query che utilizzano ST_Distance sono calcolati in tempo reale e pertanto non utilizzano l'indice spaziale . Pertanto, non è consigliabile utilizzare questa funzione in WHERE clausola! Usalo piuttosto in SELECT clausola. Tuttavia l'esempio seguente mostra come si potrebbe fare:

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)
  • Controlla l'ordine dei parametri con ST_MakePoint :È longitudine, latitudine.. non viceversa.

Demo:db<>fiddle

Equivalente Amazon Athena (distanza in gradi):

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;