SQL-запрос для точки в многоугольнике с использованием PostgreSQL
-
06-07-2019 - |
Вопрос
У меня есть следующая простая таблица:
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))'))
И столкнитесь с этой ошибкой:
столбец «поли» имеет тип многоугольника, но выражение имеет тип геометрии
Что отстойно.Итак, мои первые вопросы:
- Мне действительно нужно сниматься?
Во всяком случае, после кастинга все работает.И теперь я пытаюсь выполнить простой запрос 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.Фактический запрос к данным таблицы не работает.
Отвечать:
Дой!Проблема заключалась в том, что созданная мной БД не была основана на БД шаблона Postgis (и поэтому не имела соответствующих функций, таблиц столбцов геометрии и т. д.).В заключение позвольте мне отметить, что то, как PostGIS требует от вас добавления сотен функций, строк и нескольких таблиц в вашу базу данных только для того, чтобы у вас была поддержка ГИС, совершенно отстойно.Это делает резервное копирование схемы намного более сложным и очень подвержено ошибкам (не дай бог, если вы пренебрегаете вызовом AddGeometryColumn и просто добавляете столбец геометрии самостоятельно).
Решение
Полигон — это фундаментальный тип 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) те же пространственные индексы и т. д.?