Pages: 1
- Sujet précédent - [PostGis] Fusionner les polygones adjacents + concaténation attributs - Sujet suivant
#1 Mon 18 July 2016 11:32
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 995
[PostGis] Fusionner les polygones adjacents + concaténation attributs
Bonjour à tous,
J'ai comme l'impression qu'il y a moins de géomaticiens en vacances ici ;-)
Suite à cette question sur le Forum SIG, et grâce à la requête proposée par ChristopheV dans ce message (tâches urbaines), je suis bien parvenu à fusionner des polygones adjacents dans PostGis.
Il ne me reste qu'un (petit ?) détail à régler : je souhaiterais, au cours de cette fusion, conserver dans un champ dédié la concaténation des valeurs d'un champ des entités sources.
Exemple, si la source à un champ "id", je souhaiterais dans la couche fusionnée créer un champ "id_agg" avec les valeurs des ID source (sous forme d'un "array" (array_agg) ou d'une chaine de textes concaténés (string_agg) ).
J'ai tenté de modifier la 1ere CTE de la requête de ChristopheV, malheureusement, le résultat final contient, dans la colonne array_agg, la liste de l'ensemble des id de la couche source :
Code:
SELECT st_collectionextract(unnest(st_clusterintersecting(st_accum(polygon))),3) as geom, array_agg(id) as id_agg FROM table_source
Je dois cependant reconnaître que je ne comprends pas bien le fonctionnement de cette requête :-$
Merci à vous si vous pouvez m'aider à y voir plus clair, voire à parvenir à mes fins !
Bonne journée.
Sylvain M.
Dernière modification par Sylvain M. (Mon 18 July 2016 11:52)
Sylvain M.
Hors ligne
#2 Mon 18 July 2016 17:37
- ChristopheV
- Membre
- Lieu: Ajaccio
- Date d'inscription: 7 Sep 2005
- Messages: 3199
- Site web
Re: [PostGis] Fusionner les polygones adjacents + concaténation attributs
Bonjour,
Je sais pas trop ... enfin il y a bien le fait de tester chaque géométrie et de voir si elle est contenue dans le polygone résultant de la fusion des polygones adjacents mais c'est un peu bourrin ...
J'ai regardé du coté de
st_clusterKmeans et j'ai lu la doc sur k-means mais j'avoue que je pas tout bien comprendre.
Christophe
L'avantage d'être une île c'est d'être une terre topologiquement close
Hors ligne
#3 Tue 19 July 2016 17:01
- Sylvain M.
- Participant assidu
- Lieu: Saint-Pierre-des-Nids (53)
- Date d'inscription: 8 Sep 2005
- Messages: 995
Re: [PostGis] Fusionner les polygones adjacents + concaténation attributs
Bon, je ne sais pas si c'est la solution la plus "propre", mais ça marche pour mon besoin : finalement, je fais un UPDATE sur ma couche fusionnée, d'après une jointure spatiale sur la couche source.
Voici ce que ça donne en globalité :
Code:
DROP TABLE IF EXISTS table_fusion; WITH p as (SELECT st_collectionextract(unnest(st_clusterintersecting(st_accum(geom))),3) as geom FROM table_source), t as (SELECT row_number() OVER() as id, geom FROM p) SELECT id, ((st_dump(geom)).geom) as geom INTO table_tempo FROM t; SELECT id,st_union(st_makevalid(geom)) as geom INTO table_fusion FROM table_tempo GROUP BY id; DROP TABLE table_tempo; ALTER TABLE table_fusion ADD COLUMN id_agg text; -- UPDATE SUR JOINTURE SPATIALE : WITH t2 as (SELECT table_fusion.id, string_agg(cast(table_source.id as text), '|') as id_agg_temp, table_fusion.geom as geom FROM table_fusion JOIN table_source ON ST_Intersects(table_fusion.geom, table_source.geom) GROUP BY table_fusion.id, geom) UPDATE table_fusion SET id_agg = id_agg_temp FROM t2 WHERE t2.id=table_fusion.id;
N'hésitez pas à me faire part d'améliorations de la syntaxe (une jointure spatiale toute bête, pour moi c'était un challenge ;-) ).
Notamment sur la partie "UPDATE" (avec la CTE qui précède), qui est celle que j'ai ajoutée à la requête initiale de ChristopheV.
En espérant que cela puisse servir à d'autres !
A+
Sylvain M.
Dernière modification par Sylvain M. (Tue 19 July 2016 17:02)
Sylvain M.
Hors ligne
#4 Thu 04 August 2016 19:32
Re: [PostGis] Fusionner les polygones adjacents + concaténation attributs
Dans cette situation la jointure spatiale est la solution la plus propre (mais malheureusement pas très efficace). La seule autre méthode que je connais, c'est de stocker un valeur "id" dans une ordonnée qui vous n'utilisez pas (Z, M) et de l'extraire des résultats de ST_ClusterWithin, ce qui serait le contraire de "propre".
Ces fonctions seront plus capables dans la version 2.3 de PostGIS (devrait sortir en automne). La syntaxe est un peu plus complexe mais bien plus puissante. Au lieu de mettre chaque géométrie dans une collection, ST_ClusterDBSCAN (un algorithme général qui peut se réduire à ce de ST_ClusterWithin) ne fait que fournir un numéro qui indique à quelle grappe chaque géométrie appartient:
Code:
SELECT grappe_id, ST_Collect(geom) AS geom, string_agg(id::text, '|') AS id_agg FROM ( SELECT id, ST_ClusterDBSCAN(geom, minPoints := 1, eps := 3) OVER() AS grappe_id, geom FROM table_source ) sq GROUP BY grappe_id
Daniel
Hors ligne
Pages: 1
- Sujet précédent - [PostGis] Fusionner les polygones adjacents + concaténation attributs - Sujet suivant