PostGIS ST_Buffer Radius Справка

9

Я пытаюсь найти все точки в радиусе пяти миль от данной точки. У меня есть такой запрос:

SELECT * FROM table WHERE ST_Contains(ST_Buffer(geomFromText('POINT(0 0)', 4326), ?), latlon)

Я не могу понять, что я поставил вместо ?радиуса, чтобы получить пять миль. Все в EPSG 4326, и согласно документации PostGIS (насколько я могу судить), мой радиус должен быть в метрах. Если я наберу 12 070,0 м (примерно 5 миль), я получу спички по всей стране. Кто-нибудь знает, чего мне не хватает?

Nik
источник
4326 - это дд (десятичные градусы). 12070 - это довольно большая область (радиус), когда она проецируется как латлон.
Брэд Несом
1
неверно - 12 070 метров = 7,49995029 миль, поэтому 5 миль - это 8046,72 метра, поэтому (? = 8046,72) - география или геометрия ваших данных?
Mapperz

Ответы:

14

Поскольку ваши данные не проецируются - это точки на сфероиде - линейные расстояния не имеют смысла. Пять миль на экваторе - намного меньший угол, чем 5 миль на полярном круге. Но, к счастью, PostGIS (> = 1.5) имеет ответ, который вы ищете:

SELECT * FROM table WHERE ST_DWithin(ST_GeogFromText('SRID=4326;POINT(0,0)'), geography(latlon), 12070);

У него есть geographyтип, который предназначен именно для такого рода вещей. Он похож на геометрию, но в нем всегда используется EPSG: 4326, и с ним работает гораздо меньше функций.

В приведенном выше примере я вызвал ST_GeogFromText () (есть также ST_GeographyFromText () , и я не уверен, есть ли разница) в точке интереса (это может работать с обычным WKT, потому что параметр SRID избыточный), и приведите столбец latlon к типу географии. Если вы делаете много из них, может быть более эффективно создать столбец географии в вашей таблице и полностью пропустить приведение. Наконец, ST_DWithin () может принимать параметры географии, и это правильно делает с линейными расстояниями.

MerseyViking
источник
Я ценю помощь. Я все еще довольно новичок в PostGIS.
Ник
4

возможно, вам нужна функция ST_DWithin. см. примечание в документе st_buffer.
ST_Buffer

Люди часто делают ошибку, используя эту функцию, чтобы попытаться выполнить поиск по радиусу. Создание буфера к радиусу поиска происходит медленно и бессмысленно. Вместо этого используйте ST_DWithin .

Брэд Несом
источник