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

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#1 Mon 09 February 2015 17:25

schummi
Participant actif
Date d'inscription: 12 Mar 2009
Messages: 88

[PostgreSQL 9.3 / PostGIS] - découper deux couches de polygones

Bonjour,

J'ai deux tables spatiales dans ma base PG :
- table A contenant 975 polygones. Certains de ces polygones pouvant être superposés avec d'autres polygones de la même couche
- table B contenant 790 polygones. Certains de ces polygones pouvant être superposés avec d'autres polygones de la même couche

Le résultat que j'aimerais obtenir est une table contenant :
- les polygones de la table B découpés pour ceux concernés par une intersection avec un ou plusieurs polygones de la table A
- les polygones de la table B restant (non concernés par l'intersection).

Je n'arrive pas à trouver la solution. J'imagine qu'il me faut traiter cela par requête récursive ? Car les tests que j'ai déjà effectué par ST_Difference ne sont pas corrects sur les polygones superposés ....

Aussi, j'aimerais optimiser le temps du traitement. Une fois encore, dans mes tests, j'ai essayé de gérer par des conditions ST_Intersects ou && pour traiter par bounding box mais les temps de calcul sont très longs : je précise que mes 2 tables ont un index spatial type GIST. Ce ne sont pas des multipolygon, leur forme peut être parfois un peu complexe mais sans plus.

Auriez-vous un exemple ou une solution à mon questionnement ?

Cordialement

Hors ligne

 

#2 Mon 09 February 2015 18:10

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: [PostgreSQL 9.3 / PostGIS] - découper deux couches de polygones

Bonjour,

Si j'ai bien compris, vous voulez conserver tous les polygones de la table B découpés par la couche A.

C'est possible sans requete recursive:

D'abord unir les polygones de la couche A qui intersectent chaque polygone de la couche B. On a ainsi, pour tous les polygones de B concernés, le patch venant de A qui les recouvrent.
Ensuite on découpe chaque polygone de B avec ce patch, en se basant sur l'id du polygone.

Le trick pour garder tout le monde est de faire un left join entre la table B et les patchs, et d'appeler st_difference avec une GEOMETRYCOLLECTION EMPTY pour retourner le PG B original en cas de non-intersection avec A. En SQL:

Code:

with tmp as (
  select b.id, st_union(a.geom) as geom
  from pgb b join pga a on st_intersects(a.geom, b.geom)
  group by b.id
) select b.id, st_difference(b.geom,coalesce(t.geom, 'GEOMETRYCOLLECTION EMPTY'::geometry)) as newgeom
from pgb b left join tmp t on b.id = t.id;

Les images montrent les deux couches et le resultat en vert

Nicolas


Fichier(s) joint(s) :
Pour accéder aux fichiers vous devez vous inscrire.

Hors ligne

 

#3 Mon 09 February 2015 18:17

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: [PostgreSQL 9.3 / PostGIS] - découper deux couches de polygones

Normalement sur une telle volumétrie, ca devrait etre très rapide.

Les polygons sont-ils très grands par rapport a l'extension spatiale des données ?
Si c'est le cas, vous pouvez booster la vitesse de la requete en découpant les gros polygones sur une grille carrée.

Nicolas

Hors ligne

 

#4 Mon 09 February 2015 20:20

schummi
Participant actif
Date d'inscription: 12 Mar 2009
Messages: 88

Re: [PostgreSQL 9.3 / PostGIS] - découper deux couches de polygones

Super merci !
Cela marche de manière impeccable.

Me reste maintenant à comprendre chacun des éléments de cette requête ;-)

Cordialement

Hors ligne

 

#5 Tue 10 February 2015 09:27

MathieuB
Membre du bureau
Lieu: Montpellier
Date d'inscription: 18 Jan 2006
Messages: 1233
Site web

Re: [PostgreSQL 9.3 / PostGIS] - découper deux couches de polygones

Nicolas Ribot a écrit:

Le trick pour garder tout le monde est de faire un left join entre la table B et les patchs, et d'appeler st_difference avec une GEOMETRYCOLLECTION EMPTY pour retourner le PG B original en cas de non-intersection avec A.


Merci Nicolas,

voici une belle "astuce" à laquelle je n’avais pas pensé il y a quelques temps pour un besoin similaire.


Mathieu BOSSAERT
Association GeoRezo

Hors ligne

 

Pied de page des forums

Powered by FluxBB