Eu tenho uma tabela PostGIS polygon_b
com alguns recursos de polígono. Há também uma tabela polygon_a
que contém os mesmos polígonos, polygon_b
mas com pequenas alterações. Agora, quero criar linhas para visualizar as diferenças entre os recursos de polígono.
Suponho que ST_ExteriorRing
e ST_Difference
faça o trabalho, mas a cláusula WHERE parece ser bastante complicada.
CREATE VIEW line_difference AS SELECT
row_number() over() AS gid,
g.geom::geometry(LineString, yourSRID) AS geom
FROM
(SELECT
(ST_Dump(COALESCE(ST_Difference(ST_ExteriorRing(polygon_a.geom), ST_ExteriorRing(polygon_b.geom))))).geom AS geom
FROM polygon_a, polygon_b
WHERE
-- ?
) AS g;
Alguém pode me ajudar?
EDIT 1
Conforme publicado por 'tilt', tentei, ST_Overlaps(polygon_a.geom, polygon_b.geom) AND NOT ST_Touches(polygon_a.geom, polygon_b.geom)
mas o resultado não é o esperado.
CREATE VIEW line_difference AS SELECT
row_number() over() AS gid,
g.geom::geometry(LineString, your_SRID) AS geom
FROM
(SELECT
(ST_Dump(COALESCE(ST_Difference(ST_ExteriorRing(polygon_a.geom), ST_ExteriorRing(polygon_b.geom))))).geom AS geom
FROM polygon_a, polygon_b
WHERE
ST_Overlaps(polygon_a.geom, polygon_b.geom) AND NOT ST_Touches(polygon_a.geom, polygon_b.geom))
AS g;
EDIT 2
workupload.com/file/J0WBvRBb (exemplo de conjunto de dados)
Tentei transformar os polígonos em multilinhas antes de usar ST_Difference, mas os resultados ainda são estranhos.
CREATE VIEW multiline_a AS SELECT
row_number() over() as gid,
ST_Union(ST_ExteriorRIng(polygon_a.geom))::geometry(multilinestring, 4326) AS geom
FROM
polygon_a;
CREATE VIEW multiline_b AS SELECT
row_number() over() as gid,
ST_Union(ST_ExteriorRIng(polygon_b.geom))::geometry(multilinestring, 4326) AS geom
FROM
polygon_b;
CREATE VIEW line_difference AS SELECT
row_number() over() as gid,
g.geom
FROM
(SELECT
(ST_Dump(COALESCE(ST_Difference(multiline_a.geom, multiline_b.geom)))).geom::geometry(linestring, 4326) AS geom
FROM
multiline_a, multiline_b)
As g;
qgis
postgis
polygon
linestring
differences
Mar Lunar
fonte
fonte
Respostas:
Aqui estão alguns novos truques, usando:
EXCEPT
para remover geometrias das tabelas iguais, para que possamos focar apenas nas geometrias exclusivas de cada tabela (A_only
eB_only
).ST_Snap
para obter acenos exatos para operadores de sobreposição.ST_SymDifference
operador de sobreposição para encontrar a diferença simétrica entre os dois conjuntos de geometria para mostrar as diferenças. Atualização :ST_Difference
mostra o mesmo resultado para este exemplo. Você pode tentar qualquer uma das funções para ver o que elas recebem.Isso deve obter o que você espera:
Para descompactar um pouco mais esta resposta, o primeiro passo com
ST_Boundary
obtém o limite de cada polígono, e não apenas o exterior. Por exemplo, se houvesse buracos, eles seriam rastreados pelo limite.A
EXCEPT
cláusula é usada para remover geometrias de A que fazem parte de B e linhas de B que fazem parte de A. Isso reduz o número de linhas que fazem parte apenas de A e apenas parte de B. Por exemplo, para obter A_only:Aqui estão as 6 linhas de A_only e 3 linhas de B_only:
Próximo,
ST_Union(DISTINCT A_only.geom)
é usado para combinar o trabalho de linha em uma única geometria, geralmente uma MultiLineString.ST_Snap é usado para ajustar nós de uma geometria para outra. Por exemplo
ST_Snap(A, B, tol)
, pegue a geometria A e adicione mais nós da geometria B ou mova-os para a geometria B, se estiverem dentro datol
distância. Provavelmente, existem várias maneiras de usar essas funções, mas a idéia é obter coordenadas de cada geometria que sejam exatas entre si. Portanto, as duas geometrias após o snap são assim:E para mostrar diferenças, você pode optar por usar
ST_SymDifference
ouST_Difference
. Ambos mostram o mesmo resultado para este exemplo.fonte
Eu acho que é um pouco complicado, por causa dos diferentes conjuntos de nós dos dois polígonos (polígono verde A, segmentos diferentes vermelhos do polímero B). A comparação dos segmentos de ambos os polígonos fornece uma pista de quais segmentos do polígono B serão modificados.
Polígono de nós A
Nós do polígono B de segmentos "diferentes"
Infelizmente, isso mostra apenas a diferença na estrutura do segmento, mas espero que seja um ponto de partida e funcione assim:
Após um processo de download e descompactação, importei o conjunto de dados usando o PostgrSQL 9.46, o PostGIS 2.1 no Debian Linux Jessie com os comandos.
Supondo que os segmentos do polígono A não estejam em B e vice-vera, tento criar a diferença entre os segmentos de ambos os conjuntos de polígonos, negligenciando a associação do segmento aos polígonos de cada grupo (A ou B). Por razões didáticas, formulo o material SQL em várias visualizações.
Correspondendo a este post do GIS-SE , decomponho os dois polígonos em tabelas de segmentos
segments_a
esegments_b
O polígono da tabela de segmentos A:
O mesmo procedimento foi aplicado ao polígono B.
O polígono da tabela de segmentos B
Eu posso criar uma exibição de tabela de diferença chamada
segments_diff_{a,b}
. A diferença é dada pela não ocorrência de pontos de início ou de fim classificados no conjunto de segmentos A e B.E o material complementar:
Conclusão: Para obter um resultado adequado para os pequenos pequenos segmentos marcados com a seta vermelha, os dois polígonos devem ter a mesma estrutura do nó e uma etapa de interseção no nível do nó (é necessário inserir vértices do polígono A em B). A interseção pode ser feita por:
Mas com resultados estranhos ...
fonte
Observando o exemplo, a alteração implica que os recursos da nova tabela que foram alterados sempre estarão sobrepondo-os à tabela antiga. Portanto, você seria feito com
A negação dos toques ocorre porque os recursos também se sobrepõem se apenas suas bordas compartilharem os mesmos locais de vértices.
fonte