J'ai une table PostGIS polygon_b
avec quelques entités polygonales. Il y a aussi une table polygon_a
qui contient les mêmes polygones polygon_b
mais avec des changements mineurs. Maintenant, je veux créer des lignes pour visualiser les différences entre les entités surfaciques.
Je suppose que ST_ExteriorRing
et ST_Difference
fera le travail, mais la clause WHERE semble être assez délicate.
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;
Quelqu'un peut-il m'aider?
EDIT 1
Comme indiqué par «tilt», j'ai essayé ST_Overlaps(polygon_a.geom, polygon_b.geom) AND NOT ST_Touches(polygon_a.geom, polygon_b.geom)
mais le résultat n'est pas comme prévu.
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 (exemple d'ensemble de données)
J'ai essayé de transformer les polygones en multilignes avant d'utiliser ST_Difference, mais les résultats sont toujours étranges.
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;
la source
Réponses:
Voici quelques nouvelles astuces, en utilisant:
EXCEPT
pour supprimer les géométries des deux tables qui sont identiques, nous pouvons donc nous concentrer uniquement sur les géométries uniques à chaque table (A_only
etB_only
).ST_Snap
pour obtenir un signe de tête exact pour les opérateurs de superposition.ST_SymDifference
opérateur de superposition pour trouver la différence symétrique entre les deux jeux de géométrie pour afficher les différences. Mise à jour :ST_Difference
affiche le même résultat pour cet exemple. Vous pouvez essayer l'une ou l'autre fonction pour voir ce qu'ils obtiennent.Cela devrait obtenir ce que vous attendez:
Pour décompresser un peu plus cette réponse, la première étape avec
ST_Boundary
obtient la limite de chaque polygone, plutôt que juste l'extérieur. Par exemple, s'il y avait des trous, ceux-ci seraient tracés par la frontière.La
EXCEPT
clause est utilisée pour supprimer des géométries de A qui font partie de B et des lignes de B qui font partie de A. Cela réduit le nombre de lignes qui font partie de A uniquement et une partie de B uniquement. Par exemple, pour obtenir A_only:Voici les 6 lignes de A_only et 3 lignes de B_only:
Ensuite,
ST_Union(DISTINCT A_only.geom)
est utilisé pour combiner le dessin au trait en une seule géométrie, généralement une chaîne MultiLineString.ST_Snap est utilisé pour accrocher les nœuds d'une géométrie à une autre. Par exemple
ST_Snap(A, B, tol)
, prendra la géométrie A et ajoutera plus de nœuds de la géométrie B, ou les déplacera vers la géométrie B, s'ils sont àtol
distance. Il existe probablement plusieurs façons d'utiliser ces fonctions, mais l'idée est d'obtenir des coordonnées exactes les unes des autres à partir de chaque géométrie. Ainsi, les deux géométries après la capture ressemblent à ceci:Et pour montrer les différences, vous pouvez choisir d'utiliser soit
ST_SymDifference
ouST_Difference
. Ils montrent tous les deux le même résultat pour cet exemple.la source
Je pense que c'est un peu délicat, en raison des différents ensembles de nœuds de vos deux polygones (polygone vert A, segments rouges différents du polyon B). La comparaison des segments des deux polygones donne un indice sur les segments du polygone B qui seront modifiés.
Nœuds polygone A
Noeuds du polygone de segments "différents" B
Malheureusement, cela ne montre que la différence dans la structure des segments, mais j'espère que c'est un point de départ et que cela fonctionne comme ceci:
Après un processus de téléchargement et de décompression, j'ai importé l'ensemble de données à l'aide de PostgrSQL 9.46, PostGIS 2.1 sous Debian Linux Jessie avec les commandes.
En supposant que les segments du polygone A ne sont pas en B et vice-versa, j'essaie de créer la différence entre les segments des deux ensembles de polygones, en négligeant l'appartenance des segments aux polygones de chaque groupe (A ou B). Pour des raisons didactiques, je formule le truc SQL dans plusieurs vues.
Correspondant à ce post GIS-SE , je décompose les deux polygones en tables de segments
segments_a
etsegments_b
Le polygone de table de segments A:
La même procédure a été appliquée au polygone B.
Le polygone de table de segments B
Je peux créer une vue de table des différences nommée
segments_diff_{a,b}
. La différence est donnée par la non-occurrence de points de début ou de fin triés dans l'ensemble de segments A et B.Et les trucs complémentaires:
Conclusion: Pour obtenir un résultat correct pour les petits petits segments que vous avez marqués avec la flèche rouge, les deux polygones doivent avoir la même structure de nœud et une étape d'intersection au niveau du nœud (insertion de sommets du polygone A dans B) est requise. L'intersection pourrait se faire par:
Mais avec des résultats étranges ...
la source
En regardant l'exemple, la modification implique que les entités de la nouvelle table qui ont été modifiées seront toujours des entités se chevauchant de l'ancienne table. Par conséquent, vous en auriez fini avec
La négation au toucher est due au fait que les entités se chevauchent également si seules leurs bordures partagent les mêmes emplacements de sommets.
la source