Polygone couvert par l'intersection de plusieurs chaînes de lignes (PostGIS)
J'ai un set a linestrings, et je voudrais connaître la zone couverte par l'intersection de ces lignes.
Je ne veux pas les fusionner cependant. Pour clarifier les choses, voici un diagramme de trois chaînes multilignes. Je veux obtenir les polygones roses.
Comment puis-je y parvenir?
Réponses
Procédez comme suit:
- Nœud le dessin au trait
- Polygonisez l'ensemble des lignes nodées (cela supprime automatiquement toutes les lignes qui ne forment pas de polygones)
- Calculez l'aire du résultat polygonal.
WITH lines(geom ) AS (VALUES
('LINESTRING (170 250, 80 200, 60 110, 100 70, 145 58, 200 90, 210 150, 165 172, 130 130, 160 90, 200 70, 280 60, 310 70, 360 110, 400 180)'::geometry)
,('LINESTRING (305 6, 260 40, 250 100, 280 160, 344 145, 400 100, 405 78, 375 53)')
,('LINESTRING (540 100, 490 130, 450 90, 459 35, 530 50)')
)
,noded AS (SELECT ST_Node( ST_Collect(geom)) geom FROM lines)
SELECT ST_Area( ST_Polygonize( geom)) FROM noded;
Mise à jour: si certaines lignes coïncident (ont un dessin au trait partagé), elles ST_Uniondoivent être utilisées à la place de ST_Node ( ST_Collect.
Donc, puisque vous avez décidé de rendre la tâche plus compliquée en combinant 2 situations en une, voici ma solution pour votre situation spécifique, comme indiqué sur votre image.
Les géodonnées source sont une table avec le nom «ligne» EPSG: 4326.
Pré-créer des identifiants de ligne 1,2,3 - ils nous aideront à sélectionner / éliminer les lignes nécessaires / à moins que ...
Exécutez le script en tant que CTE:
WITH
tbla AS (SELECT id, (ST_Dump(geom)).geom geom FROM line),
tblb AS (SELECT a.id, (ST_Dump(ST_Difference(a.geom, b.geom))).geom geom FROM tbla a JOIN tbla b ON ST_Intersects(a.geom, b.geom) AND a.id<b.id),
tblc AS (SELECT ST_Union(ST_Buffer(geom, 0.0001, 'side=right')) geom FROM tblb),
tbld AS (SELECT DISTINCT (ST_Dump(ST_Split(a.geom, b.geom))).geom geom FROM tblc a JOIN tbla b ON ST_Intersects(a.geom, b.geom)),
tble AS (SELECT DISTINCT ST_MakePolygon(ST_InteriorRingN(geom,1)) geom FROM tbld),
tblf AS (SELECT a.id, (ST_Dump(ST_Difference(a.geom, b.geom))).geom geom FROM tbla a JOIN tbla b ON ST_Intersects(a.geom, b.geom) AND a.id>b.id),
tblg AS (SELECT ST_Buffer(geom, 0.0001, 'side=left') geom FROM tblf UNION SELECT ST_Buffer(geom, 0.0001, 'side=right') geom FROM tblb),
tblh AS (SELECT ST_Union(geom) geom FROM tblg),
tbli AS (SELECT DISTINCT (ST_Dump(ST_Split(a.geom, b.geom))).geom geom FROM tblh a JOIN tbla b ON ST_Intersects(a.geom, b.geom)),
tblj AS (SELECT DISTINCT ST_MakePolygon(ST_InteriorRingN(geom,1)) geom FROM tbli)
SELECT ST_Union(geom) geom FROM (SELECT * FROM tble UNION SELECT * FROM tblj) foo
Vérifiez votre résultat,
Bonne chance pour savoir ... 🙂