Le constat : les calculs ne sont pas bons#
Date de publication initiale : 18 juillet 2024
Dans nos SIG, les opérations de superposition (overlay dans la langue de Shakespeare) telles que les intersections, les unions, les différences, etc. ainsi que l'accrochage utilisé par les dessinateurs, sont omniprésentes. Ces processus s'appuient sur des calculs similaires, simplifiés ici pour une meilleure compréhension dans cette présentation générale.
Cet article est la première partie de la série d'été sur la gestion de la géométrie dans les SIG.
Identification du problème#
Chargement des données#
Toutes les données utilisées sont disponibles sur mon GitHub, et pour simplifier la compréhension et la transposition de ces données dans différents SIG, j'utiliserai les formats WKB et WKT1.
autopromo
Pour celles et ceux qui veulent en savoir plus sur ces formats, pensez à suivre Geotribu sur les réseaux sociaux ou à vous abonner à notre newsletter pour être informé du prochain article dédié .
Revenons-en au fait, prenons un exemple avec une géométrie de type ligne, ici fermée, mais cela serait similaire pour un polygone (puisqu'un polygone est une ligne). Les géométries utilisées sont projetées dans le système de coordonnées EPSG:3946, projection de mon coin magnifique.
Exemple d'une géométrie de ligne au format WKB :
0102000000050000007997c6b68d3c3e4139eb62c260d55341ac9ea7316a3c3e41cbeb40e073d55341403e0bfbc33c3e41b3fc06f380d55341387a2a800c3d3e41f256b8176dd553417997c6b68d3c3e4139eb62c260d55341
À partir de cette ligne, je génère d'autres lignes qui s'accrochent aux points d'intersection/accrochage avec la ligne suivante :
Sur QGIS, on peut charger ces WKB - ainsi que les EWKB, EWKT, WKT - avec le très utile plugin QuickWKT.
Ce qui nous donne :
Intersections de ces lignes#
Nous avons désormais notre base pour étudier ce problème de précision/tolérance/intersection.
Justement, calculons l'intersection entre ces lignes. Pour cela, nous allons utiliser l'outil native:lineintersections
de QGIS.
Nous obtenons deux points d'intersection. Visuellement, les résultats sont conformes à nos attentes, les points d'intersection se trouvant précisément sur les lignes.
Quand je dis « précisément », si l'on visualise sur une échelle totalement « absurde », on a toujours cette superposition.
Pour plus tard, on notera leurs WKB :
dont l'équivalent WKT est POINT(1981640.7849060092 5199258.022088398)
et
respectivement POINT(1981583.6205737416 5199333.301878075)
Création de lignes depuis ces intersections#
QGIS propose différentes options pour s'accrocher. On en utilisera deux, l'accrochage sur un sommet et l'accrochage aux intersections.
Accrochage sur les points d'intersection#
Tout d'abord, on va utiliser la fonctionnalité d'accrochage sur les intersections. Attention, ce n'est pas sur les points que l'on vient de générer, mais sur les intersections entre les géométries. On repère l'icône d'accrochage d'intersection avec une croix. L'accrochage sur un sommet avec un carré.
Dans la vidéo ci-après, je montre comment j'ai généré des lignes de part et d'autre de la ligne principale aux points d'intersection.
Accrochage sur les intersections#
Je répète l'opération, cette fois en me focalisant sur les points d'intersection. L'objectif est de garantir l'accrochage précis sur la ligne principale, indépendamment des variations des sommets adjacents.
Comparaison des points d'accrochage#
On fait confiance à QGIS et, visuellement, les lignes apparaissent bien accrochées à la ligne de base.
Comparons maintenant nos géométries textuelles. On a 8 lignes/segments dans les deux cas. Si l'accrochage se déroule correctement, on devrait avoir les mêmes points de départs.
line_intersection
:
wkb_geom | wkt_geom |
---|---|
b'010200000002000000b5ebdd9e8f3c3e416bf8515379d5534124c410b4923c3e411668a7ae7bd55341' | LineString (1981583.62057374161668122 5199333.30187807511538267, 1981586.70338083151727915 5199342.7289676871150732) |
b'010200000002000000b5ebdd9e8f3c3e416bf8515379d553414819cb1c8c3c3e41d19efa7177d55341' | LineString (1981583.62057374161668122 5199333.30187807511538267, 1981580.11247404105961323 5199325.78092165384441614) |
b'010200000002000000a899efc8c83c3e4175e5698166d5534120d8f49bcc3c3e41ff84f6ed68d55341' | LineString (1981640.78490600921213627 5199258.02208839822560549, 1981644.60920477658510208 5199267.71817135717719793) |
b'010200000002000000a899efc8c83c3e4175e5698166d55341bc8cd13bc53c3e411d15f16064d55341' | LineString (1981640.78490600921213627 5199258.02208839822560549, 1981637.23366622533649206 5199249.5147145064547658) |
b'010200000002000000a899efc8c83c3e4175e5698166d5534199299383d33c3e412d56acf265d55341' | LineString (1981640.78490600921213627 5199258.02208839822560549, 1981651.51396427140571177 5199255.79176859278231859) |
b'010200000002000000a899efc8c83c3e4175e5698166d55341faacc621bc3c3e4126b2ed1567d55341' | LineString (1981640.78490600921213627 5199258.02208839822560549, 1981628.13193780044093728 5199260.34263280592858791) |
b'010200000002000000b5ebdd9e8f3c3e416bf8515379d55341dc272032983c3e41f6e5308b78d55341' | LineString (1981583.62057374161668122 5199333.30187807511538267, 1981592.19580315705388784 5199330.17485951445996761) |
b'010200000002000000b5ebdd9e8f3c3e416bf8515379d5534167a9c58f873c3e41c2567db879d55341' | LineString (1981583.62057374161668122 5199333.30187807511538267, 1981575.56160982861183584 5199334.88265007920563221) |
line_snap
:
wkb_geom | wkt_geom |
---|---|
b'010200000002000000b5ebdd9e8f3c3e416bf8515379d553419c2333eb913c3e417ba04d457cd55341' | LineString (1981583.62057374161668122 5199333.30187807511538267, 1981585.91874907072633505 5199345.08286296855658293) |
b'010200000002000000b5ebdd9e8f3c3e416bf8515379d553416d6001368d3c3e41080dad2b77d55341' | LineString (1981583.62057374161668122 5199333.30187807511538267, 1981581.2109585062135011 5199324.68243718892335892) |
b'010200000002000000b5ebdd9e8f3c3e416bf8515379d553412f400c50963c3e413ab69fef78d55341' | LineString (1981583.62057374161668122 5199333.30187807511538267, 1981590.31268693110905588 5199331.74412303604185581) |
b'010200000002000000b5ebdd9e8f3c3e416bf8515379d5534142628f76863c3e41b7d3bff479d55341' | LineString (1981583.62057374161668122 5199333.30187807511538267, 1981574.46312536345794797 5199335.82420819159597158) |
b'010200000002000000a899efc8c83c3e4175e5698166d55341259db491ca3c3e410908b4b168d55341' | LineString (1981640.78490600921213627 5199258.02208839822560549, 1981642.56916219857521355 5199266.77661324385553598) |
b'010200000002000000a899efc8c83c3e4175e5698166d5534175e25c6ad23c3e4164c45eac65d55341' | LineString (1981640.78490600921213627 5199258.02208839822560549, 1981650.41547980648465455 5199254.69328412786126137) |
b'010200000002000000a899efc8c83c3e4175e5698166d55341cccd8ccdc63c3e414a00e65664d55341' | LineString (1981640.78490600921213627 5199258.02208839822560549, 1981638.80292974691838026 5199249.35778815485537052) |
b'010200000002000000a899efc8c83c3e4175e5698166d55341d0a0d012bd3c3e4126b2ed1567d55341' | LineString (1981640.78490600921213627 5199258.02208839822560549, 1981629.07349591329693794 5199260.34263280592858791) |
On remarque que nos points d'origine sont dans les deux cas :
1981583.62057374161668122 5199333.30187807511538267
1981640.78490600921213627 5199258.02208839822560549
respectivement en WKB :
0101000000b5ebdd9e8f3c3e416bf8515379d55341
0101000000a899efc8c83c3e4175e5698166d55341
Les lignes semblent donc avoir été correctement accrochées, comme le montrent nos représentations en WKT et WKB.
En effet, on retrouve bien les coordonnées d'origine :
b5ebdd9e8f3c3e416bf8515379d55341
et a899efc8c83c3e4175e5698166d55341
dans les points.
Sélection des lignes intersectant la base#
Par conséquent, nous avons des lignes qui sont sur le point d'intersection. Si l'on souhaite vérifier l'accrochage, on utilise le prédicat « intersecte » de QGIS. Pour vérifier cela, utilisons l'outil « sélection par localisation » :
Le prédicat intersects
avec line_snap
#
On regarde si line_snap
est accroché sur base
. Dans les exemples ci-après, même si je devrais n'utiliser que touches ou intersects, je vais tout cocher sauf disjoint.
Le résultat :
Aïe, seulement 2 sur les 4…
Le prédicat intersects
avec line_intersection
#
On fait de même pour line_intersection
:
Et voici le résultat :
Re Aïe. Seulement 2 sur les 4, et du même côté. C'est au moins ça de cohérent dans notre incohérence…
Est-ce que ce n'est que pour ces deux points ?#
Pour aller plus loin, je réalise des tests aléatoires en essayant d'accrocher la ligne principale à différents endroits. C'est la couche test_line
dans le GeoPackage.
Dans notre franchise OSGeo, QGIS est un de nos superhéros, tel Spider-Man. Notre petite toile d'araignée manque de glu, car notre accrochage n'est toujours pas bon :
Testons tous les 1 mètre sur la base#
Il y a quelques années, j'ai développé un outil pour créer des transects. Il génère des bandes, suivant un angle donné. Il est principalement utilisé pour des analyses sur des profils en travers, en génie civil, en écologie, etc. Ici, on va réaliser un transect avec l'outil… « transect », tous les mètres de part et d'autre de la ligne principale.
Pour commencer, nous allons densifier la géométrie :
Ensuite, on génère de cette couche les transects à gauche et à droite de la ligne (suivant le sens de la ligne) :
Notre dessin ressemble à :
Et maintenant, on va sélectionner les entités de transect_left
et transect_right
qui intersectent la base :
Et, non, ce n'est pas l'algo de transect qui est tout buggué.
Mais, comme on dit… "Caramba ! Encore raté !"
Et si je teste sur la géométrie densifiée ?
Et notre résultat ?
Cela fonctionne ! Mais pourquoi ?
Et bien, nous verrons cela plus tard.
Auteur·ice#
Loïc Bartoletti#
Après un cursus en Histoire, je me suis orienté vers l'urbanisme sur l'aménagement des territoires.
J'ai travaillé pendant environ 10 ans dans une station touristique dans les Alpes, Megève, en tant qu'urbaniste puis responsable du bureau d'études et administrateur SIG.
Bidouilleur et partisan des solutions OpenSource, j'ai commencé à toucher à GRASS, puis QGIS et PostGIS. Au fil du temps j'ai contribué à ces logiciels, principalement pour migrer des outils DAO vers le SIG et je suis aujourd'hui commiter QGIS, PostGIS et FreeBSD où je m'occupe des paquets des outils OSGeo et plus si affinité.
Licence Beerware #
Ce contenu est sous licence Beerware (Révision 42).
Les médias d'illustration sont potentiellement soumis à d'autres conditions d'utilisation.
Réutiliser, citer l'article
Tant que vous conservez cette licence :
- vous pouvez faire ce que vous voulez de ce contenu
- si vous rencontrez l'auteur/e un jour et que vous pensez que ce contenu vaut le coup, vous pouvez lui payer un coup en retour
Citer cet article :
"Le constat : les calculs géométriques ne sont pas bons" publié par Loïc Bartoletti sur Geotribu - Source : https://geotribu.fr/articles/2024/2024-07-18_de-la-tolerance-en-sig-geometrie-01-calculs-intersects-qgis-pas-bons/
-
formats standards de représentation des géométries :
- WKB (Well-Known Binary) : Le WKB est un format binaire utilisé pour représenter des objets géométriques de manière compacte et efficace, couramment utilisé dans les bases de données géospatiales pour le stockage et l'échange de données géographiques.
- WKT (Well-Known Text) : Le WKT est un format texte utilisé pour représenter des objets géométriques de manière lisible par l'humain. Il est souvent utilisé pour le partage et l'affichage de données géographiques.
Commentaires
Une version minimale de la syntaxe markdown est acceptée pour la mise en forme des commentaires.
Propulsé par Isso.
Ce contenu est sous licence Beerware