Jeśli chcesz uniknąć rozszerzenia GIS, ja dostosować funkcje z this post do postgres SQL:
create or replace function change_in_lat(miles numeric)
returns double precision as $$
with v as (select
3960.0 as earth_radius,
180/pi() as radians_to_degrees
) select (miles/earth_radius) * radians_to_degrees from v;
$$ language sql
returns null on null input;
create or replace function change_in_long(lat numeric, miles numeric)
returns double precision as $$
with v as (select
3960.0 as earth_radius,
pi()/180 as degrees_to_radians,
180/pi() as radians_to_degrees
) select (
miles/(earth_radius * cos(lat * degrees_to_radians))
) * radians_to_degrees from v;
$$ language sql
returns null on null input;
używając tych można zrobić kilka okolicznych kwadratowych wyszukiwania:
--find all "a"s within 25 miles of any "b"
select * from a join b on (
a.gpslat between
b.gpslat - change_in_lat(25) and b.gpslat + change_in_lat(25)
and a.gpslong between
b.gpslong - change_in_long(b.gpslat::numeric, 25)
and b.gpslong + change_in_long(b.gpslat::numeric, 25)
);
jeśli używał go dość często. Jestem pewien, że przekształcenie instrukcji między dwiema funkcjami w jedną funkcję byłoby łatwe. Jednak nigdy nie robiłem żadnych faktycznych zapytań "w promieniu".
Jeśli chodzi o coś bardziej skomplikowanego, prawdopodobnie będziesz potrzebować rozszerzenia GIS, tak jak inne odpowiedzi. PostGIS jest dobry, ale odkryłem, że wiele funkcji specyficznych dla gis może być trudnych do uzyskania, i jeśli nie wykorzystasz indeksów ograniczających pola, zapytania przestrzenne mogą zająć dzień, jeśli twój zestaw danych będzie wystarczająco duży. Ale kompromis w złożoności jest zdecydowanie warta wszystkich fantazyjnych rzeczy, takich jak wyprowadzanie danych w formacie geojsona, itp.