Como usar o ST_Intersection?


15

Aqui está um rápido resumo sobre o que estou tentando fazer: tenho 3 tabelas no Postgres, 'a' e 'b', cada uma com uma coluna Polígono e 'c' com uma coluna Point. O que estou tentando fazer aqui é obter as interseções de geometrias entre 'a', 'b' e 'c' e exibir essas geometrias em uma camada vetorial OpenLayers.

Eu já sei como exibir qualquer tipo de geometria de uma String em OpenLayers, mas estou tendo problemas com a função ST_Intersection do PostGIS, estou fazendo o seguinte:

SELECT ST_Intersection(a.geom, b.geom) as inter from a, b;

onde a.geom e b.geom são as colunas de geometria, e recebo esta mensagem de erro:

NOTICE:  TopologyException: found non-noded intersection between 515172 2.14408e+06, 497067 2.13373e+06 and 501321 2.13546e+06, 471202 2.14843e+06 500621 2.13576e+06 
ERROR:  GEOS Intersection() threw an error!

Também tentei expressar a geometria resultante como texto usando ST_AsText assim:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as inter from a, b;

mas ele me enviou esta mensagem de erro:

HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Não sei o que estou fazendo de errado, só quero que o WKT dos polígonos o exiba no OpenLayers, eis como mostro uma geometria de um WKT:

                    var in_options = {
                        'internalProjection': new OpenLayers.Projection("EPSG:4326"),
                        'externalProjection': new OpenLayers.Projection("EPSG:4326")
                    }; 

                    var fea= new OpenLayers.Format.WKT(in_options).read(data); //data is the string with the WKT
                    vectorLayer.addFeatures([fea]); //this piece of code works great
                    map.zoomToExtent(bounds);

UPDATE: Tentei o seguinte:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab FROM a INNER JOIN b ON 
ST_Intersection(a,b) WHERE ST_Overlaps(a.geom, b.geom) 
AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

mas recebo a próxima mensagem de erro:

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Eu adicionei o isvalid para verificar que apenas polígonos válidos estão sendo avaliados, mas está dizendo que o erro está na ST_Intersection (a, b), ambos a, bec têm o mesmo SRID, então estou realmente confuso, desculpe se estou pedindo demais, mas eu sou muito novo no PostGIS, então espero não estar incomodando muito. Obrigado.


1
O que SELECT PostGIS_Full_Version();retorna?
— Mike T

POSTGIS = "1.4.0" GEOS = "3.1.0-CAPI-1.5.0" PROJ = "Rel. 4.7.1, 23 de setembro de 2009" USE_STATS
— Uriel

Respostas:


8

Meu palpite seria que falhará se o cruzamento retornar NULL. Portanto, você deve adicionar uma cláusula where para verificar se existe realmente um cruzamento antes de tentar criar o WKT.


Tentei o seguinte: SELECT ST_Intersection (a.geom, b.geom) as intersect_ab FROM INNER JOIN b ON ST_Intersection (a, b) WHERE ST_Overlaps (a.geom, b.geom) AND ST_isvalid (a.geom) = 't 'AND ST_isvalid (b.geom) =' t '; mas retornou o mesmo erro: ** ERRO: A função st_intersection (a, b) não existe. DICA: Nenhuma função corresponde ao nome e aos tipos de argumento. Pode ser necessário adicionar conversões de tipo explícitas. ** Estou realmente preso a este, se você puder me ajudar, eu realmente aprecio isso.
— Uriel

Tente resumo (a.geom) e resumo (b.geom) para investigar os valores.
— underdark

resumo -------------------------- Polígono [BS] com anel de 1 anel 0 possui 4 pontos Polígono [BS] com anel de 1 anel 0 possui 5 pontos Polígono [BS] com 1 anéis anel 0 tem 10 pontos
— Uriel

Sim, deve ser ST_Intersection (a.geom, b.geom) e não ST_Intersection (a, b)
— underdark

6

A pista é

