Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Suite à un problème technique intervenu entre le 22 et le 23 mars, nous avons du procéder dans la soirée du 25 mars, à la restauration de la base de données du 24 mars (matinée).

En clair, nous avons perdu vos contributions et inscriptions du dimanche 24 et du lundi 25 mars.
Nous vous prions de nous excuser.

#1 Mon 18 July 2016 11:32

Sylvain M.
Participant assidu
Lieu: Saint-Pierre-des-Nids (53)
Date d'inscription: 8 Sep 2005
Messages: 981

[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 ! smile

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: 3163
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. sad


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: 981

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 ! smile

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

dbaston
Juste Inscrit !
Lieu: Montpelier
Date d'inscription: 3 Jun 2016
Messages: 7
Site web

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

 

Pied de page des forums

Powered by FluxBB