SQL-запрос для точки в полигоне с использованием PostgreSQL

у меня есть следующая простая таблица:

CREATE TABLE tbl_test
(
  id serial NOT NULL,
  poly polygon NOT NULL
)
WITH (OIDS=FALSE);

затем я пытаюсь вставить строку с многоугольником:

insert into tbl_test values(1, PolyFromText('POLYGON((0 0, 10 10, 10 0, 0 0))'))

и запустить эту ошибку:

столбец "poly" имеет тип polygon, но выражение имеет тип geometry

хромой. Итак, мои первые вопросы:

  1. я действительно должен бросить?

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

select id, poly from tbl_test where ST_Contains(poly, Point(GeomFromText('POINT(9 2)')))

что дает ошибку:

ERROR:  function st_contains(polygon, point) does not exist
LINE 1: select id, poly from tbl_test where ST_Contains(poly, Point(...
                                            ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

что я должен делать?

следующие работы:

select st_contains(st_geomfromtext('POLYGON((0 0, 10 10, 10 0, 0 0))'), st_geomfromtext('POINT(0 0)'))

но это, вероятно, потому, что оба аргумента имеют тип Geometry. Фактический запрос к данным таблицы не работает.

ответ:

Doi! Проблема заключалась в том, что созданная мной БД не была основана на шаблоне postgis (и поэтому не имела соответствующих функций и таблицы столбцов геометрии, etc.). Могу ли я просто отметить, в заключение, что способ PostGIS требует от вас добавления сотен функций, строк и нескольких таблиц в вашу БД, чтобы у вас была поддержка ГИС, полностью хромает. Это делает резервную копию схемы намного сложнее и очень подвержена ошибкам (боже упаси, если вы пренебрегаете вызовом AddGeometryColumn и просто добавляете столбец геометрии самостоятельно).

2 ответов


полигон является фундаментальным типом Postgres, который PostGIS строит поверх. Вы включаете столбцы геометрии с помощью функции PostGIS select AddGeometryColumn(...). В противном случае вы работаете с прямыми полигонов:

=> create table gt (id int, space polygon);
=> insert into gt values (1, '((2,2),(3,4),(3,6),(1,1))');
INSERT 0 1
=> select point(space) from gt where id = 1;
    point    
-------------
 (2.25,3.25)
(1 row)

это центральная точка многоугольника

=> select circle(space) from gt where id = 1;
             circle             
--------------------------------
 <(2.25,3.25),1.93994028704315>
(1 row)

это минимальная ограничивающая окружность многоугольника, выраженная как Postgres circle тип. Все геометрические операторы задокументированы здесь: http://www.postgresql.org/docs/8.3/interactive/functions-geometry.html базовый многоугольник не имеет проекционных данных, SRID и т. д., поэтому, если он работает с PostGIS, он, вероятно, просто по умолчанию использует пресеты и получает удачу. Но, конечно, есть тонны случаев, когда вам просто нужна геометрия в суб-геопространственном масштабе.


ОК, странно, я узнал, что работает следующий синтаксис намного проще:

insert into tbl_test (poly) values ('(0,0),(0,10),(10, 10), (0, 0)')

select * from tbl_test where poly @> '(2, 8)'

но я пытаюсь выяснить разницу между этими наборами функций и операторов. Использует ли этот более короткий синтаксис (который на самом деле не совместим с OpenGIS) те же пространственные индексы и т. д.?