В 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