Если вы хотите избежать расширения ГИС, я адаптировал функции из этого поста к 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;
используя те из них, вы можете выполнить несколько запросов на окружающие квадраты:
--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)
);
если бы вы использовали его достаточно часто, я уверен, что преобразование операторов в одну функцию будет простым. Хотя я никогда не делал никаких реальных запросов в пределах радиуса.
Для чего-то более сложного вы, вероятно, захотите расширение ГИС, как сказали другие ответы. PostGIS хорош, но я обнаружил, что многие специфические для ГИС функции могут быть трудно получить правильные, и если вы не используете индексы ограничивающего прямоугольника, ваши пространственные запросы могут занять день, если ваш набор данных достаточно большой. Но компромисс между сложностью определенно стоит того, чтобы все такие модные вещи, как вывод ваших данных в формате геоджон и т. Д.