Pages: 1
- Sujet précédent - QGIS / Postgis: fusionner des polygones sans multi-parties - Sujet suivant
#1 Thu 11 May 2017 19:45
QGIS / Postgis: fusionner des polygones sans multi-parties
Bonjour à toutes et tous,
J'interroge une base de données postresql/postgis depuis Qgis. Je souhaite fusionner des polygones selon plusieurs critères et calculer des statistiques sur une partie des champs. Depuis le DB manager, j'ai saisi le code suivant
Code:
SELECT ST_Union(occup2015.geom) as singlegeom, MIN(no_par) as no_par, SUM(surf) as s_ilot, code_stream, id_resp FROM occup2015 GROUP BY code_stream, id_resp
L'objectif de la fusion et de retrouver des parcelles agricoles à partir de polygones qui sont des sous-parcelles (code_stream: identifiant de la culture, id_resp: identifiant de l'agriculteur). Mais je veux un polygone par îlot agricole, or ce code me génère une couche présentant un unique polygone par couple (agriculteur, culture). Du coup, s_ilot prend pour valeur la surface totale des blés de M. Untel, alors que je voudrais la valeur îlot par îlot.
Le manuel parle pourtant de la possibilité de produire des "single geometry" http://postgis.net/docs/manual-2.1/ST_Union.html. À moins que j'interprète mal, je pensais que "single geometry" signifiait une géométrie simple (par opposition à une géométrie multi-partie).
Comment forcer ST_Union à me retourner des polygones simples ?
Vous remerciant par avance pour votre aide,
Bien sincèrement,
Jean-Baptiste
Hors ligne
#2 Fri 12 May 2017 00:30
- JD
- Moderateur
- Date d'inscription: 8 Aug 2013
- Messages: 726
Re: QGIS / Postgis: fusionner des polygones sans multi-parties
Bonsoir,
st_union est un fonction d'agrégation et ne renverra qu'une entité simple seulement si une seule entité est concernée par le couple code_stream, id_resp.
Pour en revenir au fond du problème, je ne comprends pas tous les tenants et les aboutissants.
Vous parlez d'îlots agricoles, de parcelles agricoles, de sous-parcelles.
Je suppose que la couche occup2015 contient les parcelles. Aussi vous voulez agréger les géométries par îlot et obtenir pour chaque îlot la surface de chaque culture. Mais dans ce cas là je ne comprend pas pourquoi vous utilisez id_resp dans votre clause de regroupement.
Bref, si vous pouviez reformuler car cela me semble assez confus.
Cordialement,
Dernière modification par lejedi76 (Fri 12 May 2017 00:31)
Hors ligne
#3 Fri 12 May 2017 01:06
Re: QGIS / Postgis: fusionner des polygones sans multi-parties
bonsoir,
J'ai cherché un compromis entre être d'un côté simplifier et aller à l'essentiel, et de l'autre contextualiser mon problème. Il semble que l'équilibre n'était pas bon.
Le fichier de couche est une sorte de parcellaire. Il permet de suivre l'occupation du sol précise sur plusieurs années. Chaque polygone a toujous été homogène occupation du sol. Un îlot agricole est un espace contigüe exploité par un agriculteur. L'assolement fait que le nombre de parcelles agricoles au sein d'un îlot varie d'une année sur l'autre. De plus, les limites de parcelles peuvent changer même si le nombre de parcelles est le même. Pour définir une parcelle, il faut un espace continu présentant la même culture exploitée par le même agriculteur (pour ne pas fusionner les blés de M. Bidule avec ceux de son voisin).
Voilà pour le contexte.
Pour la question technique, ce que vous dites de st_union ne me rassure pas... Pourriez-vous préciser, SVP ?
Avec mes remerciements,
Jean-Baptiste
Hors ligne
#4 Fri 12 May 2017 12:55
- SANTANNA
- Moderateur
- Lieu: Angers
- Date d'inscription: 18 Jan 2008
- Messages: 3945
Re: QGIS / Postgis: fusionner des polygones sans multi-parties
Bonjour,
Regardez du côté de st_dump qui permet d'exploser une géométrie multiparties en géométries d'un seul tenant
Hors ligne
#5 Fri 12 May 2017 16:08
Re: QGIS / Postgis: fusionner des polygones sans multi-parties
Bonjour Santana,
J'ai essayé st_dump().
Code:
SELECT (st_dump(st_union(geom))).geom as singlegeom, MIN(no_par) as no_par, SUM(surf) as s_ilot, MAX(date_interv), SUM(quantite)/SUM(surf) as dose, code_stream, id_resp FROM occup2015 GROUP BY code_stream, id_resp
Cette fonction permet bien d'exploser une géométrie multipartie: la couche produite est conforme à ce que j'attends du point de vue de la géométrie. Mais les statistiques sont calculées sur l'ensemble, avant "explosion". Chaque géométrie retournée par st_dump se voit attribuer la même valeur s_ilot ou de dose, calculées sur l'ensemble des enregistrements présentant le même couple (code_stream, id_resp), contiguës ou pas. J'ai même forcé le passage en polygones simples, mais le résultat est le même.
Code:
SELECT (st_dump(st_union(geom))).geom::geometry(polygon,2154) as singlegeom,
Faudra-t-il multiplier les étapes
1) fusionner avec st_union,
2) "exploser" avec st_dump,
3) calculer les autres champs avec une jointure spatiale (st_within) ?
Ce ne serait pas très élégant, lorsqu'il suffirait que st_union nous donne des géométries simples... J'en reviens donc à ma question initiale, que je reformule de façon plus prudente néanmoins :
Est-il possible de forcer st_union à retourner des polygones simples ?
En vous remerciant pour votre aide,
Bien sincèrement,
Jean-Baptiste
Hors ligne
#6 Fri 12 May 2017 17:00
Re: QGIS / Postgis: fusionner des polygones sans multi-parties
Re-bonjour à toutes et tous,
Je pense soudain à une bidouille : préparer une couche des îlots avec st_dump(st_union(geom)) en regroupant uniquement sur id_resp, attribuer un numéro arbitraire (row_number() over()) à ces îlots, ajouter ce champ par jointure spatiale à ma couche de polygones, et ajouter la valeur d'îlot dans le GROUP BY du code ci-dessus.
Cela résout mon problème ponctuel (disons qu'il serait ainsi résolu à 95%, resteraient quelques cas particuliers), mais ne permet pas de traiter le cas général. Je pense donc que la question initiale mérite réponse...
Dans l'attente de vos lumières,
Bien sincèrement,
Jean-Baptiste
Hors ligne
#7 Tue 16 January 2018 17:24
- Alicemartin
- Participant occasionnel
- Date d'inscription: 30 Jun 2013
- Messages: 48
Re: QGIS / Postgis: fusionner des polygones sans multi-parties
Bonjour,
Mon message arrive sûrement trop tard, mais j’ai eût le même problème que vous et, m’inspirant de votre « bidouille », j’ai réussi à le régler. Voilà le code que vous auriez pu utiliser (inspiré de celui que j’ai fait mais il faudrait le tester) :
Code:
SELECT table_fusion.singlegeom AS geom, MIN(table_ini.no_par) as no_par, SUM(table_ini.surf) as s_ilot, MAX(table_ini.date_interv), SUM(table_ini.quantite)/SUM(table_ini.surf) as dose, table_fusion.code_stream, table_fusion.id_resp FROM (SELECT code_stream, id_resp, (st_dump(st_union(geom))).geom as singlegeom FROM occup2015 GROUP BY code_stream, id_resp) AS table_fusion, LEFT OUTER JOIN occup2015 AS table_ini ON ST_Contains(table_fusion.geom,table_ini.geom) GROUP BY table_fusion.geom,table_fusion.code_stream,table_fusion.id_resp
L’idée est donc de créer :
- une table « table_fusion » qui contient les géométries voulues : les parcelles fusionnées, groupées par identifiant de culture et d’agriculteur, puis explosées avec ST_DUMP
- une table « table_ini » qui contient les données initiales, regroupées via des fonctions d’aggrégation (MIN, SUM, MAX) et associées par une jointure spatiale « ST_CONTAINS » aux parcelles de « table_fusion »
Je ne sais pas si mes explications sont claires, mais j’espère en tout cas que cette bidouille pourra aider quelqu’un.
Bien cordialement,
Alice Martin
Hors ligne
Pages: 1
- Sujet précédent - QGIS / Postgis: fusionner des polygones sans multi-parties - Sujet suivant