В PostGIS, как найти все точки в полигоне?
Я использую PostgreSQL с расширением GIS для хранения данных карты вместе с OpenLayers, GeoServer и т.д. Учитывая многоугольник, например, окрестности, мне нужно найти все точки LAT/LONG, хранящиеся в некоторой таблице (например, светофоры, рестораны), которые находятся внутри многоугольника. В качестве альтернативы, заданного набора полигонов, я хотел бы найти множество точек внутри каждого многоугольника (например, запрос GROUP BY, а не итерацию по каждому полигону).
Являются ли эти функции чем-то, что мне нужно для программирования, или доступной функциональностью (как расширенный SQL)? Пожалуйста, уточните.
Также для простых 2D-данных я действительно нуждаюсь в расширении GIS (лицензия GPL является ограничением) или будет достаточно PostgreSQL?
Спасибо!
Ответы
Ответ 1
В PostGIS вы можете использовать оператор ограничивающего прямоугольника для поиска кандидатов, который очень эффективен, так как он использует индексы GiST. Затем, если требуются строгие совпадения, используйте оператор contains.
Что-то вроде
SELECT
points,neighborhood_name from points_table,neighborhood
WHERE
neighborhood_poly && points /* Uses GiST index with the polygon bounding box */
AND
ST_Contains(neighborhood_poly,points); /* Uses exact matching */
О том, если это необходимо, зависит от ваших требований. Для работы над этим вам, разумеется, необходимо установить PostGIS и GEOS. Но, если совпадения с ограничивающим полем достаточно, вы можете закодировать его просто в SQL, не требующем PostGIS.
Если требуются точные соответствия, содержит общедоступные алгоритмы, но для их эффективного использования требуется некоторое усилие, реализующее его в библиотеке, которая затем будет вызываться из SQL (как и GEOS).
Ответ 2
Я считаю, что ST_Contains автоматически перезаписывает запрос, чтобы использовать ограничительную рамку с индексом GiST, поскольку он отмечает:
"Этот вызов функции будет автоматически включают сравнение с ограничивающей ячейкой, которое будут использовать любые индексы, которые доступный по геометрии. Избегать использования индекса, используйте функцию _ST_Contains".
http://postgis.refractions.net/docs/ST_Contains.html
Ответ 3
ST_Contains решит вашу проблему.
SELECT
polygon.gid, points.x, points.y
FROM
polygons LEFT JOIN points
ON st_contains(polygon.geom, points.geom)
WHERE
polygon.gid=your_id