diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b540e621f9..37d12fc12c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,11 +5,22 @@ repos: hooks: - id: check-hooks-apply + - repo: local + hooks: + - id: geotribu-strip-autogenerated-author-article-lists + name: Supprime les listes d'articles autogénérées des pages auteurs + entry: python -m hooks.precommit.git_nocommit_author_autolist + exclude: ^content/team/archive/ + files: ^content/team/.*\.md$ + language: python + pass_filenames: true + - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 hooks: - id: check-added-large-files - id: check-case-conflict + - id: check-illegal-windows-names - id: check-yaml args: - --unsafe diff --git a/content/articles/2024/2024-12-24_QGIS-Layers-Menu-From-Project-Le-catalogue-magique.md b/content/articles/2024/2024-12-24_QGIS-Layers-Menu-From-Project-Le-catalogue-magique.md index 00bef6ea97..3ed644f26a 100644 --- a/content/articles/2024/2024-12-24_QGIS-Layers-Menu-From-Project-Le-catalogue-magique.md +++ b/content/articles/2024/2024-12-24_QGIS-Layers-Menu-From-Project-Le-catalogue-magique.md @@ -1,157 +1,157 @@ ---- -title: "LMFP : LE catalogue magique !" -subtitle: Deux voix, une magie -authors: - - Emilie BIGORNE - - Céline PORNIN -categories: - - article -comments: true -date: 2024-12-24 -description: "Une extension QGIS peut-être (trop) méconnue : Layers Menu From Project permet de simplifier la vie des administrateurs ET des utilisateurs, retour d'expérience à deux voix. " -icon: fontawesome/solid/wand-magic-sparkles -image: https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2024/retex_layers_menu_from_project/be-qool_myriade.png -license: default -robots: index, follow -tags: - - Layers Menu From Project - - plugin QGIS - - QGIS ---- - -# Plugin Layers Menu From Project : LE catalogue magique ! - -:calendar: Date de publication initiale : {{ page.meta.date | date_localized }} - -Bonjour à toi lectrice ou lecteur ! - -Aujourd'hui, à deux voix, nous avons choisi de faire un retour d'expérience sur l'utilisation d'une extension QGIS peut être (trop) méconnue : [Layers Menu From Project](https://plugins.qgis.org/plugins/menu_from_project/#plugin-details). - -[Commenter cet article :fontawesome-solid-comments:](#__comments "Aller aux commentaires"){: .md-button } -{: align=middle } - ----- - -## Menus magiques - par Émilie - -J'ai découvert il y a déjà plusieurs années, l'outil "layers menu from project" et depuis, les utilisateurs ne jurent plus que par ça. Chez nous, on l'appelle "menu magique". - -### Pourquoi c'est magique - -[Layers menu from project](https://aeag.github.io/MenuFromProject-Qgis-Plugin/index.html) répond aux questions récurrentes des utilisateurs : où est stockée la donnée (sur le serveur, dans une base de données, dans un flux WMS ?), q'elle est la dernière version, comment dois-je la représenter ? Les données sont désormais accessibles en 2 clics, depuis des menus intégrés directement à QGIS. - -Grâce à LMFP, en deux coups de baguette magique, la donnée est affichée ! - -![Be Qool](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2024/retex_layers_menu_from_project/be-qool_myriade.png){: .img-center loading=lazy } - -### Comment ça fonctionne ? - -Les entrées du menu correspondent aux couches stockées dans un projet QGIS (qgs ou qgz), accessible depuis les postes utilisateurs. Les données peuvent être vecteurs ou rasters, des fichiers plats, issues d'une base de données ou des flux, et toute la configuration de la couche est conservée : symbologie, actions, mise en forme de la table attributaire, formulaire, notes de couche,… - -Concrètement, l’administrateur prépare le.s projet.s QGIS, l’utilisateur le pointe dans le plugin LMFP et le tour est joué. - -![QGIS - Exemple de menus générés par le plugin Layers Menu From Project](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2024/retex_layers_menu_from_project/LMFP_QGIS_EP-Loire_exemple.webp){: .img-center loading=lazy } - - -!!! tip "Astuce déploiement" - ![logo QDT (QGIS Deployment Toolbelt)](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/qdt.webp){: .img-thumbnail-left } - - Pour encore plus de rapidité côté administrateur et de simplicité côté utilisateur, le déploiement peut se faire via [QGIS Deployment Toolbelt (QDT)](https://qgis-deployment.github.io/qgis-deployment-toolbelt-cli/#) : installation du plugin et paramétrage automatique selon les profils utilisateurs. - - -### L'association avec une base de données PostgreSQL - -Avec une base PG, je peux afficher les couches directement depuis une requête, plus besoin de stocker des vues qui induisent des dépendances parfois complexes. En revanche, attention, le mode de connexion à la base (identifiant/mot de passe) est également stocké. - -!!! tip "Astuce sécurité" - Pour contourner cette difficulté, j'ajoute des couches depuis une connexion dont je n'ai pas sauvegardé les paramètres d'authentification. Ainsi, l'utilisateur est invité à saisir ses propres identifiants. - -### Une limite de taille ? - -Dans la théorie, non. En revanche, un projet source avec trop de couches va mettre beaucoup de temps à s'ouvrir et c'est l'administrateur qui va être embêté pour faire ses mises à jour. Mais l'outil propose une solution : il est possible de créer une entrée (un menu) à partir de plusieurs projets QGIS. Ainsi, on peut avoir plusieurs petits projets plus faciles à maintenir plutôt qu'un seul gros projet. - -Pour l'utilisateur, un menu trop long peut être inconfortable. Pour remédier aux listes trop longues, plus ou moins bien organisées, il est possible de grouper les couches en sous-menu (voire sous-sous-menu) en utilisant les groupes de couches. Un groupe de couches vide peut également être utilisé comme séparateur. - -### En action - -Les actions des couches sont également conservées. On peut par exemple permettre, au clic sur des entités, d'ouvrir une page web, de charger des dalles raster ou des photos (moyennant quelques lignes de Python) - -!!! quote "La conclusion d'Émilie" - En interne, on adore la magie. - ----- - -## LE catalogue - par Céline - -De mon côté, c'est sur un outil mutualisé par plusieurs structures que LMFP a changé la donne ! - -**C'est pratique, voilà pourquoi !** - -### Du côté utilisateur - -Une base de données pour plusieurs structures, ça veut dire plusieurs utilisateurs plus ou moins habitués à l'utilisation de QGIS. -**La formation et l'accompagnement ne font pas tout, il nous fallait une solution "User friendly"** ergonomique et facile à lire pour n'importe qui. -Du coup, la liste des couches configurées depuis la base de données dans l'explorateur : ça ne fonctionne pas ! Un menu dédié, qu'on a appelé "catalogue" : c'est explicite et c'est facile pour tout le monde. - -![Le plugin LMFP rend les utilisateurs finaux heureux - Testé en laboratoire](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2024/retex_layers_menu_from_project/lmfp_utilisateur_qgis_malheureux_heureux.webp){: .img-center loading=lazy } - -### Du côté administrateur - -La liste des couches configurée depuis la base de données dans l'explorateur : ça ne fonctionne pas non plus ! Il faudrait nommer les schémas, tables et vues et que tout soit rangé en pensant à l'utilisateur ... ou utiliser un schéma dédié avec toutes les vues renommées ... -Avec LMFP : pas de sujet ! **Peu importe le modèle de données, c'est le nommage et la configuration dans le projet QGIS utilisé qui comptent** (et bienvenue aux accents et aux espaces). - -!!! tip "Autre avantage" - Étant donné qu'il est possible aussi de mettre des flux, on s'épargne des actions de mise à jour et on remercie les producteurs de gérer leurs mises à jour tous seuls ! - -Comme dit précédemment : la principale contrainte est alors liée au maintien du projet QGIS en entrée du plugin et à l'accès des utilisateurs à ce projet. Chez nous, il est enregistré en base de données. Une authentification avec un identifiant / mot de passe est enregistrée à la première connexion de l'utilisateur, qui lui donne accès au projet via le menu et aux différentes données en base (en lecture ou en écriture). - -!!! tip "Encore plus de paillettes" - En plus des groupes, sous-groupes et agencement de différents projets, il est possible de créer des sections avec des titres et des séparateurs. Rendez-vous sur la documentation du plugin pour rendre tout ça encore plus beau ! [C'est par ici](https://aeag.github.io/MenuFromProject-Qgis-Plugin/usage/fr_use.html#). - -Pour finir, la **cerise sur le gateau : la mise à jour d'un outil sans réinstallation ou téléchargement.** -Notre outil est en constante évolution : champs, listes de valeurs, symbologie ... on change des trucs régulièrement (on corrige aussi des fautes de frappe dans les formulaires par exemple...). Il suffit simplement à l'utilisateur de recharger la couche depuis le menu pour que tout soit à jour : pas besoin de redémmarrer QGIS, réinstaller une extension, aller chercher un style enregistré quelque part ou encore télécharger et écraser un projet QGIS ! - -### L'évolution du plugin - -Il n'y a pas que nos outils qui évoluent, le plugin aussi ! -L'année dernière, on a commencé à intégrer des relations dans notre projet QGIS. Le problème : charger une couche depuis le menu ne chargeait ni l'autre (ou les autres) couche(s) ni la relation. - -Un ticket Git, quelques échanges avec le développeur : et voilà, problème réglé. - -Aujourd'hui, on a remarqué d'autres limites à cette extension (nul n'est parfait ...) alors on va continuer d'apporter notre contribution et nos retours pour la faire évoluer. Et quand on est plusieurs concernés, autant mutualiser, et c'est ce qu'on va faire avec d'autres structures qui utilisent ce plugin ! - -!!! quote "La conclusion de Céline" - User et Administrateur friendly ! - ----- - -## En résumé - - -### Nos :material-plus-thick: - - -* Facile d'utilisation pour les utilisateurs et adaptable par groupes d'utilisateurs -* Facile à configurer -* Permets de rendre accessible des données issues de différentes sources (base de données, fichiers, flux, requêtes...) -* Permets de gérer facilement les styles (symbologie, formulaires, actions) -* Mises à jour des données et styles facilitées -* Une communauté de fans grandissante qui va permettre de faire évoluer l'extension pour encore plus de magie ! - - -### Nos :material-minus-thick: - - -* Attention aux menus trop longs : le projet initial est lourd, le chargement trop impactant sur les perfs d'ouverture du logiciel -* Trop de menus différents : temps d'ouverture de QGIS plus long - -* Des optimisations à faire côté performances dans certains cas techniques - -!!! success "Le mot de la fin" - Un grand merci à tous les développeurs et financeurs des évolutions du plugin LMFP ! - ----- - - - -{% include "licenses/default.md" %} +--- +title: "LMFP : LE catalogue magique !" +subtitle: Deux voix, une magie +authors: + - Emilie BIGORNE + - Céline PORNIN +categories: + - article +comments: true +date: 2024-12-24 +description: "Une extension QGIS peut-être (trop) méconnue : Layers Menu From Project permet de simplifier la vie des administrateurs ET des utilisateurs, retour d'expérience à deux voix. " +icon: fontawesome/solid/wand-magic-sparkles +image: https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2024/retex_layers_menu_from_project/be-qool_myriade.png +license: default +robots: index, follow +tags: + - Layers Menu From Project + - plugin QGIS + - QGIS +--- + +# Plugin Layers Menu From Project : LE catalogue magique ! + +:calendar: Date de publication initiale : {{ page.meta.date | date_localized }} + +Bonjour à toi lectrice ou lecteur ! + +Aujourd'hui, à deux voix, nous avons choisi de faire un retour d'expérience sur l'utilisation d'une extension QGIS peut être (trop) méconnue : [Layers Menu From Project](https://plugins.qgis.org/plugins/menu_from_project/#plugin-details). + +[Commenter cet article :fontawesome-solid-comments:](#__comments "Aller aux commentaires"){: .md-button } +{: align=middle } + +---- + +## Menus magiques - par Émilie + +J'ai découvert il y a déjà plusieurs années, l'outil "layers menu from project" et depuis, les utilisateurs ne jurent plus que par ça. Chez nous, on l'appelle "menu magique". + +### Pourquoi c'est magique + +[Layers menu from project](https://aeag.github.io/MenuFromProject-Qgis-Plugin/index.html) répond aux questions récurrentes des utilisateurs : où est stockée la donnée (sur le serveur, dans une base de données, dans un flux WMS ?), q'elle est la dernière version, comment dois-je la représenter ? Les données sont désormais accessibles en 2 clics, depuis des menus intégrés directement à QGIS. + +Grâce à LMFP, en deux coups de baguette magique, la donnée est affichée ! + +![Be Qool](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2024/retex_layers_menu_from_project/be-qool_myriade.png){: .img-center loading=lazy } + +### Comment ça fonctionne ? + +Les entrées du menu correspondent aux couches stockées dans un projet QGIS (qgs ou qgz), accessible depuis les postes utilisateurs. Les données peuvent être vecteurs ou rasters, des fichiers plats, issues d'une base de données ou des flux, et toute la configuration de la couche est conservée : symbologie, actions, mise en forme de la table attributaire, formulaire, notes de couche,… + +Concrètement, l’administrateur prépare le.s projet.s QGIS, l’utilisateur le pointe dans le plugin LMFP et le tour est joué. + +![QGIS - Exemple de menus générés par le plugin Layers Menu From Project](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2024/retex_layers_menu_from_project/LMFP_QGIS_EP-Loire_exemple.webp){: .img-center loading=lazy } + + +!!! tip "Astuce déploiement" + ![logo QDT (QGIS Deployment Toolbelt)](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/qdt.webp){: .img-thumbnail-left } + + Pour encore plus de rapidité côté administrateur et de simplicité côté utilisateur, le déploiement peut se faire via [QGIS Deployment Toolbelt (QDT)](https://qgis-deployment.github.io/qgis-deployment-toolbelt-cli/#) : installation du plugin et paramétrage automatique selon les profils utilisateurs. + + +### L'association avec une base de données PostgreSQL + +Avec une base PG, je peux afficher les couches directement depuis une requête, plus besoin de stocker des vues qui induisent des dépendances parfois complexes. En revanche, attention, le mode de connexion à la base (identifiant/mot de passe) est également stocké. + +!!! tip "Astuce sécurité" + Pour contourner cette difficulté, j'ajoute des couches depuis une connexion dont je n'ai pas sauvegardé les paramètres d'authentification. Ainsi, l'utilisateur est invité à saisir ses propres identifiants. + +### Une limite de taille ? + +Dans la théorie, non. En revanche, un projet source avec trop de couches va mettre beaucoup de temps à s'ouvrir et c'est l'administrateur qui va être embêté pour faire ses mises à jour. Mais l'outil propose une solution : il est possible de créer une entrée (un menu) à partir de plusieurs projets QGIS. Ainsi, on peut avoir plusieurs petits projets plus faciles à maintenir plutôt qu'un seul gros projet. + +Pour l'utilisateur, un menu trop long peut être inconfortable. Pour remédier aux listes trop longues, plus ou moins bien organisées, il est possible de grouper les couches en sous-menu (voire sous-sous-menu) en utilisant les groupes de couches. Un groupe de couches vide peut également être utilisé comme séparateur. + +### En action + +Les actions des couches sont également conservées. On peut par exemple permettre, au clic sur des entités, d'ouvrir une page web, de charger des dalles raster ou des photos (moyennant quelques lignes de Python) + +!!! quote "La conclusion d'Émilie" + En interne, on adore la magie. + +---- + +## LE catalogue - par Céline + +De mon côté, c'est sur un outil mutualisé par plusieurs structures que LMFP a changé la donne ! + +**C'est pratique, voilà pourquoi !** + +### Du côté utilisateur + +Une base de données pour plusieurs structures, ça veut dire plusieurs utilisateurs plus ou moins habitués à l'utilisation de QGIS. +**La formation et l'accompagnement ne font pas tout, il nous fallait une solution "User friendly"** ergonomique et facile à lire pour n'importe qui. +Du coup, la liste des couches configurées depuis la base de données dans l'explorateur : ça ne fonctionne pas ! Un menu dédié, qu'on a appelé "catalogue" : c'est explicite et c'est facile pour tout le monde. + +![Le plugin LMFP rend les utilisateurs finaux heureux - Testé en laboratoire](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2024/retex_layers_menu_from_project/lmfp_utilisateur_qgis_malheureux_heureux.webp){: .img-center loading=lazy } + +### Du côté administrateur + +La liste des couches configurée depuis la base de données dans l'explorateur : ça ne fonctionne pas non plus ! Il faudrait nommer les schémas, tables et vues et que tout soit rangé en pensant à l'utilisateur ... ou utiliser un schéma dédié avec toutes les vues renommées ... +Avec LMFP : pas de sujet ! **Peu importe le modèle de données, c'est le nommage et la configuration dans le projet QGIS utilisé qui comptent** (et bienvenue aux accents et aux espaces). + +!!! tip "Autre avantage" + Étant donné qu'il est possible aussi de mettre des flux, on s'épargne des actions de mise à jour et on remercie les producteurs de gérer leurs mises à jour tous seuls ! + +Comme dit précédemment : la principale contrainte est alors liée au maintien du projet QGIS en entrée du plugin et à l'accès des utilisateurs à ce projet. Chez nous, il est enregistré en base de données. Une authentification avec un identifiant / mot de passe est enregistrée à la première connexion de l'utilisateur, qui lui donne accès au projet via le menu et aux différentes données en base (en lecture ou en écriture). + +!!! tip "Encore plus de paillettes" + En plus des groupes, sous-groupes et agencement de différents projets, il est possible de créer des sections avec des titres et des séparateurs. Rendez-vous sur la documentation du plugin pour rendre tout ça encore plus beau ! [C'est par ici](https://aeag.github.io/MenuFromProject-Qgis-Plugin/usage/fr_use.html#). + +Pour finir, la **cerise sur le gateau : la mise à jour d'un outil sans réinstallation ou téléchargement.** +Notre outil est en constante évolution : champs, listes de valeurs, symbologie ... on change des trucs régulièrement (on corrige aussi des fautes de frappe dans les formulaires par exemple...). Il suffit simplement à l'utilisateur de recharger la couche depuis le menu pour que tout soit à jour : pas besoin de redémmarrer QGIS, réinstaller une extension, aller chercher un style enregistré quelque part ou encore télécharger et écraser un projet QGIS ! + +### L'évolution du plugin + +Il n'y a pas que nos outils qui évoluent, le plugin aussi ! +L'année dernière, on a commencé à intégrer des relations dans notre projet QGIS. Le problème : charger une couche depuis le menu ne chargeait ni l'autre (ou les autres) couche(s) ni la relation. + +Un ticket Git, quelques échanges avec le développeur : et voilà, problème réglé. + +Aujourd'hui, on a remarqué d'autres limites à cette extension (nul n'est parfait ...) alors on va continuer d'apporter notre contribution et nos retours pour la faire évoluer. Et quand on est plusieurs concernés, autant mutualiser, et c'est ce qu'on va faire avec d'autres structures qui utilisent ce plugin ! + +!!! quote "La conclusion de Céline" + User et Administrateur friendly ! + +---- + +## En résumé + + +### Nos :material-plus-thick: + + +* Facile d'utilisation pour les utilisateurs et adaptable par groupes d'utilisateurs +* Facile à configurer +* Permets de rendre accessible des données issues de différentes sources (base de données, fichiers, flux, requêtes...) +* Permets de gérer facilement les styles (symbologie, formulaires, actions) +* Mises à jour des données et styles facilitées +* Une communauté de fans grandissante qui va permettre de faire évoluer l'extension pour encore plus de magie ! + + +### Nos :material-minus-thick: + + +* Attention aux menus trop longs : le projet initial est lourd, le chargement trop impactant sur les perfs d'ouverture du logiciel +* Trop de menus différents : temps d'ouverture de QGIS plus long + +* Des optimisations à faire côté performances dans certains cas techniques + +!!! success "Le mot de la fin" + Un grand merci à tous les développeurs et financeurs des évolutions du plugin LMFP ! + +---- + + + +{% include "licenses/default.md" %} diff --git a/content/articles/2025/2025-02-25_stack_data_gard.md b/content/articles/2025/2025-02-25_stack_data_gard.md index 38bd05e455..a33a9afd84 100644 --- a/content/articles/2025/2025-02-25_stack_data_gard.md +++ b/content/articles/2025/2025-02-25_stack_data_gard.md @@ -1,289 +1,289 @@ ---- -title: "L'enjeu de la data au département du Gard" -subtitle: "Taradata, stack moderne" -authors: - - Satya MINGUEZ -categories: - - article -comments: true -date: 2025-02-25 -description: Comment le département du Gard valorise son patrimoine de données classiques et de géo-données au travers de différents outils numériques. -icon: fontawesome/solid/cubes-stacked -image: https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/affiche.png -tags: - - Apache Airflow - - DBT - - GDAL - - Metabase - - Open Source - - PostGIS - - PostgreSQL - - Python - - QGIS ---- - -# L’enjeu de la data au département du Gard - -:calendar: Date de publication initiale : {{ page.meta.date | date_localized }} - -![Logo du département du Gard](https://cdn.geotribu.fr/img/logos-icones/entreprises_association/gard.jpg){: .img-thumbnail-left } - -Le département du Gard dispose de [plusieurs compétences](https://www.gard.fr/ses-missions) parmi lesquelles l'aide sociale et l'infrastructure routière. Il entretient et améliore un réseau de 4 600 km de routes afin de sécuriser les déplacements. - -L’éducation fait également partie de ses missions, notamment à travers la gestion de 53 collèges publics. À cela s’ajoutent d’autres domaines importants comme la culture et les archives départementales. - -Dans chacun de ces domaines, une grande quantité de données est produite et consommée, c'est ce patrimoine de données que le département souhaite valoriser pour notamment aider les directions et services à prendre les décisions éclairées dans l'exercice de leurs missions. - -Auparavant, les analyses se faisaient plutôt dans des silos métiers mais aussi des silos techniques avec une séparation BI/SIG. Or, le croisement de données de natures et de sources diverses peut apporter de l'information. - -C'est pourquoi une étude a été menée auprès de différents acteurs de l'écosystème data afin de définir une stratégie de valorisation des données. Un département c'est avant tout un territoire, cela implique que les données que nous traitons sont en grande partie géolocalisées. -Notre volonté était de ne pas séparer les données classiques et les géo-données dans deux systèmes distincts, mais de les traiter et de les valoriser dans une même architecture. - -L'objectif de l'étude était donc de tirer les meilleures pratiques de chacun et d'adapter la démarche à nos besoins. - -Il va donc être question pour la suite, de te présenter la démarche mise en place ainsi que les outils retenus par le département du Gard pour valoriser son patrimoine de données. - ----- - -## Vers un nouveau modèle Data - -L'analyse s'est faite auprès d'acteurs dans le secteur public (les confrères territoriaux), le secteur privé mais aussi auprès de responsables de masters universitaires dans le domaine de la géomatique. - -### 1. Ce que nous avons appris - -En se renseignant auprès de nos confrères du secteur public, nous nous sommes rendu compte qu'aucun modèle ne se dégageait véritablement. Et plus encore, nous avons souvent constaté une séparation entre data et SIG. - -Du côté du secteur privé, nous avons retenu plusieurs choses, notamment un modèle qui semble l'emporter : La **Modern Data Stack**. - -Pour définir une Modern Data Stack (MDS), le plus simple est de la comparer avec un modèle traditionnel (TDS). - -Le modèle traditionnel est souvent construit autour d'un outil unique et propriétaire installé localement (On-Premise). À l'inverse, la Modern Data Stack est plus modulaire. Plusieurs outils y sont combinés, chacun ayant un rôle dédié de la collecte à la valorisation des données. Ceux-ci sont en général Open Source et hébergés sur le Cloud en mode SaaS. - -Par ailleurs, le modèle de traitement diffère. En traditionnel, l'approche ETL (Extract Transform Load) est privilégiée c'est-à-dire que la transformation de la donnée est préalable à son intégration dans l'entrepôt. En MDS, les données sont d'abord importées avant d'être transformées ; on parle d'ELT (Extract Load Transform). - -Pour résumer, ces différences peuvent être synthétisées dans le tableau suivant : - -| Caractéristique | Traditional Data Stack | Modern Data Stack | -| :---------------------------- | :-------------------------------------- | :----------------------------------- | -| **Architecture** | Monolithique / Graphique (ex. FME) | Modulaire / As Code | -| **Hébergement** | Logiciels On-Premise | Cloud / SaaS | -| **Logiciels** | Fermés, propriétaires | Plus ouverts, souvent Open Source | -| **Approche de traitement** | ETL (Extract, Transform, Load) | ELT (Extract, Load, Transform) | - -Si tu as envie de creuser un peu, laisse-moi te recommander quelques ressources en ligne : - -- Définition et avantages d'une MDS : -- MDS expliquée en vidéo par [Michael Kahan](https://www.youtube.com/c/KahanDataSolutions) (la vidéo est en anglais, sous-titres disponibles) : -- ETL vs ELT (sous-titres dispo) - -### 2. Notre stratégie - -Notre objectif initial était de réunir les données classiques et géographiques au sein d'un même système, afin de tirer parti de leur complémentarité. Pour y parvenir, nous avons élaboré une stratégie consistant à construire un modèle de traitement des données inspiré des principes de la Modern Data Stack, tout en l'adaptant pour répondre aux spécificités liées à la composante géographique. - ----- - -## Taradata : notre Data Stack - -La stack mise en oeuvre au département porte le nom de **Taradata**. - -Bien qu'inspirée des principes de la MDS, Taradata n'en est pas une version stricte. En effet, nos logiciels ne sont pas hébergés sur le Cloud, mais plutôt On-Premise / [Docker](https://fr.wikipedia.org/wiki/Docker_(logiciel)). Cependant, nous avons conservé les éléments essentiels d'une MDS, comme la modularité et l'approche ELT. - -### Son utilité - -Nous devons traiter les données dites **« attributaires »** et **« géographiques »**. -Cela implique : - -1. Extraire les données provenant de sources variées comme les bases de données, les API, les données issues d’IoT, etc. -2. Charger ces données dans un entrepôt. -3. Transformer ces données via renommages, restructurations et associations. -4. Entreposer dans une base de données. -5. Valoriser ces données via des tableaux de bords, cartographie, etc. - -Voici le principe de la stack simplifié au travers d'un schéma : - -![Schéma de la stack Taradata](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/principes_taradata.png){: .img-center loading=lazy } - ----- - -### Les outils - -Mettre en place une Modern Data Stack, c'est choisir les différentes briques qui la constituent, nous allons détailler ici les outils retenus pour Taradata. - -#### PostgreSQL/PostGIS - -![Logo PostgreSQL](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/postgresql.png){: .img-thumbnail-left } - -Pour l'entrepôt de données, nous avons retenu PostgreSQL/[PostGIS](https://postgis.net/) simplement car nous n'avons pas trouvé d'équivalence en termes de traitement pour la composante géographique dans les moteurs les plus utilisés en MDS. - -À titre d'exemple [GoogleBigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions) et [Snowflake](https://docs.snowflake.com/en/sql-reference/functions-geospatial), qui sont deux entrepôts de données Cloud, disposent, au moment où j'écris ces lignes, respectivement de 67 et 70 fonctions géographiques, alors que [PostGIS en propose plus de 500](https://postgis.net/docs/manual-3.5/reference.html). - -#### Extraction et chargement : GDAL/OGR (ogr2ogr) - -![GDAL/OGR](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/gdal.png){: .img-thumbnail-left } - -[ogr2ogr](https://gdal.org/en/stable/programs/ogr2ogr.html) permet d'extraire et charger des données : - -- de différentes natures (notamment des données géographiques), -- de différents formats (CSV, SHP, GPKG, GeoJSON...), -- de différentes sources. - -Voilà à quoi pourrait ressembler une extraction de données au format GeoJSON par un appel API avec au passage une transformation du système de coordonnées. - -```bash -PG:"dbname='' host ='' port='5432' user='***' password='***'" --f PostgreSQL -GeoJSON:"https://data.sncf.com/api/explore/v2.1/catalog/datasets/liste-des-passages-a- -niveau/exports/geojson?select=id_if%2Clibelle%2Cmnemo%2Cobstacle%2Ccode_ligne%2Crg_troncon%2Cdiffr%2Cc_geo -&where=in_bbox%28c_geo%2C43.15738485671127%2C%201.839594309811448%2C%2045.36619392221315%2C%205.8304424666 -54746%29" --s_srs EPSG:4326 --t_srs EPSG:2154 --lco SCHEMA=src_data_sncf_com --lco OVERWRITE=YES --nln passages_a_niveau -``` - -A ce stade, les données sont chargées dans l'entrepôt mais de façon brute. Nous avons donc besoin d'un outil pour les transformer. - ----- - -#### Transformation : Data Build Tool (DBT) - -![DBT logo](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/dbt.png){: .img-thumbnail-left } - -Dans le paragraphe qui précède, nous avons vu comment OGR nous aide à charger les données. Il faut maintenant les transformer. -Ça tombe bien, pour la transformation nous avons retenu [DBT](https://docs.getdbt.com/docs/core/installation-overview), un logiciel dont la version Core est Open Source sous licence Apache et utilisable en lignes de commandes. Il existe également une version Cloud. - -C'est un peu un abus de langage de dire qu'il transforme les données simplement car c'est l’entrepôt, soit dans notre cas PostgreSQL/PostGIS qui s'en charge. -On peut dire que DBT a pour rôle de commander les transformations. - -Les transformations sont décrites en SQL/[Jinja](https://jinja.palletsprojects.com/en/stable/). -Voici par exemple une transformation des données de la [Base Adresse Nationale (BAN)](https://adresse.data.gouv.fr/) lors de l'étape dite de [staging](https://docs.getdbt.com/best-practices/how-we-structure/2-staging) : - -{% raw %} - -```sql+jinja title="Script SQL templaté avec la syntaxe Jinja dans DBT" linenums="1" -{% set departements = ["07", "12", "13", "26", "30", "34", "48", "84"] %} - -with adresses as ( - {% for departement in departements %} - select * - from {{ source("src_adresse_data_gouv_fr", "adresses_" ~ departement) }} - {% if not loop.last %} union all {% endif %} - {% endfor %} -), -selections_typages_renommages as ( - select - {{ to_integer_or_null("numero") }} as numero, - {{ trim_or_null_if_empty("suffixe") }} as suffixe, - {{ trim_or_null_if_empty("voie_nom") }} as nom_voie, - {{ trim_or_null_if_empty("commune_insee") }} as cog_commune, - {{ trim_or_null_if_empty("source") }} as source, - {{ trim_or_null_if_empty("position") }} as position, - {{ to_numeric_or_null("long") }} as longitude, - {{ to_numeric_or_null("lat") }} as latitude - from adresses -), -geolocalisations as ( - select - *, - case - when {{ is_valid_longitude("longitude") }} and {{ is_valid_latitude("latitude") }} - then {{ to_srid_2154(make_2d_point_4326("longitude", "latitude")) }} - end as geom - from selections_typages_renommages -) -select * -from geolocalisations -``` - -{% endraw %} - -Le logiciel permet aussi de connaître le [lignage](https://fr.wikipedia.org/wiki/Data_lineage) de la donnée c'est-à-dire la capacité à visualiser et tracer l'origine, les transformations, et les relations entre les différentes données. -Voici un extrait de lignage avec les données sources en vert, la donnée finale en violet et toutes les liaisons. - -![Lignage de la donnée](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/lignage_dbt.png){: .img-center loading=lazy } - -Documenter les données est aussi une possibilité que nous offre le logiciel. - -![Extrait de documentation](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/documentation_dbt.png){: .img-center loading=lazy } - -Pour aller plus loin, je te conseille vivement la [playlist DBT](https://www.youtube.com/playlist?list=PLy4OcwImJzBLJzLYxpxaPUmCWp8j1esvT), toujours de Michael Kahan qui est une excellente source d'apprentissage et qui te détaillera bien plus les spécificités du logiciel que moi. - ----- - -#### Orchestration : Apache Airflow - -![Logo Apache Airflow](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/airflow.png){: .img-thumbnail-left } - -Apache Airflow est [l'orchestrateur](https://github.com/apache/airflow/blob/main/README.md), la clé de voûte de toute la stack. Son objectif est de décrire les tâches à réaliser et planifier leur exécution. - -Dans Airflow, les tâches sont définies et organisées dans ce qu’on appelle un DAG (_Directed Acyclic Graph_), une structure qui permet de représenter les relations et l’ordre d’exécution des tâches. Ces tâches sont créées à l'aide de scripts Python (car Airflow est écrit en Python) - -Et donc Airflow nous permet de : - -- définir les tâches en Python, -- spécifier les contraintes entre les tâches, -- organiser les tâches dans un DAG, -- planifier l’exécution des DAGs et suivre leur avancement. - -Tu peux trouver ci-dessous une représentation graphique des différentes dépendances entre les tâches d'un DAG d'extraction et chargement des données de la BAN concernant le Gard ainsi que ses départements limitrophes. - -![Représentation graphique des tâches pour le DAG de la BAN](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/graph_ban_airflow.png){: .img-center loading=lazy } - ----- - -#### Valorisation avec Metabase et QGIS - -![Logo Metabase](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/Metabase.png){: .img-thumbnail-left } - -Après avoir fait ce cheminement, il faut bien que nos données servent à quelque chose. On a justement au travers de [Metabase](https://www.metabase.com/) tout un champ de possibilités concernant la représentation de nos données transformées. C’est l’outil de Data Visualisation. - -Dans l'idéal, nous aurions souhaité un outil aussi performant en dataviz qu'en représentation cartographique mais cet outil n'existe vraisemblablement pas encore, donc nous complétons ça avec QGIS. -Metabase est limité en carto certes (pas de carte multi-couches, pas de gestion de la symbologie), mais il est auto hébergé et permet de produire des tableaux de bord de manière autonome. - -Voyons un peu les actions qu'il permet de faire : - -- Interroger l’entrepôt en mode graphique. -- Représenter les données sous différentes formes. -- Combiner plusieurs visualisations dans des tableaux de bord. -- Ajouter des filtres interactifs sur les données affichées. - ----- - -### Interaction avec les données - -Découvrons justement ce qu'il est possible de faire avec Metabase au travers d'un cas d'usage. - -L'exemple ci-dessous, réalisé en collaboration avec la direction des bâtiments, te montre la localisation ponctuelle des différents sites présents dans le département (collèges, actions sociales, ...). - -![Dashboard de la localisation des sites](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/dashboard_dlog_metabase.png){: .img-center loading=lazy } - -Il est possible, comme spécifié plus haut, de filtrer nos données par catégorie, nom et autres. - -![Fitres Metabase](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/filtres_metabase.png){: .img-center loading=lazy } - -Et voici le résultat lorsqu'on active le filtre sur la catégorie "ENVIRONNEMENT". - -![Dashboard avec le filtre Environnement](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/dashboard_dlog_filtre.png){: .img-center loading=lazy } - -## En résumé - -Si tu as bien suivi, tu as sans doute compris que nous avions un outil pour chacune des étapes pour respecter la modularité d'une MDS. - -![Stack Taradata](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/stack_taradata.png){: .img-center loading=lazy } - -## Quelques ressources - -Tu pourras trouver le lien vers le support que [Michaël](https://geotribu.fr/team/michael-galien/) a présenté lors des GeoDataDays de Nantes les 19 et 20 septembre 2024. Il explique la Modern Data Stack et détaille le cas d'usage Metabase que je t'ai présenté plus haut. - -[Modern GIS Stack - Geodatadays 2024 :simple-slideshare:](https://www.geodatadays.fr/_medias/afigeo/files/GDD_2024/Presentations/3_GDD24_Modern_GIS_Stack_GARD.pdf){ .md-button } -{: align=middle } - -Dans ce replay de la Forward Data Conference, il présente comment la composante géographique a été prise en compte dans Taradata. - - - - - +--- +title: "L'enjeu de la data au département du Gard" +subtitle: "Taradata, stack moderne" +authors: + - Satya MINGUEZ +categories: + - article +comments: true +date: 2025-02-25 +description: Comment le département du Gard valorise son patrimoine de données classiques et de géo-données au travers de différents outils numériques. +icon: fontawesome/solid/cubes-stacked +image: https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/affiche.png +tags: + - Apache Airflow + - DBT + - GDAL + - Metabase + - Open Source + - PostGIS + - PostgreSQL + - Python + - QGIS +--- + +# L’enjeu de la data au département du Gard + +:calendar: Date de publication initiale : {{ page.meta.date | date_localized }} + +![Logo du département du Gard](https://cdn.geotribu.fr/img/logos-icones/entreprises_association/gard.jpg){: .img-thumbnail-left } + +Le département du Gard dispose de [plusieurs compétences](https://www.gard.fr/ses-missions) parmi lesquelles l'aide sociale et l'infrastructure routière. Il entretient et améliore un réseau de 4 600 km de routes afin de sécuriser les déplacements. + +L’éducation fait également partie de ses missions, notamment à travers la gestion de 53 collèges publics. À cela s’ajoutent d’autres domaines importants comme la culture et les archives départementales. + +Dans chacun de ces domaines, une grande quantité de données est produite et consommée, c'est ce patrimoine de données que le département souhaite valoriser pour notamment aider les directions et services à prendre les décisions éclairées dans l'exercice de leurs missions. + +Auparavant, les analyses se faisaient plutôt dans des silos métiers mais aussi des silos techniques avec une séparation BI/SIG. Or, le croisement de données de natures et de sources diverses peut apporter de l'information. + +C'est pourquoi une étude a été menée auprès de différents acteurs de l'écosystème data afin de définir une stratégie de valorisation des données. Un département c'est avant tout un territoire, cela implique que les données que nous traitons sont en grande partie géolocalisées. +Notre volonté était de ne pas séparer les données classiques et les géo-données dans deux systèmes distincts, mais de les traiter et de les valoriser dans une même architecture. + +L'objectif de l'étude était donc de tirer les meilleures pratiques de chacun et d'adapter la démarche à nos besoins. + +Il va donc être question pour la suite, de te présenter la démarche mise en place ainsi que les outils retenus par le département du Gard pour valoriser son patrimoine de données. + +---- + +## Vers un nouveau modèle Data + +L'analyse s'est faite auprès d'acteurs dans le secteur public (les confrères territoriaux), le secteur privé mais aussi auprès de responsables de masters universitaires dans le domaine de la géomatique. + +### 1. Ce que nous avons appris + +En se renseignant auprès de nos confrères du secteur public, nous nous sommes rendu compte qu'aucun modèle ne se dégageait véritablement. Et plus encore, nous avons souvent constaté une séparation entre data et SIG. + +Du côté du secteur privé, nous avons retenu plusieurs choses, notamment un modèle qui semble l'emporter : La **Modern Data Stack**. + +Pour définir une Modern Data Stack (MDS), le plus simple est de la comparer avec un modèle traditionnel (TDS). + +Le modèle traditionnel est souvent construit autour d'un outil unique et propriétaire installé localement (On-Premise). À l'inverse, la Modern Data Stack est plus modulaire. Plusieurs outils y sont combinés, chacun ayant un rôle dédié de la collecte à la valorisation des données. Ceux-ci sont en général Open Source et hébergés sur le Cloud en mode SaaS. + +Par ailleurs, le modèle de traitement diffère. En traditionnel, l'approche ETL (Extract Transform Load) est privilégiée c'est-à-dire que la transformation de la donnée est préalable à son intégration dans l'entrepôt. En MDS, les données sont d'abord importées avant d'être transformées ; on parle d'ELT (Extract Load Transform). + +Pour résumer, ces différences peuvent être synthétisées dans le tableau suivant : + +| Caractéristique | Traditional Data Stack | Modern Data Stack | +| :---------------------------- | :-------------------------------------- | :----------------------------------- | +| **Architecture** | Monolithique / Graphique (ex. FME) | Modulaire / As Code | +| **Hébergement** | Logiciels On-Premise | Cloud / SaaS | +| **Logiciels** | Fermés, propriétaires | Plus ouverts, souvent Open Source | +| **Approche de traitement** | ETL (Extract, Transform, Load) | ELT (Extract, Load, Transform) | + +Si tu as envie de creuser un peu, laisse-moi te recommander quelques ressources en ligne : + +- Définition et avantages d'une MDS : +- MDS expliquée en vidéo par [Michael Kahan](https://www.youtube.com/c/KahanDataSolutions) (la vidéo est en anglais, sous-titres disponibles) : +- ETL vs ELT (sous-titres dispo) + +### 2. Notre stratégie + +Notre objectif initial était de réunir les données classiques et géographiques au sein d'un même système, afin de tirer parti de leur complémentarité. Pour y parvenir, nous avons élaboré une stratégie consistant à construire un modèle de traitement des données inspiré des principes de la Modern Data Stack, tout en l'adaptant pour répondre aux spécificités liées à la composante géographique. + +---- + +## Taradata : notre Data Stack + +La stack mise en oeuvre au département porte le nom de **Taradata**. + +Bien qu'inspirée des principes de la MDS, Taradata n'en est pas une version stricte. En effet, nos logiciels ne sont pas hébergés sur le Cloud, mais plutôt On-Premise / [Docker](https://fr.wikipedia.org/wiki/Docker_(logiciel)). Cependant, nous avons conservé les éléments essentiels d'une MDS, comme la modularité et l'approche ELT. + +### Son utilité + +Nous devons traiter les données dites **« attributaires »** et **« géographiques »**. +Cela implique : + +1. Extraire les données provenant de sources variées comme les bases de données, les API, les données issues d’IoT, etc. +2. Charger ces données dans un entrepôt. +3. Transformer ces données via renommages, restructurations et associations. +4. Entreposer dans une base de données. +5. Valoriser ces données via des tableaux de bords, cartographie, etc. + +Voici le principe de la stack simplifié au travers d'un schéma : + +![Schéma de la stack Taradata](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/principes_taradata.png){: .img-center loading=lazy } + +---- + +### Les outils + +Mettre en place une Modern Data Stack, c'est choisir les différentes briques qui la constituent, nous allons détailler ici les outils retenus pour Taradata. + +#### PostgreSQL/PostGIS + +![Logo PostgreSQL](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/postgresql.png){: .img-thumbnail-left } + +Pour l'entrepôt de données, nous avons retenu PostgreSQL/[PostGIS](https://postgis.net/) simplement car nous n'avons pas trouvé d'équivalence en termes de traitement pour la composante géographique dans les moteurs les plus utilisés en MDS. + +À titre d'exemple [GoogleBigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions) et [Snowflake](https://docs.snowflake.com/en/sql-reference/functions-geospatial), qui sont deux entrepôts de données Cloud, disposent, au moment où j'écris ces lignes, respectivement de 67 et 70 fonctions géographiques, alors que [PostGIS en propose plus de 500](https://postgis.net/docs/manual-3.5/reference.html). + +#### Extraction et chargement : GDAL/OGR (ogr2ogr) + +![GDAL/OGR](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/gdal.png){: .img-thumbnail-left } + +[ogr2ogr](https://gdal.org/en/stable/programs/ogr2ogr.html) permet d'extraire et charger des données : + +- de différentes natures (notamment des données géographiques), +- de différents formats (CSV, SHP, GPKG, GeoJSON...), +- de différentes sources. + +Voilà à quoi pourrait ressembler une extraction de données au format GeoJSON par un appel API avec au passage une transformation du système de coordonnées. + +```bash +PG:"dbname='' host ='' port='5432' user='***' password='***'" +-f PostgreSQL +GeoJSON:"https://data.sncf.com/api/explore/v2.1/catalog/datasets/liste-des-passages-a- +niveau/exports/geojson?select=id_if%2Clibelle%2Cmnemo%2Cobstacle%2Ccode_ligne%2Crg_troncon%2Cdiffr%2Cc_geo +&where=in_bbox%28c_geo%2C43.15738485671127%2C%201.839594309811448%2C%2045.36619392221315%2C%205.8304424666 +54746%29" +-s_srs EPSG:4326 +-t_srs EPSG:2154 +-lco SCHEMA=src_data_sncf_com +-lco OVERWRITE=YES +-nln passages_a_niveau +``` + +A ce stade, les données sont chargées dans l'entrepôt mais de façon brute. Nous avons donc besoin d'un outil pour les transformer. + +---- + +#### Transformation : Data Build Tool (DBT) + +![DBT logo](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/dbt.png){: .img-thumbnail-left } + +Dans le paragraphe qui précède, nous avons vu comment OGR nous aide à charger les données. Il faut maintenant les transformer. +Ça tombe bien, pour la transformation nous avons retenu [DBT](https://docs.getdbt.com/docs/core/installation-overview), un logiciel dont la version Core est Open Source sous licence Apache et utilisable en lignes de commandes. Il existe également une version Cloud. + +C'est un peu un abus de langage de dire qu'il transforme les données simplement car c'est l’entrepôt, soit dans notre cas PostgreSQL/PostGIS qui s'en charge. +On peut dire que DBT a pour rôle de commander les transformations. + +Les transformations sont décrites en SQL/[Jinja](https://jinja.palletsprojects.com/en/stable/). +Voici par exemple une transformation des données de la [Base Adresse Nationale (BAN)](https://adresse.data.gouv.fr/) lors de l'étape dite de [staging](https://docs.getdbt.com/best-practices/how-we-structure/2-staging) : + +{% raw %} + +```sql+jinja title="Script SQL templaté avec la syntaxe Jinja dans DBT" linenums="1" +{% set departements = ["07", "12", "13", "26", "30", "34", "48", "84"] %} + +with adresses as ( + {% for departement in departements %} + select * + from {{ source("src_adresse_data_gouv_fr", "adresses_" ~ departement) }} + {% if not loop.last %} union all {% endif %} + {% endfor %} +), +selections_typages_renommages as ( + select + {{ to_integer_or_null("numero") }} as numero, + {{ trim_or_null_if_empty("suffixe") }} as suffixe, + {{ trim_or_null_if_empty("voie_nom") }} as nom_voie, + {{ trim_or_null_if_empty("commune_insee") }} as cog_commune, + {{ trim_or_null_if_empty("source") }} as source, + {{ trim_or_null_if_empty("position") }} as position, + {{ to_numeric_or_null("long") }} as longitude, + {{ to_numeric_or_null("lat") }} as latitude + from adresses +), +geolocalisations as ( + select + *, + case + when {{ is_valid_longitude("longitude") }} and {{ is_valid_latitude("latitude") }} + then {{ to_srid_2154(make_2d_point_4326("longitude", "latitude")) }} + end as geom + from selections_typages_renommages +) +select * +from geolocalisations +``` + +{% endraw %} + +Le logiciel permet aussi de connaître le [lignage](https://fr.wikipedia.org/wiki/Data_lineage) de la donnée c'est-à-dire la capacité à visualiser et tracer l'origine, les transformations, et les relations entre les différentes données. +Voici un extrait de lignage avec les données sources en vert, la donnée finale en violet et toutes les liaisons. + +![Lignage de la donnée](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/lignage_dbt.png){: .img-center loading=lazy } + +Documenter les données est aussi une possibilité que nous offre le logiciel. + +![Extrait de documentation](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/documentation_dbt.png){: .img-center loading=lazy } + +Pour aller plus loin, je te conseille vivement la [playlist DBT](https://www.youtube.com/playlist?list=PLy4OcwImJzBLJzLYxpxaPUmCWp8j1esvT), toujours de Michael Kahan qui est une excellente source d'apprentissage et qui te détaillera bien plus les spécificités du logiciel que moi. + +---- + +#### Orchestration : Apache Airflow + +![Logo Apache Airflow](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/airflow.png){: .img-thumbnail-left } + +Apache Airflow est [l'orchestrateur](https://github.com/apache/airflow/blob/main/README.md), la clé de voûte de toute la stack. Son objectif est de décrire les tâches à réaliser et planifier leur exécution. + +Dans Airflow, les tâches sont définies et organisées dans ce qu’on appelle un DAG (_Directed Acyclic Graph_), une structure qui permet de représenter les relations et l’ordre d’exécution des tâches. Ces tâches sont créées à l'aide de scripts Python (car Airflow est écrit en Python) + +Et donc Airflow nous permet de : + +- définir les tâches en Python, +- spécifier les contraintes entre les tâches, +- organiser les tâches dans un DAG, +- planifier l’exécution des DAGs et suivre leur avancement. + +Tu peux trouver ci-dessous une représentation graphique des différentes dépendances entre les tâches d'un DAG d'extraction et chargement des données de la BAN concernant le Gard ainsi que ses départements limitrophes. + +![Représentation graphique des tâches pour le DAG de la BAN](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/graph_ban_airflow.png){: .img-center loading=lazy } + +---- + +#### Valorisation avec Metabase et QGIS + +![Logo Metabase](https://cdn.geotribu.fr/img/logos-icones/logiciels_librairies/Metabase.png){: .img-thumbnail-left } + +Après avoir fait ce cheminement, il faut bien que nos données servent à quelque chose. On a justement au travers de [Metabase](https://www.metabase.com/) tout un champ de possibilités concernant la représentation de nos données transformées. C’est l’outil de Data Visualisation. + +Dans l'idéal, nous aurions souhaité un outil aussi performant en dataviz qu'en représentation cartographique mais cet outil n'existe vraisemblablement pas encore, donc nous complétons ça avec QGIS. +Metabase est limité en carto certes (pas de carte multi-couches, pas de gestion de la symbologie), mais il est auto hébergé et permet de produire des tableaux de bord de manière autonome. + +Voyons un peu les actions qu'il permet de faire : + +- Interroger l’entrepôt en mode graphique. +- Représenter les données sous différentes formes. +- Combiner plusieurs visualisations dans des tableaux de bord. +- Ajouter des filtres interactifs sur les données affichées. + +---- + +### Interaction avec les données + +Découvrons justement ce qu'il est possible de faire avec Metabase au travers d'un cas d'usage. + +L'exemple ci-dessous, réalisé en collaboration avec la direction des bâtiments, te montre la localisation ponctuelle des différents sites présents dans le département (collèges, actions sociales, ...). + +![Dashboard de la localisation des sites](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/dashboard_dlog_metabase.png){: .img-center loading=lazy } + +Il est possible, comme spécifié plus haut, de filtrer nos données par catégorie, nom et autres. + +![Fitres Metabase](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/filtres_metabase.png){: .img-center loading=lazy } + +Et voici le résultat lorsqu'on active le filtre sur la catégorie "ENVIRONNEMENT". + +![Dashboard avec le filtre Environnement](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/dashboard_dlog_filtre.png){: .img-center loading=lazy } + +## En résumé + +Si tu as bien suivi, tu as sans doute compris que nous avions un outil pour chacune des étapes pour respecter la modularité d'une MDS. + +![Stack Taradata](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/2025/stack_data_gard/stack_taradata.png){: .img-center loading=lazy } + +## Quelques ressources + +Tu pourras trouver le lien vers le support que [Michaël](https://geotribu.fr/team/michael-galien/) a présenté lors des GeoDataDays de Nantes les 19 et 20 septembre 2024. Il explique la Modern Data Stack et détaille le cas d'usage Metabase que je t'ai présenté plus haut. + +[Modern GIS Stack - Geodatadays 2024 :simple-slideshare:](https://www.geodatadays.fr/_medias/afigeo/files/GDD_2024/Presentations/3_GDD24_Modern_GIS_Stack_GARD.pdf){ .md-button } +{: align=middle } + +Dans ce replay de la Forward Data Conference, il présente comment la composante géographique a été prise en compte dans Taradata. + + + + + {% include "licenses/cc4_by.md" %} diff --git a/content/team/nicolas-rochard.md b/content/team/nicolas-rochard.md index a57a82c235..171c6f9415 100644 --- a/content/team/nicolas-rochard.md +++ b/content/team/nicolas-rochard.md @@ -1,32 +1,32 @@ ---- -title: Nicolas Rochard -categories: - - contributeur -hide: - - feedback -social_accounts: - bluesky: badwolf59.bsky.social - github: Doctor-Who - gitlab: - linkedin: nicolas-rochard - mail: - mastodon: - instance: mapstodon.space - username: badwolf42 - openstreetmap: - osgeo: doctorwho - twitter: - website: ---- - -# Nicolas Rochard - - - -![Portrait Nicolas Rochard](https://cdn.geotribu.fr/img/internal/contributeurs/nrochard.jpg "Portrait Nicolas Rochard"){: .img-thumbnail-left } - -Je suis chef de projet data au sein de la Région Hauts-de-France pour la plateforme Geo2France. Je suis spécialisé dans la conception, la gestion et l’exploitation de données, avec un intérêt particulier pour celles liées à l’occupation du sol. Mon travail consiste à animer des groupes de travail collaboratifs, à structurer et mettre en avant des données de qualité, et à développer des outils pour leur valorisation et leur accessibilité. - -Passionné par la philosophie open source, je contribue à divers projets, qu’ils soient liés aux systèmes d’information géographique (SIG) ou à d’autres domaines. Ces contributions reflètent mon engagement pour des solutions ouvertes, collaboratives et innovantes, qui favorisent le partage des connaissances et l’amélioration continue des pratiques. Cette expérience m’a également permis de promouvoir des outils collaboratifs et d’accompagner des équipes dans l’automatisation et l’industrialisation des traitements de données. - - +--- +title: Nicolas Rochard +categories: + - contributeur +hide: + - feedback +social_accounts: + bluesky: badwolf59.bsky.social + github: Doctor-Who + gitlab: + linkedin: nicolas-rochard + mail: + mastodon: + instance: mapstodon.space + username: badwolf42 + openstreetmap: + osgeo: doctorwho + twitter: + website: +--- + +# Nicolas Rochard + + + +![Portrait Nicolas Rochard](https://cdn.geotribu.fr/img/internal/contributeurs/nrochard.jpg "Portrait Nicolas Rochard"){: .img-thumbnail-left } + +Je suis chef de projet data au sein de la Région Hauts-de-France pour la plateforme Geo2France. Je suis spécialisé dans la conception, la gestion et l’exploitation de données, avec un intérêt particulier pour celles liées à l’occupation du sol. Mon travail consiste à animer des groupes de travail collaboratifs, à structurer et mettre en avant des données de qualité, et à développer des outils pour leur valorisation et leur accessibilité. + +Passionné par la philosophie open source, je contribue à divers projets, qu’ils soient liés aux systèmes d’information géographique (SIG) ou à d’autres domaines. Ces contributions reflètent mon engagement pour des solutions ouvertes, collaboratives et innovantes, qui favorisent le partage des connaissances et l’amélioration continue des pratiques. Cette expérience m’a également permis de promouvoir des outils collaboratifs et d’accompagner des équipes dans l’automatisation et l’industrialisation des traitements de données. + + diff --git a/content/team/nicolas-roelandt.md b/content/team/nicolas-roelandt.md index 078c11c51f..f6feb293f0 100644 --- a/content/team/nicolas-roelandt.md +++ b/content/team/nicolas-roelandt.md @@ -1,41 +1,41 @@ ---- -title: Nicolas Roelandt -categories: - - contributeur -hide: - - feedback -social_accounts: - bluesky: - github: - gitlab: - linkedin: - mail: - mastodon: - instance: - username: - openstreetmap: - osgeo: - twitter: - website: ---- - -# Nicolas Roelandt - - - -![portrait Nicolas Roelandt](https://cdn.geotribu.fr/img/internal/contributeurs/nroe.jpg "Bouletmaton Nicolas Roelandt"){: .img-thumbnail-left } - -Géomaticien au sein de l'[Université Gustave Eiffel](https://www.univ-gustave-eiffel.fr/) depuis 2018 suite à une reconversion. -J'avais goûté à la topographie et aux SIG durant ma formation de forestier. -J'ai oeuvré pendant 10 ans en tant que topographe sur des chantiers aéroportuaires, puis lassé je me suis tourné vers la géomatique. -J'ai ensuite suivi la [licence pro](https://www.ensg.eu/Licence-professionnelle) de l'ENSG puis le [master G2M](https://geographie.univ-paris8.fr/?Master-G2M) de l'université Paris8 en alternance. -En 2018, j'ai intégré en tant que géomaticien l'[IFSTTAR](https://www.ifsttar.fr/accueil/) qui deviendra l'Université Gustave Eiffel en 2020. - -Convaincu par les valeurs du logiciel libre, j'ai longtemps été utilisateur. -Lors de ma reconversion, c'est tout naturellement que j'ai cherché les logiciels libres en géomatique. -Je suis devenu contributeur du projet [OSGeoLive](https://live.osgeo.org/fr/index.html) et j'ai participé à l'organisation des événements organisés par l'[OSGeo-fr](https://www.osgeo.asso.fr/). -Par la suite, j'ai rejoint le bureau de l'association. - -En 2019, mon ouvrage [SIG – Introduction à la géomatique et mise en place d’un système d’information géographique libre](https://www.d-booker.fr/sig/582-sig-libre.html) a été publié aux [éditions D-Booker](https://www.d-booker.fr/). - - +--- +title: Nicolas Roelandt +categories: + - contributeur +hide: + - feedback +social_accounts: + bluesky: + github: + gitlab: + linkedin: + mail: + mastodon: + instance: + username: + openstreetmap: + osgeo: + twitter: + website: +--- + +# Nicolas Roelandt + + + +![portrait Nicolas Roelandt](https://cdn.geotribu.fr/img/internal/contributeurs/nroe.jpg "Bouletmaton Nicolas Roelandt"){: .img-thumbnail-left } + +Géomaticien au sein de l'[Université Gustave Eiffel](https://www.univ-gustave-eiffel.fr/) depuis 2018 suite à une reconversion. +J'avais goûté à la topographie et aux SIG durant ma formation de forestier. +J'ai oeuvré pendant 10 ans en tant que topographe sur des chantiers aéroportuaires, puis lassé je me suis tourné vers la géomatique. +J'ai ensuite suivi la [licence pro](https://www.ensg.eu/Licence-professionnelle) de l'ENSG puis le [master G2M](https://geographie.univ-paris8.fr/?Master-G2M) de l'université Paris8 en alternance. +En 2018, j'ai intégré en tant que géomaticien l'[IFSTTAR](https://www.ifsttar.fr/accueil/) qui deviendra l'Université Gustave Eiffel en 2020. + +Convaincu par les valeurs du logiciel libre, j'ai longtemps été utilisateur. +Lors de ma reconversion, c'est tout naturellement que j'ai cherché les logiciels libres en géomatique. +Je suis devenu contributeur du projet [OSGeoLive](https://live.osgeo.org/fr/index.html) et j'ai participé à l'organisation des événements organisés par l'[OSGeo-fr](https://www.osgeo.asso.fr/). +Par la suite, j'ai rejoint le bureau de l'association. + +En 2019, mon ouvrage [SIG – Introduction à la géomatique et mise en place d’un système d’information géographique libre](https://www.d-booker.fr/sig/582-sig-libre.html) a été publié aux [éditions D-Booker](https://www.d-booker.fr/). + + diff --git a/content/team/satya-minguez.md b/content/team/satya-minguez.md index 869e0598f4..128df13ec7 100644 --- a/content/team/satya-minguez.md +++ b/content/team/satya-minguez.md @@ -1,29 +1,29 @@ ---- -title: Satya Minguez -categories: - - contributeur -hide: - - feedback -social_accounts: - bluesky: - github: - gitlab: - linkedin: - mail: - mastodon: - instance: - username: - openstreetmap: - osgeo: - twitter: - website: ---- - -# Satya Minguez - - - -En 2023, j'intègre le [département du Gard](https://www.gard.fr) en tant qu'apprenti développeur de la donnée. -C'est là que je commence à me familiariser avec le monde de la géomatique en travaillant notamment avec QGIS et PostGIS, l'extension géographique de PostgreSQL. - - +--- +title: Satya Minguez +categories: + - contributeur +hide: + - feedback +social_accounts: + bluesky: + github: + gitlab: + linkedin: + mail: + mastodon: + instance: + username: + openstreetmap: + osgeo: + twitter: + website: +--- + +# Satya Minguez + + + +En 2023, j'intègre le [département du Gard](https://www.gard.fr) en tant qu'apprenti développeur de la donnée. +C'est là que je commence à me familiariser avec le monde de la géomatique en travaillant notamment avec QGIS et PostGIS, l'extension géographique de PostgreSQL. + + diff --git a/hooks/mkdocs/G006_authors_block.py b/hooks/mkdocs/G006_authors_block.py index 12650ec095..996fad511e 100644 --- a/hooks/mkdocs/G006_authors_block.py +++ b/hooks/mkdocs/G006_authors_block.py @@ -23,6 +23,7 @@ logger = logging.getLogger("mkdocs") +log_prefix = f"[{__name__}] " dico_contributors = {} exclude_files = [ @@ -33,6 +34,11 @@ "sponsoring.md", ] +# balises pour éviter de dupliquer la section "Liste de mes articles" autogénérée +authors_with_existing_autolist: set[str] = set() +AUTHOR_ARTICLES_AUTOLIST_START = "" +AUTHOR_ARTICLES_AUTOLIST_END = "" + regex_pattern = re.compile( pattern="", flags=re.I | re.M, @@ -54,6 +60,16 @@ def on_files(files: Files, config: MkDocsConfig): ): dico_contributors[Path(f.abs_src_path).stem] = 0 + # Si y'a déjà le marqueur de début, on met la page auteur dans une liste à + # ignorer au prochain build. + content = filepath.read_text(encoding="UTF-8") + if AUTHOR_ARTICLES_AUTOLIST_START in content: + authors_with_existing_autolist.add(filepath.stem) + logger.debug( + log_prefix + + f"[G006] Liste auto-générée déjà présente pour : {filepath.stem}" + ) + # @mkdocs.plugins.event_priority(-100) def on_page_markdown( @@ -69,7 +85,8 @@ def on_page_markdown( page_authors = page.meta.get("authors") if not isinstance(page_authors, list): logger.warning( - f"L'entrée 'authors' de l'en-tête de la page '{page.file.abs_src_path}' est incorrecte." + log_prefix + + f"L'entrée 'authors' de l'en-tête de la page '{page.file.abs_src_path}' est incorrecte." ) return @@ -79,62 +96,82 @@ def on_page_markdown( author_block = "\n## Auteur·ice {: data-search-exclude }\n" for author in page_authors: + author_slug = sluggy(author) + if author == "Geotribu": author_block += '### L\'équipe Geotribu\n\n--8<-- "content/toc_nav_ignored/snippets/authors/geotribu.md:author-sign-block"\n\n' else: - if sluggy(author) not in dico_contributors: - logger.warning( - f"L'auteur/ice '{author}' du contenu '{page.file.abs_src_path}' " - f"n'a pas de page correspondante : {sluggy(author)}" + if author_slug not in dico_contributors: + logger.error( + log_prefix + + f"L'auteur/ice '{author}' du contenu '{page.file.abs_src_path}' " + f"n'a pas de page correspondante : {author_slug}" ) continue - author_block += f'### [{author}](../../team/{sluggy(author)}.md "Voir la page complète de l\'auteur·ice avec la liste de ses articles")\n\n--8<-- "content/team/{sluggy(author)}.md:author-sign-block"\n\n' - - # -- Ajoute la page à la liste des articles dans la page auteur - articles_headers = "" - if dico_contributors.get(sluggy(author)) == 0: - articles_headers = "\n\n## Liste de mes articles\n" - dico_contributors[sluggy(author)] = ( - dico_contributors.get(sluggy(author)) + 1 - ) + author_block += f'### [{author}](../../team/{author_slug}.md "Voir la page complète de l\'auteur·ice avec la liste de ses articles")\n\n--8<-- "content/team/{author_slug}.md:author-sign-block"\n\n' - # date - item_date = format_date( - date=page.meta.get("date"), format="long", locale="fr_FR" - ) + if author_slug in authors_with_existing_autolist: + # liste autogénérée déjà présente dans le fichier, probablement via + # un précédent build (rebuild) + dico_contributors[author_slug] = ( + dico_contributors.get(author_slug) + 1 + ) + logger.debug( + log_prefix + + f"[G006] La liste des articles existe déjà pour '{author_slug}'." + ) + else: + + # -- Ajoute la page à la liste des articles dans la page auteur + articles_headers = "" + + if dico_contributors.get(author_slug) == 0: + # intère une balise pour éviter de dupliquer cette section quand + # plusieurs builds sont successivement lancés + articles_headers += f"\n{AUTHOR_ARTICLES_AUTOLIST_START}" + articles_headers += "\n## Liste de mes articles\n" - # icône - item_icon = "" - if page.meta.get("icon"): - item_icon = f" :{page.meta.get('icon').replace('/', '-')}:" - - # hyperlink data - list_item_link_data = "" - if ( - page.meta.get("description") - and page.meta.get("description") != page.title - ): - list_item_link_data += escape( - page.meta.get("description"), quote=True + dico_contributors[author_slug] = ( + dico_contributors.get(author_slug) + 1 ) - if page.meta.get("tags"): + + # date + item_date = format_date( + date=page.meta.get("date"), format="long", locale="fr_FR" + ) + + # icône + item_icon = "" + if page.meta.get("icon"): + item_icon = f" :{page.meta.get('icon').replace('/', '-')}:" + + # hyperlink data + list_item_link_data = "" if ( page.meta.get("description") and page.meta.get("description") != page.title ): - list_item_link_data += "

