Lead Magnet · Stack Cloud-Native

⚡ GeoParquet + gpio
La stack qui rend QGIS optionnel

Du "télécharge puis ouvre QGIS" au SQL spatial cloud-native — le guide pratique pour migrer vos workflows GIS en 2026.

⏱ Temps de lecture : 10 min 📊 Niveau : intermédiaire 📅 Mai 2026

Pour qui ? Data engineers, GIS analysts, consultants SIG et toute personne qui passe plus de temps à analyser des snapshots de données qu'à les éditer.

Pré-requis : Savoir ce qu'est un Shapefile. Avoir déjà utilisé QGIS ou ArcGIS. Python et SQL basique appréciés mais pas obligatoires.

🎯 Ce que ce guide vous apporte

  1. Un cheat sheet complet gpio + DuckDB prêt à copier-coller en 6 commandes
  2. 5 étapes numérotées pour migrer n'importe quel dataset en cloud-native
  3. La vérité chiffrée : 60–80 % de réduction de taille, 10× gain sur les requêtes spatiales
  4. Le tableau "quand utiliser quoi" : QGIS / PostGIS / GeoParquet selon le cas

Part 1 — Le Framework

📦 Le problème : 100 % des données lues pour 5 % de la zone

Un cadastre France entière représente environ 8 GB en Shapefile. Pour analyser Paris intra-muros — soit 0,2 % du territoire national — QGIS télécharge intégralement ces 8 GB avant d'afficher quoi que ce soit.

Ce n'est pas un bug ni un problème de machine. C'est une conséquence du format. Les formats géospatiaux classiques (Shapefile, GeoJSON, GeoPackage) sont séquentiels : ils ne savent pas "lire seulement la partie qui concerne l'Île-de-France". C'est tout ou rien.

📊 Le problème en chiffres

Opération Workflow classique Cloud-native
Accès cadastre France entière 8 GB à télécharger, ~8 min Requête directe, ~4 sec
Analyse sur 5 % du territoire Lit 100 % du fichier Lit ~5 % du fichier
Taille après optimisation 8 GB (Shapefile) ~1,4 GB (GeoParquet + ZSTD)
Partage avec un collègue .zip par email ou Wetransfer URL S3 + script DuckDB
Mise à jour du dataset Re-télécharger tout Remplacer la partition concernée
Stockage local requis 10–50 GB pour quelques datasets 0 (ou cache temporaire)

❌ Les 3 erreurs que tout le monde fait

Erreur #1 : Convertir en GeoParquet sans optimisation

Exporter "brut" depuis QGIS ou GDAL génère un GeoParquet non ordonné. Sans Hilbert sorting ni bbox columns, les performances cloud sont identiques à un GeoJSON — le fichier est parcouru en entier à chaque requête. C'est de là que vient le "j'ai essayé GeoParquet, ça ne change rien".

Erreur #2 : Utiliser GeoParquet pour des données transactionnelles

GeoParquet est un format analytique conçu pour les snapshots. Si vos données subissent des UPDATE granulaires quotidiens — mise à jour d'adresses, édition de tracés terrain — PostGIS reste le bon choix. Confondre les deux use cases garantit la déception.

Erreur #3 : Abandonner QGIS complètement

QGIS reste irremplaçable pour la cartographie exploratoire, l'édition manuelle de géométries et les livrables visuels PDF/print. La stack cloud-native ne le remplace pas — elle le rend optionnel pour les 70 % de cas qui relèvent de l'analytique pure.

🔄 Le changement de paradigme

Avant — Outil centrique

La donnée vit dans un fichier local.
Le logiciel SIG est le centre de gravité.

Workflow : télécharger → ouvrir → analyser → exporter

Après — Donnée centrique

La donnée vit dans le cloud.
Le SQL est le centre de gravité.

Workflow : interroger → filtrer → visualiser

💡 Insight clé
GeoParquet + Hilbert ordering, c'est une bibliothèque dont on ne lit que les pages qui nous intéressent. Le tri physique des données dans l'espace rend la lecture partielle possible — et dix fois plus rapide.


Part 2 — La Méthode

🛠️ Process pas-à-pas : du Shapefile au cloud-native

Cinq étapes, deux outils (gpio et duckdb). Chaque étape peut être utilisée indépendamment selon votre contexte.

Étape 0 — Installation (2 minutes)

pip install geoparquet-io duckdb

# Vérifier les installations
gpio --version
duckdb --version

Étape 1 — Inspecter n'importe quel GeoParquet sans télécharger

# Fichier local
gpio inspect mon_fichier.parquet

# Fichier distant — aucun téléchargement, lecture des métadonnées seulement
gpio inspect https://cadastre.data.gouv.fr/data/etalab-cadastre/latest/geoparquet/france/cadastre.parquet

# Résultat : CRS, nombre de features, bbox, compression, colonnes disponibles

Étape 2 — Convertir vos données existantes

# Depuis Shapefile
gpio convert input.shp output.parquet

# Depuis GeoJSON
gpio convert input.geojson output.parquet

# Depuis GeoPackage
gpio convert input.gpkg output.parquet

Étape 3 — Optimiser (étape critique — ne pas sauter)

# Optimisation complète : Hilbert + bbox + ZSTD
gpio optimize output.parquet \
  --spatial-sort hilbert \
  --add-bbox \
  --compression zstd

# En une seule commande : conversion + optimisation
gpio convert input.shp output.parquet \
  --spatial-sort hilbert \
  --add-bbox \
  --compression zstd

💡 Pourquoi --add-bbox ?
DuckDB peut filtrer sur les colonnes bbox.minx / bbox.maxx / bbox.miny / bbox.maxy avant même de toucher à la géométrie. C'est ce qui divise le temps de requête par 10 sur les gros datasets cloud — sans cette option, vous ne bénéficiez que de la compression, pas de la lecture partielle.

