L’analyse spatiale avec SQL: 5-fonction d’agrégation (Union d’ArcGis)

Dans l’article précédent nous avons certaines les fonctions SQL de traitement spatial. Dans cet article nous verrons une fonction un peu plus compliquée à mettre en œuvre: la fonction d’agrégation de deux couches de polygones. Cette opération est celle qui est nommée Union dans ArcGis. Le but de l’opération est d’obtenir une couche avec toutes les intersections des entités des deux couches initiales, ainsi que toutes les entités non intersectées.

Prenons un exemple. Nous avons une première couche « rectangles »

Une deuxième couche « cercles »:

Qui se superposent spatialement:

Ce que nous voulons obtenir est une couche contenant tous les polygones des deux couches, mais en créant des polygones pour les zones de superposition:

Nous allons procéder en suivant la même méthode que dans l’article précédent, c’est à dire en construisant une requête SQL composée de plusieurs sous requêtes.

En premier lieu, nous allons construire une requête qui va construire les polygones des zones de superposition (les intersections) des deux couches. Ces polygones apparaissent en jaune sur l’image suivante.

Nous reprendrons la requête utilisée dans l’article précédent:

select cercle.id as id1,rectangles.id as id2, st_intersection(cercle.geom,rectangles.geom) as the_geom
from cercle,rectangles
where st_intersects(cercle.geom,rectangles.geom)
group by cercle.id,rectangles.id

Vous remarquerez que le select est construit pour non seulement récupérer les géométries intersectées, mais aussi les identifiants des entités d’origine (cercle.id  et rectangles.id) . Bien sûr, vous pourrez récupérer d’autres attributs, ou tous, en modifiant cette partie de la requête.

A ces polygones, nous allons ajouter le reste des surfaces occupées par la couche rectangles (en jaune sur l’image suivante)

select 0 as id1, rectangles.id as id2, st_difference(rectangles.geom,

(select st_multi(st_union(the_geom) ) as the_geom from (
select st_intersection(cercle.geom,rectangles.geom) as the_geom
from cercle,rectangles
where st_intersects(cercle.geom,rectangles.geom) )
as the_geom)) as the_geom
from rectangles

Ce que nous faisons avec cette requête est d’extraire toutes les zones d’intersection (comme dans la requête précédente) et les convertir en un seul et unique multi-polygone. La requête extrait après la différence de ce multi-polygone avec la couche de rectangles.

Pour finir, à ces polygones, nous allons ajouter le reste des surfaces occupées par la couche cercles (en jaune sur l’image suivante)

 

Nous procédons de la même manière que pour les rectangles, en utilisant un multi-polygone des zones d’intersection et en calculant la différence avec la couche cercles:

select cercle.id as id1, 0 as id2,st_difference(cercle.geom,(
select st_multi(st_union(the_geom) ) as the_geom from (
select st_intersection(cercle.geom,rectangles.geom) as the_geom
from cercle,rectangles
where st_intersects(cercle.geom,rectangles.geom) )
as the_geom)) as the_geom
from cercle

L’union de ces trois requêtes produit la couche résultat que nous attendions:

select *
from
(select cercle.id as id1,rectangles.id as       id2,st_intersection(cercle.geom,rectangles.geom) as the_geom
from cercle,rectangles
where st_intersects(cercle.geom,rectangles.geom)
group by cercle.id,rectangles.id
union all
select 0 as id1, rectangles.id as id2,st_difference(rectangles.geom,(
select st_multi(st_union(the_geom) ) as the_geom from (
select st_intersection(cercle.geom,rectangles.geom) as the_geom
from cercle,rectangles
where st_intersects(cercle.geom,rectangles.geom) )
as the_geom)) as the_geom
from rectangles
union all
select cercle.id as id1, 0 as id2,st_difference(cercle.geom,(
select st_multi(st_union(the_geom) ) as the_geom from (
select st_intersection(cercle.geom,rectangles.geom) as the_geom
from cercle,rectangles
where st_intersects(cercle.geom,rectangles.geom) )
as the_geom)) as the_geom
from cercle
)as T1

 

Si cet article vous a intéressé et que vous pensez qu'il pourrait bénéficier à d'autres personnes, n'hésitez pas à le partager sur vos réseaux sociaux en utilisant les boutons ci-dessous. Votre partage est apprécié !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *