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.

Uriel
fonte
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.

underdark
fonte
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 .

Francisco Puga
fonte
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.

Fabien Ancelin
fonte
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

CaptDragon
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.

Uriel
fonte
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

Ruthe
fonte