OSM DATA V2 : de la visualisation cartographique à la scène 3D#
Date de publication initiale : 18 mars 2025
Introduction#
Dans l'article précédent, le processus de gestion des données SIG a été présenté afin de définir des flux cartographiques WMS et WFS. Ces flux permettent d'exposer des données en 2D, mais comment est générée la visualisation 3D avec OSM DATA ?
De manière simple, les géométries Point
, Polyline
, Polygon
peuvent être représentées en 3D en renseignant l'altitude dans la géométrie (PointZ
, PolylineZ
, PolygonZ
) ou alors à l'aide d'une valeur attributaire définie pour chaque entité.
Avec les entités polygonales, il est aussi possible de générer des volumes en 3D à l'aide de traitements géométriques. Par exemple et pour tout le reste de cet article, nous allons nous intéresser à la modélisation architecturale.
Processus de modélisation architecturale 3D dans OSM DATA#
Pour ce processus, nous utilisons la table planet_osm_polygon
dans laquelle nous retrouvons les informations suivantes :
- L'emprise géométrique du bâtiment ou/et de la toiture représentée par le polygone considéré.
- La hauteur de la toiture roof:height définie entre le sommet le plus haut de la toiture et son sommet le plus bas.
- La hauteur du bâtiment par rapport au sol min_height définie entre le point le plus bas du bâtiment et le point projeté au sol.
- La hauteur du point le plus haut du bâtiment par rapport au sol height définie entre le point le plus haut du bâtiment et le point projeté au sol.
- Le type de toiture définissant la forme du toit.
- La texture caractérisant les matériaux du toit et/ou de la façade.
Avec l'ensemble de ces informations, il est donc possible de reconstruire le bâti en 3D d'un territoire en appliquant à l'ensemble des polygones le processus suivant :
- Création de la toiture
- Reconstruction des façades
- Application des matériaux
Cet article aborde la création de la toiture, le prochain article présente la génération des façades. En modélisation 3D, la notion de Level Of Detail (LOD) est importante et caractérise le niveau de représentation géométrique d'un objet, il s'appuie sur l'une des normes suivantes :
- BIMForum, essentiellement utilisée dans le cadre de projets Building Information Modeling (BIM)
- CityGML, largement répandue dans la création de socles 3D territoriaux
OpenStreetMap étant une base de données d'emprise mondiale, il nous semble plus pertinent d'utiliser la norme CityGML pour définir le niveau de détail. Dans OSM DATA, le niveau de détail est équivalent à celui d'un LOD2.
Exemple de modélisation#
Pour faciliter la compréhension, utilisons un exemple pour présenter l'ensemble du processus de modélisation 3D.
Considérons le bâtiment suivant dans OpenStreetMap (oui oui ce bâtiment est présent dans l'Opéra Garnier) :
Le GeoJSON
de ce bâtiment est :
GeoJSON du bâtiment exemple
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
259521.14076069795,
6253167.799861707
],
[
259606.34863939675,
6253192.28359733
],
[
259590.5611086523,
6253248.230426137
],
[
259505.31590718575,
6253223.7466905145
],
[
259521.14076069795,
6253167.799861707
]
]
]
},
"properties": {
"roofType": "gabled",
"roofHeight": 10,
"roofOrientation": "along",
"type": "building",
"minHeight": 31,
"roofMaterial": "metal",
"osmId": 822290992,
"buildingType": "yes",
"height": 58
}
}
L'objectif est d'arriver au résultat suivant :
Pour le reste de l'article, à des fins de simplification, les visualisations 3D sont affichées sous Three.js. Dans le dernier article, nous présentons la visualisation avec Giro3D dans OSM DATA.
Création de la toiture#
En interprétant le fichier GeoJSON
ci-dessus, nous avons les informations suivantes concernant le bâtiment considéré :
- Hauteur de la toiture : 10 m.
- Hauteur du bâtiment par rapport au sol : 31 m.
- Hauteur du point le plus bas de la toiture : 48 m (height 58 m - roof:height 10 m).
- Hauteur du point le plus haut du bâtiment par rapport au sol : 58 m
- Type de toiture : Gabled (toiture à pignon).
- Texture : Métal.
Pour réaliser la toiture, trois étapes sont nécessaires :
- Détermination du squelette droit (straight skeleton).
- Post-traitement du squelette afin de l'ajuster au type de toiture.
- Ajout de la hauteur à chaque sommet du squelette.
Pour réaliser cette transformation, nous nous appuyons sur la bibliothèque CGAL.
Détermination du squelette droit (straight skeleton)#
La construction d'un squelette droit permet de définir, à partir de l'emprise d'un polygone, la version la plus fine d'un polygone jusqu'à l'obtention d'un ou plusieurs axes médians. Si vous n'avez rien compris, c'est normal, on essaye d'une autre manière : imaginez qu'un polygone (rectangle pour faire facile) se rétracte progressivement comme si ses bords brûlaient uniformément vers l'intérieur. Les lignes tracées par les sommets qui se déplacent pendant cette "rétraction" forment le squelette droit. Si vous n'avez toujours rien compris, c'est encore normal, rendez-vous sur Wikipedia pour les bilingues.
La majorité des toitures dans OSM DATA sont construites à l'aide du squelette droit. En assignant une hauteur à chaque segment du squelette et/ou à chaque sommet du polygone initial, il est donc possible de générer des toitures complexes et cohérentes avec la géométrie initiale.
Sur la page ci-dessous, nous illustrons le polygone de notre bâtiment exemple (en haut) associé à son squelette droit (en bas).
Si on ajoute une hauteur à l'axe médian uniquement on obtient donc le résultat suivant :
Post-traitement du squelette droit pour obtenir la forme à pignon (Gabled)#
En considérant le squelette droit précédemment créé, on peut donc décomposer le polygone initial en quatre polygones :
- En rose, 2 polygones à trois sommets (des triangles pour les plus scientifiques)
- En vert, 2 polygones à quatre sommets (à vous de donner la réponse en commentaire !)
Ci-dessous, l'écriture de ces quatre polygones au format JSON
, chacun avec un somment de début et un sommet de fin de polygone :
Les 4 polygones associées au squelette droit
{
"polygons": [
{
"vertices": [
{
"x": 259521.140625,
"y": 6253168
},
{
"x": 259540.953125,
"y": 6253203.5
},
{
"x": 259505.3125,
"y": 6253223.5
}
],
"edgeStart": {
"x": 259505.3125,
"y": 6253223.5
},
"edgeEnd": {
"x": 259521.140625,
"y": 6253168
}
},
{
"vertices": [
{
"x": 259606.34375,
"y": 6253192.5
},
{
"x": 259570.71875,
"y": 6253212.5
},
{
"x": 259540.953125,
"y": 6253203.5
},
{
"x": 259521.140625,
"y": 6253168
}
],
"edgeStart": {
"x": 259521.140625,
"y": 6253168
},
"edgeEnd": {
"x": 259606.34375,
"y": 6253192.5
}
},
{
"vertices": [
{
"x": 259590.5625,
"y": 6253248
},
{
"x": 259570.71875,
"y": 6253212.5
},
{
"x": 259606.34375,
"y": 6253192.5
}
],
"edgeStart": {
"x": 259606.34375,
"y": 6253192.5
},
"edgeEnd": {
"x": 259590.5625,
"y": 6253248
}
},
{
"vertices": [
{
"x": 259505.3125,
"y": 6253223.5
},
{
"x": 259540.953125,
"y": 6253203.5
},
{
"x": 259570.71875,
"y": 6253212.5
},
{
"x": 259590.5625,
"y": 6253248
}
],
"edgeStart": {
"x": 259590.5625,
"y": 6253248
},
"edgeEnd": {
"x": 259505.3125,
"y": 6253223.5
}
}
]
}
Afin d'obtenir un toit à pignon, nous souhaitons atteindre le résultat suivant :
Ainsi, il faut supprimer les polygones roses et modifier les sommets des polygones verts en deux étapes :
- Modification des sommets des deux polygones verts : projection orthogonale des sommets intérieurs sur la base des triangles roses.
- Suppression des triangles roses
Ces deux actions peuvent être faites de manières simultanées (à voir dans l'onglet TypeScript
) :
Notre squelette maintenant adapté au type de toit, il faut affecter une hauteur à chaque sommet.
Ajout de la hauteur à chaque sommet du squelette#
Pour représenter les polygones en WebGL (et donc avec Three.js et Giro3D), il convient de réaliser un réseau triangulé irrégulier (Triangulated Irregular Network, TIN) à partir du squelette modifié. Les triangles disposent des avantages suivants :
- Les triangles sont la forme polygonale la plus simple, définie par seulement trois sommets. Ils représentent une surface toujours plane quelle que soit la position des sommets.
- Tout polygone, aussi complexe soit-il, peut être décomposé en un ensemble de triangles.
La triangulation est réalisée avec la bibliothèque JS Earcut pour obtenir la géométrie ci-dessous : Chaque polygone est représenté par deux triangles.
Pour rappel, voici les informations importantes pour l'affectation des hauteurs :
- Hauteur de la toiture : 10 m.
- Hauteur du bâtiment par rapport au sol : 31 m.
- Hauteur du point le plus bas de la toiture : 48 m (height 58 m - roof:height 10 m).
Dans le cas de notre polygone, la détermination des hauteurs est assez simple car il n'y a que deux hauteurs différentes.
Dans le cas de toitures plus complexes et à des fins d'industrialisation de la solution, nous avons défini une formule de détermination générale de la hauteur pour chaque point de notre géométrie. Soit le point i, son altitude est définie de la manière suivante :
\(Zi = height - roof:height + roof:height * (Dmax / Di)\)
Avec :
- \(Zi\), la hauteur du point souhaité.
- \(Dmax\), la distance projetée maximale entre le point haut de la toiture et le point bas.
- \(Di\), la distance projetée entre le point haut de la toiture et le point souhaité.
Dans notre cas, la formule ci-dessous est égale à :
\(Zi = 58 - 10 + 10 * (Dmax / Di) = 48 + 10 * (Dmax / Di)\)
La même schéma mais en 3D pour une meilleure représentation de Dmax
:
Pour déterminer la valeur \(Dmax\), on analyse tous les polygones par itération afin de déterminer la distance projetée entre deux points la plus importante sur notre géométrie. La fenêtre ci-dessous détaille les caluls implémentés.
Nous avons déterminé \(Dmax\) pour notre exemple, sa valeur est de 28.85 m. La formule ci-dessus est utilisée afin de déterminer chaque hauteur de sommet. On peut alors visualiser notre toiture en 3D à l'aide de Three.js (n'hésitez pas à bouger la scène avec votre souris ).
Dans ce troisième article, nous avons construit la toiture d’un bâtiment issu d’OpenStreetMap. Les principales étapes sont la génération du squelette droit, sa correction éventuelle, la triangulation et la détermination de la hauteur de chaque sommet. Dans le prochain article, nous présentons la génération des façades afin de produire le modèle géométrique 3D complet du bâtiment.
2 : Des données à la cartographie
Auteur·ices#
Karl TAYOU#
Passionné et curieux par tout ce qui tourne au tour du SIG, 3D et OpenStreetMap.
Principal développeur de demo.openstreetmap.fr
Romain LATAPIE#
Géomètre de formation, j'ai découvert l'open-source au fil de relevés topographiques/bathymétriques et du développement d'outils géospatiaux au Québec pour Tetra Tech. Revenu en France en 2022, je me suis intéressé à la modélisation 3D et au BIM avec FUTURMAP. Je travaille désormais à Siradel, toujours avec un projet QGIS / PostGIS sous le coude !
Licence #
Ce contenu est sous licence Creative Commons International 4.0 BY-NC-SA, avec attribution et partage dans les mêmes conditions, sauf dans le cadre d'une utilisation commerciale.
Les médias d'illustration sont potentiellement soumis à d'autres conditions d'utilisation.
Réutiliser, citer l'article
Vous êtes autorisé(e) à :
- Partager : copier, distribuer et communiquer le matériel par tous moyens et sous tous formats
- Adapter : remixer, transformer et créer à partir du matériel pour toute utilisation, exceptée commerciale.
Citer cet article :
"OSM Data : Extrusion des données en 3D" publié par Karl TAYOU, Romain LATAPIE sur Geotribu sous CC BY-NC-SA - Source : https://geotribu.fr/articles/2025/2025-03-10_osm-data-3D-03-modelisation-toiture/
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 Creative Commons BY-NC-SA 4.0 International