Я должен согласиться с ответом Делавена, но использование st_distance само по себе будет очень медленным . Таким образом, чтобы ускорить процесс, вам придется использовать индексы GIST (обратите внимание большинство функций PostGIS, включая st_distance НЕ использовать индексы см .: рекомендация по индексированию Postgis ).
Таким образом, вы сначала создали бы буфер вокруг точки, а затем отметили его ограничивающий прямоугольник, используя «&&» (это использует встроенный индекс GIST - так он будет работать намного лучше), а затем вы проверили бы расстояние с помощью «st_distance». ».
Например, чтобы получить ближайший «ресторан» из заданного расположения кухни (например, X = 1, Y = 1), вы должны написать:
select *,st_distance(the_geom_col,st_geomfromtext('POINT(1 1)',27700)) as distance
from restaurants where st_buffer(st_geomfromtext('POINT(1 1)',27700),100)
&& "the_geom_col"
Это было бы очень быстро по сравнению с "st_distance", но результаты могут содержать рестораны, которые находятся на расстоянии более 100 метров от заданного местоположения (особенно, когда геометрии сохраняются в линейных или полигональных форматах).
Чтобы получить более точные результаты, в ресторанах с точным радиусом действия 100 метров, вы добавляете , следуя приведенному выше запросу:
and st_distance(the_geom_col,st_geomfromtext('POINTFROMTEXT(1 1)',27700)) <= 100
Это все равно будет более эффективным и быстрым, чем само использование st_distance . Поскольку база данных будет работать только st_distance против записей, которые соответствуют первым критериям.
Так что, как правило, всякий раз, когда вам приходится выполнять дорогостоящие пространственные поиски, старайтесь:
- Отфильтруйте как можно больше ложных результатов, используя специальные операторы (см. Специальные операции в официальных документах postgis .
- Затем напишите фактическую функцию проверки пространственных отношений.
- Всегда иметь индекс GIST в столбце "геометрия".
- Добавьте ограничивающие рамки к вашим «геометриям», используя st_addbbox .
- Регулярно переиндексируйте и анализируйте ваши таблицы.
Примечание. Размер буфера или фактическое расстояние должны соответствовать проекционной системе, которую вы используете, т. Е. Если вы используете EPSG: 4326 (широта / долгота), то вы должны указать эти расстояния в градусах. Например
1 метр в реальном мире = 0,00000899 градусов .. и 100 метров = сделать математику:)