consulta SQL para point-in-polígono usando PostgreSQL
-
06-07-2019 - |
Pergunta
Eu tenho a seguinte tabela simples:
CREATE TABLE tbl_test
(
id serial NOT NULL,
poly polygon NOT NULL
)
WITH (OIDS=FALSE);
Em seguida, tentar inserir uma linha com um polígono:
insert into tbl_test values(1, PolyFromText('POLYGON((0 0, 10 10, 10 0, 0 0))'))
E executar para esse erro:
coluna "poli" é de tipo polígono mas a expressão é do tipo de geometria
O que é coxo. Então, minhas primeiras perguntas é:
- Do eu realmente tenho que elenco?
De qualquer forma, depois de lançar ele funciona. E agora eu estou tentando fazer uma consulta simples ST_Contains:
select id, poly from tbl_test where ST_Contains(poly, Point(GeomFromText('POINT(9 2)')))
O que dá o erro:
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.
O que devo fazer?
As seguintes obras:
select st_contains(st_geomfromtext('POLYGON((0 0, 10 10, 10 0, 0 0))'), st_geomfromtext('POINT(0 0)'))
Mas isso é provavelmente porque ambos os argumentos são do tipo Geometry. A consulta real contra os dados da tabela não funciona.
Resposta:
Doi! O problema era que a DB eu criei não foi baseada no modelo de postgis DB (e por isso não tinha as funções relevantes e mesas coluna de geometria, etc.). Posso apenas observar, em conclusão, que a maneira PostGIS requer que você adicionar centenas de funções, linhas e algumas mesas para o seu DB só assim você teria suporte GIS é completamente coxo. Faz backup do esquema que muito mais complexo e é muito propenso a erros (Deus nos livre se você negligenciar a chamar AddGeometryColumn e basta adicionar uma coluna de geometria si mesmo).
Solução
O polígono é um tipo fundamental Postgres que PostGIS constrói em cima. Você permitir que as colunas da geometria com a função select AddGeometryColumn(...)
PostGIS. Caso contrário, você está trabalhando com polígonos retas:
=> 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)
Este é o ponto central do polígono
=> select circle(space) from gt where id = 1;
circle
--------------------------------
<(2.25,3.25),1.93994028704315>
(1 row)
Este é o círculo de limite mínimo do polígono, expressa como um tipo circle
Postgres. Todos os operadores geométricos são documentados href="http://www.postgresql.org/docs/8.3/interactive/functions-geometry.html" aqui: http://www.postgresql.org /docs/8.3/interactive/functions-geometry.html O polígono de base não tem quaisquer dados de projeção, SRID, etc., assim que se trabalha com PostGIS é provavelmente apenas falta para presets e ter sorte. Mas é claro que existem toneladas de casos em que você simplesmente precisa de geometria em uma escala sub-geoespacial.
Outras dicas
Ok, estranho, eu descobri as seguintes obras de sintaxe muito mais simples:
insert into tbl_test (poly) values ('(0,0),(0,10),(10, 10), (0, 0)')
select * from tbl_test where poly @> '(2, 8)'
Mas eu estou lutando para descobrir a diferença entre estes conjuntos de funções e operadores. Será que esta sintaxe mais curta (que não é realmente OpenGIS compliant) aproveitar os mesmos índices espaciais, etc.?