Étape 4 — Partitionner pour les gros datasets (> 500 MB)

# Partitionnement par admin boundary (France : level 4 = département)
gpio partition output.parquet \
  --by admin \
  --admin-level 4 \
  --output-dir ./by_dept/

# Partitionnement par H3 (résolution 5 ≈ hexagones de 250 km²)
gpio partition output.parquet \
  --by h3 \
  --resolution 5 \
  --output-dir ./h3_partitions/

Étape 5 — Requêter sans télécharger (DuckDB Spatial)

-- Charger l'extension spatiale
LOAD spatial;

-- Requête directe sur S3 — zéro téléchargement local
SELECT * FROM read_parquet('https://cadastre.data.gouv.fr/data/etalab-cadastre/latest/geoparquet/france/cadastre.parquet')

WHERE departement like '91' AND commune like '91477'

Ou avec une bbox

WHERE bbox.minx >= 511150 AND bbox.maxx <= 660000
  AND bbox.miny >= 6333210 AND bbox.maxy <= 6430000;


-- Agréger par département sur données partitionnées
SELECT dept_code, COUNT(*) AS nb_parcelles
FROM read_parquet('s3://mon-bucket/by_dept/*.parquet')
GROUP BY dept_code
ORDER BY nb_parcelles DESC;

-- Join spatial avec une autre table
SELECT a.id, b.nom_commune
FROM read_parquet('parcels.parquet') a
JOIN read_parquet('communes.parquet') b
  ON ST_Within(a.geometry, b.geometry);

📋 Tableau avant/après

Workflow Classique (Shapefile + QGIS) Cloud-native (GeoParquet + DuckDB)
Outil central QGIS / ArcGIS DuckDB + SQL
Format source .shp, .geojson, .gpkg .parquet (Hilbert-sorted)
Lieu de la donnée Disque local S3 / GCS / Azure Blob
Lecture pour une zone cible 100 % du fichier 5–10 % (si Hilbert)
Partage des données Compression + envoi URL S3 partagée
Reproductibilité "Ouvre ce fichier dans QGIS" Script SQL versionnable (git)
Coût d'entrée 0 € (open source) 0 € (gpio + DuckDB open source)

Part 3 — L'Outil

🧰 La stack 2026 recommandée

gpio  (conversion / optimisation Hilbert)
S3 / GCS / Azure Blob  (stockage cloud)
DuckDB Spatial  (requêtes SQL analytiques)
Felt / Kepler.gl / DeckGL  (visualisation, rendu GeoParquet natif)
CoucheOutilPourquoi
Conversion / optimisation gpio (Cloud Native Geo, mars 2026) Hilbert + bbox + ZSTD en une commande, open source
Stockage GeoParquet sur S3/Azure Cloud-native, partitionnable, lecture partielle
Query engine DuckDB Spatial Lit S3 en SQL, R-tree natif, zéro infrastructure
Partitionnement H3 (Uber) ou admin boundaries Découpages stables, indépendants de tout vendor
Visualisation Felt / Kepler.gl / DeckGL Rendu GeoParquet natif, sans serveur de tuiles

📋 Cheat sheet — 6 commandes à garder sous la main

# 1. Inspecter un fichier distant (0 téléchargement)
gpio inspect https://data.source.com/file.parquet

# 2. Conversion + optimisation complète (tout en une commande)
gpio convert input.shp output.parquet \
  --spatial-sort hilbert --add-bbox --compression zstd

# 3. Statistiques du fichier résultant
gpio stats output.parquet

# 4. Partitionnement par département (France : admin level 4)
gpio partition output.parquet \
  --by admin --admin-level 4 --output-dir ./by_dept/

# 5. Requête DuckDB depuis S3 (adapter les coordonnées bbox)
duckdb -c "LOAD spatial; \
  SELECT COUNT(*) FROM read_parquet('s3://bucket/data.parquet') \
  WHERE bbox.minx > 2.2 AND bbox.maxx < 2.5 \
  AND bbox.miny > 48.8 AND bbox.maxy < 49.1;"

# 6. Partitionnement par H3 résolution 5
gpio partition output.parquet \
  --by h3 --resolution 5 --output-dir ./h3_r5/

🗂️ Quand utiliser quoi

Cas d'usageOutil recommandéPourquoi
Snapshot analytique cloud GeoParquet + gpio + DuckDB Lecture partielle, SQL versionnable, 0 € infra
Données transactionnelles (UPDATE quotidien) PostGIS ACID, granularité, écosystème étendu (pgRouting…)
Cartographie exploratoire visuelle QGIS IHM, sémiologie graphique, exports PDF/print
Données > 100 GB, équipe multi-users Snowflake / BigQuery Spatial Scalabilité, gouvernance, concurrence
Partage avec non-techniciens Felt (sur warehouse) Pas de setup client, interface carte intuitive
R&D, prototypage rapide local DuckDB en local Zéro infrastructure, résultat en secondes

📜 Les 3 règles d'or

Règle 1. Si vous écrivez des UPDATE tous les jours, restez sur PostGIS. Si vous faites des snapshots hebdomadaires ou mensuels, GeoParquet + DuckDB vous fera gagner 80 % du temps de setup.
Règle 2. Un GeoParquet sans Hilbert ordering est un format, pas une optimisation. Ne sautez jamais l'étape --spatial-sort hilbert --add-bbox — c'est elle qui change tout.
Règle 3. QGIS et GeoParquet ne sont pas des concurrents. L'un édite et visualise ; l'autre stocke et requête à distance. Choisissez selon ce que vous faites, pas selon ce que vous avez l'habitude d'utiliser.