ERROR: Function st_intersection(a,b) does not exist.
HINT: No function matches the given name and argument types. You might need to add explicit type casts.

Como a mensagem de erro diz, você não pode usar st_intersection dessa maneira. Resumindo as outras respostas, você deve usar algo como isto:

SELECT ST_Intersection(a.geom, b.geom) as intersect_ab 
FROM a INNER JOIN b ON ST_Intersects(a.geom,b.geom)
WHERE ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

AFAIK, não faz sentido usar st_overlaps e st_intersects na mesma frase, pois são bastante semelhantes .


4

Eu testei entre diferentes camadas de polígonos e ele falhou se houver pelo menos uma geometria inválida em uma das camadas. Você verificou a validade dos seus polígonos usando ST_isvalid (the_geom)? Pode ser a chave.


Tentei o seguinte: SELECT ST_Intersection (a.geom, b.geom) as intersect_ab FROM INNER JOIN b ON ST_Intersection (a, b) WHERE ST_Overlaps (a.geom, b.geom) AND ST_isvalid (a.geom) = 't 'AND ST_isvalid (b.geom) =' t '; mas retornou o mesmo erro: ** ERRO: A função st_intersection (a, b) não existe. DICA: Nenhuma função corresponde ao nome e aos tipos de argumento. Pode ser necessário adicionar conversões de tipo explícitas. ** Eu estou realmente perdido a respeito de porque ele não está funcionando
— Uriel

2

Tente algo como isto:

SELECT  ST_Intersection(a.geom, b.geom) As intersect_ab
    FROM a INNER JOIN b ON ST_Intersection(a,b)
    WHERE ST_Overlaps(a.geom, b.geom)
    ;

Fonte


Tentei isso também, mas ele retorna a mesma mensagem de erro: DICA: Nenhuma função corresponde ao nome e aos tipos de argumento. Pode ser necessário adicionar conversões de tipo explícitas.
— Uriel

Que tal se você usar "INNER JOIN b ON ST_Intersection (a.geom, b.geom)"?
— precisa saber é o seguinte

Diz: ERRO: o argumento de JOIN / ON deve ser do tipo booleano, não do tipo geometria.
— Uriel

shizer ... deve haver algo errado com os dados ou algo assim, porque esse tipo de consulta funciona para mim.
— CaptDragon

Adicionei AND ST_isvalid (a.geom) = 't' AND ST_isvalid (b.geom) = 't'; no fim de avaliar apenas as geometrias válidas, mas ele está me dizendo o erro está em que ST_Intersection (a, b)
— Uriel

1

Tentei excluir as geometrias inválidas, mas não funcionou, então, no final, tive que excluir todas as geometrias inválidas e depois usar o seguinte:

SELECT ST_AsText(ST_Intersection(a.geom, b.geom)) as intersect_ab FROM a,b 
WHERE ST_Overlaps(a.geom, b.geom) AND ST_isvalid(a.geom)='t' AND ST_isvalid(b.geom)='t';

Como você pode ver, omiti a parte ST_Intersection (a, b), e isso funcionou muito bem, estou meio triste porque não consegui encontrar uma maneira de excluir nenhuma geometria inválida do meu select, de qualquer forma, obrigado a todos por me ajudarem lá fora.


0

Eu tive esse problema uma vez.

<pre>NOTICE:  TopologyException: found non-noded intersection between xxx, xxxx and xxx, xxx  ERROR:  GEOS Intersection() threw an error!</pre>

Consegui resolver esse erro usando esse método.
- Use o QGIS
- Adicione uma camada vetorial do seu banco de dados
- Pegue o ponto da mensagem de erro e procure-o no QGIS
   "QuickWKT" (plugin) pode ser usado para encontrá-lo
- Então você verá o problema da cadeia de linhas
- Ative o modo de edição
- Selecione "ferramenta de nó" para mostrar o nó verde (problema do nó)
- Afaste o nó do nó de sobreposição
- Salvar alterações

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.