" - list_item_link_data += ( - "Mots-clés : " - f"{escape(', ', quote=True).join(page.meta.get('tags'))}" - ) - - with Path(f"content/team/{sluggy(author)}.md").open( - "a", encoding="UTF-8" - ) as author_file: - author_file.write(articles_headers) - author_file.write( - f"\n-{item_icon} [{escape(page.title, quote=True)}](../{page.file.src_uri} '{list_item_link_data}') - _publié le {item_date}_" - ) + list_item_link_data += escape( + page.meta.get("description"), quote=True + ) + if page.meta.get("tags"): + if ( + page.meta.get("description") + and page.meta.get("description") != page.title + ): + list_item_link_data += "

" + list_item_link_data += ( + "Mots-clés : " + f"{escape(', ', quote=True).join(page.meta.get('tags'))}" + ) + + with Path(f"content/team/{author_slug}.md").open( + "a", encoding="UTF-8" + ) as author_file: + author_file.write(articles_headers) + author_file.write( + f"\n-{item_icon} [{escape(page.title, quote=True)}](../{page.file.src_uri} '{list_item_link_data}') - _publié le {item_date}_" + ) # on cherche et remplace la balise de bloc de signature en ignorant la casse # (re.I) et en gérant le multi-ligne (re.M) @@ -142,3 +179,31 @@ def on_page_markdown( author_block, markdown, ) + + +def on_post_build(config: MkDocsConfig): + for author_slug, count in dico_contributors.items(): + # auteuricess ayant au moins 1 article ET dont la liste a été + # créée durant ce build. + if count == 0 or author_slug in authors_with_existing_autolist: + continue + + author_file_path = Path(f"content/team/{author_slug}.md") + if not author_file_path.exists(): + continue + + content = author_file_path.read_text(encoding="UTF-8") + + # on ajoute le marqueur de fin que si le marqueur de début + # est présent mais que la fin est absente + if ( + AUTHOR_ARTICLES_AUTOLIST_START in content + and AUTHOR_ARTICLES_AUTOLIST_END not in content + ): + with author_file_path.open("a", encoding="UTF-8") as f: + f.write(f"\n\n{AUTHOR_ARTICLES_AUTOLIST_END}\n") + logger.debug( + log_prefix + + "Balise de fin de liste autogénérée des articles ajoutée à la " + f"page '{author_slug}' ({count} article(s))." + ) diff --git a/hooks/precommit/__init__.py b/hooks/precommit/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hooks/precommit/git_nocommit_author_autolist.py b/hooks/precommit/git_nocommit_author_autolist.py new file mode 100755 index 0000000000..6f2e1608b2 --- /dev/null +++ b/hooks/precommit/git_nocommit_author_autolist.py @@ -0,0 +1,59 @@ +"""Custom git hook to be used with pre-commit to automatically remove author articles +lists from Markdown files before commit.""" + +from __future__ import annotations + +import re +import sys +from pathlib import Path + +regex_pattern = re.compile( + r".*?" + r"", + re.DOTALL, +) + + +def process_file(path: Path) -> bool: + """Parses the given file and removes any block matching the pattern. + Args: + path (Path): file about to be committed + + Returns: + bool: True if the file has been modified, False otherwise + """ + + original: str = path.read_text(encoding="utf-8") + cleaned: str = re.sub(regex_pattern, "", original) + + if cleaned != original: + path.write_text(cleaned, encoding="utf-8") + print( + f"La liste autogénérée d'articles a été retirée de la page de l'auteurice {path}" + ) + return True + + return False + + +def main() -> int: + """Entry point for the git hook. + + Returns: + 0 if no changes were needed, + 1 if files were modified or errors were detected. + """ + changed: bool = False + for filename in sys.argv[1:]: + path = Path(filename) + + if path.exists(): + if process_file(path): + print(f"Stripped autolist block(s) in {filename}") + changed = True + + return 1 if changed else 0 + + +if __name__ == "__main__": + sys.exit(main())