Add web map with zone generation API, side job queue, and restore historical DTM hole rendering
- webapp.py: FastAPI serving the continuous map (port 8973) with /api/preview, /api/generate and /api/status; tiles are downloaded from IGN and processed in a logged subprocess, tracked live in a side "File de génération" panel that survives page reloads - fetch_ign.py: download missing 1 km LiDAR HD tiles from the IGN geoplateforme before processing - index.py: tile thumbnails and 500 m subtiles are now invalidated by mtime so regenerating a tile refreshes its cached images; progress logging per tile - dtm.py: back to the historical gap handling (small gaps filled by fillnodata only, larger holes left as nodata rendered black); lowest-return floor only via --bare-earth, IGN class selection via --ign-classes - cli.py: positional input now optional (--rebuild-index works alone) - docker-compose.yml: serve (GPU, port 8973) and process services; launch via docker compose only (documented in AGENTS.md/AGENTS.md) - tests: 131 passing, incl. regressions for thumbnail staleness, --rebuild-index without input, and nodata rendering
This commit is contained in:
141
docs/GROUND_CLASSIFICATION.md
Normal file
141
docs/GROUND_CLASSIFICATION.md
Normal file
@ -0,0 +1,141 @@
|
||||
# Classification du sol — options et références
|
||||
|
||||
Note de synthèse pour choisir/améliorer l'algorithme de détection du sol.
|
||||
Contexte : tiles LiDAR HD IGN (Lambert 93), zones de relief fort / rochers /
|
||||
forêt dense où le sol est sous-classifié et le MNT présente de grands trous.
|
||||
|
||||
Tile de référence : `LHD_FXX_0999_6778_PTS_LAMB93_IGN69`
|
||||
- 65 047 919 points, ~1 km², résolutions 0.5 m et 0.2 m.
|
||||
- Répartition classes (pré-classification fournisseur) :
|
||||
classe 2 (sol) **25.79 %**, classe 5 (veg haute) **63.2 %**,
|
||||
classe 3 (veg basse) 7.85 %, classe 4 (veg moyenne) 2.66 %,
|
||||
classe 1 0.47 %, classe 6 0.01 %. Aucun point en classe 0.
|
||||
- Trous dans le MNT existant (avant correction) : **43.5 %** à 0.5 m,
|
||||
**44.1 %** à 0.2 m (surface du tile, bornes du header).
|
||||
|
||||
## Benchmark mesuré (PDAL, 1 km²)
|
||||
|
||||
| Méthode | Temps | Points sol | Surface sol* | Trous* |
|
||||
|---|---|---|---|---|
|
||||
| **IGN** (pré-classif.) | **9.4 s** | 25.8 % | 84.6 % | 15.4 % |
|
||||
| **SMRF** | 326.3 s | 36.1 % | 90.4 % | 9.6 % |
|
||||
| **CSF** | 355.2 s | 17.6 % | 46.9 % | 53.1 % |
|
||||
|
||||
\* « Surface sol » calculée sur l'emprise des points (bounding box du nuage),
|
||||
à 0.5 m. Les % de trous du MNT final (bornes du header, plus grandes) sont
|
||||
supérieurs : voir le tile de référence ci-dessus.
|
||||
|
||||
## A. Filtres géométriques (stack PDAL actuelle)
|
||||
|
||||
- **IGN** (pré-classification fournisseur, classe 2) : le plus rapide (~9 s).
|
||||
Fiable là où le fournisseur a confiance ; trous sous forêt dense / relief.
|
||||
Aucun paramètre à régler.
|
||||
- **SMRF** — Pingel, Clarke & McBride 2013, *ISPRS J. Photogramm. Remote
|
||||
Sens.* 77:21-30. Filtre **raster** (opère sur un DSM, pas sur les points),
|
||||
donc plus rapide que les filtres point-based ; **minimise les erreurs de
|
||||
type I** (omission de sol) → bien adapté quand le sol est rare (forêt).
|
||||
Meilleure couverture des trois ici (90.4 %) mais ~5.4 min/tile.
|
||||
- **CSF** — Zhang et al. 2016, *Remote Sensing* 8(6):501. Toile inversée
|
||||
drapée sur le nuage ; simple, précis, mais **la toile ne touche plus le sol
|
||||
en terrain raide/vallonné** → mauvaise classification. Le plus lent ici et
|
||||
le pire sur ce tile. À réserver aux zones urbaines.
|
||||
- **PTD/PTIN** (Progressive TIN Densification) — Axelsson 2000, ISPRS
|
||||
Congress. **Gagnant de la littérature** : le plus robuste sur terrain
|
||||
complexe + forêt (Moudrý et al. 2020, *Measurement* 150:107047 ; Cai et al.
|
||||
2019, *Remote Sensing* 11(9):1037) et le plus rapide (benchmark lidR :
|
||||
PTD ~20 s vs CSF ~156 s vs PMF ~1800 s). **NON disponible dans la version
|
||||
PDAL de cette image** (`filters.ground` / TIN absents) — à ajouter pour
|
||||
l'utiliser (ou via lidR / une implémentation maison).
|
||||
|
||||
## B. Hybride rapide (choisi pour implémentation)
|
||||
|
||||
Principe **PTD / Wack & Wimmer** (Wack & Wimmer 2002, *ISPRS Archives*
|
||||
XXXIV/3A:293-296 : MNT par retour le plus bas, en excluant le 1 % le plus bas
|
||||
par cellule pour écarter les outliers) :
|
||||
|
||||
1. **Base = pré-classification IGN** (classe 2, ~9 s, fiable et officielle).
|
||||
2. **Comblement mesuré des trous** : pour chaque cellule sans point sol,
|
||||
prendre le **retour le plus bas robuste** (min du 99 % des points de la
|
||||
cellule) → ajoute du sol *mesuré* là où le fournisseur a échoué
|
||||
(rochers, clairières, sol forestier).
|
||||
3. **Inpainting topographique** des derniers vides (interpolation
|
||||
terrain-aware déjà implémentée dans `dtm.py:_interpolate_holes`).
|
||||
|
||||
Attendu : MNT **continu** (0 % de trous), robuste en forêt/relief,
|
||||
**~10-15 s/tile** au lieu de 326-355 s. Aucune dépendance GPU, aucun
|
||||
entraînement.
|
||||
|
||||
## C. Modèles IA / ML (supervisés — nécessitent des labels)
|
||||
|
||||
Avertissement (Qin et al. 2023, *ISPRS J. Photogramm. Remote Sens.*
|
||||
202:246-261) : **tout est supervisé** ; le principal risque est la
|
||||
**généralisation** — un modèle entraîné sur une région dégrade ailleurs.
|
||||
Aucun filtre DL entièrement non-supervisé publié à date.
|
||||
|
||||
**Basés sur les points (3D) :**
|
||||
|
||||
| Modèle | Année | Archi | Précision | Vitesse (~/km², GPU) |
|
||||
|---|---|---|---|---|
|
||||
| KPConv / RandLA-Net (Qin, OpenGF) | 2021 | KPConv / RandLA-Net | 97.8 % OA, RMSE DTM 0.20 m, IoU sol 95 % | 0.5-2.5 min |
|
||||
| PFCN (Jin, *IEEE JSTARS* 13:3958) | 2020 | point-FCN | Te 1.73 %, Kappa 93.9 % | ~1/3 du coût PointNet++ |
|
||||
| Terrain-Net (Li, *Remote Sensing* 14(22):5798) | 2022 | KPConv + self-attention | OA 98 %, mIoU 0.933 | param-free au transfert |
|
||||
| MSVC (Štroner, *Remote Sensing* 17(4):615) | 2025 | DNN voxel 9x9x9 | bat CSF en F-score | — |
|
||||
|
||||
**Rasterisés (sortent directement le MNT — le plus proche du besoin) :**
|
||||
|
||||
| Modèle | Année | Archi | Résultat |
|
||||
|---|---|---|---|
|
||||
| Precursor (Rizaldy, *ISPRS Annals* IV-2:231) | 2018 | 2D FCN | Te 5.22 %, 78x plus rapide |
|
||||
| DeepTerRa / ALS2DTM (Lê, *IEEE JSTARS* 15:2778) | 2022 | GAN pix2pix (U-Net) | RMSE MNT < 1 m, filtre + interp en 1 passe |
|
||||
| DSM2DTM (Bittner, *ISPRS Annals* X-1/W1-2023:925) | 2023 | U-Net (EfficientNet) | masque non-sol + hauteur sol/pixel |
|
||||
|
||||
**Jeu de données d'entraînement** : OpenGF (Qin et al., CVPRW 2021,
|
||||
arXiv:2101.09641 — 47.7 km², 542 M pts) ; ALS2DTM (Lê et al. 2022,
|
||||
arXiv:2206.03778 — 52 km², 1.66 Md pts, urbain/forêt/montagne).
|
||||
|
||||
**Coûts / obstacles pour notre cas** : (1) labels → à générer en
|
||||
pseudo-labels (sortie SMRF/PTD haute qualité sur un échantillon représentatif
|
||||
de nos tiles) ou pré-entraînement OpenGF/ALS2DTM ; (2) généralisation sur le
|
||||
terrain divers de LiDAR HD (plaine/forêt/montagne/urbain) ; (3) infra :
|
||||
checkpoint + chemin d'inférence GPU dans l'image Docker.
|
||||
|
||||
**Meilleur fit si on part sur l'IA** : un **U-Net rasterisé (style
|
||||
DSM2DTM)** — rasteriser le nuage en grilles multi-canaux (altitude, pente,
|
||||
courbure, densité, stats de retours), sortir masque sol + hauteur sol.
|
||||
2D = très rapide et trivial à déployer sur GPU, fusionne filtrage +
|
||||
interpolation. Le KPConv/RandLA-Net est plus précis en 3D pur mais plus lourd
|
||||
à déployer.
|
||||
|
||||
## Synthèse / décision
|
||||
|
||||
- « Rapide » contrainte dure + faible maintenance → **hybride (B)**
|
||||
(~10-40 s/tile, zéro entraînement, zéro GPU). ← **choix retenu, IMPLÉMENTÉ**
|
||||
- Base = pré-classification IGN (rapide, ~10 s). `auto` la préfère dès que
|
||||
≥ 20 % des points sont classés sol (seuil abaissé de 30 % à 20 %, car le
|
||||
MNT est ensuite complété — voir ci-dessous).
|
||||
- Le MNT est **toujours** complété dans `create_dtm_fast` : comblement par le
|
||||
**retour le plus bas par cellule** (`_min_return_grid`, Wack & Wimmer 2002)
|
||||
pour les trous, puis **interpolation terrain-aware** (`_interpolate_holes`).
|
||||
Résultat : MNT continu (0 % de trous) pour n'importe quelle base.
|
||||
- Vérifié sur le tile 0999_6778 : base CSF + comblement → 1,9 M trous
|
||||
comblés par retour le plus bas, 5,3 % interpolés, MNT 0 % de trous.
|
||||
- Qualité max dans les cas durs (raide + dense), ~1-2 min/tile + GPU +
|
||||
entraînement acceptés → **U-Net rasterisé (C)**. (non implémenté)
|
||||
- Meilleur filtre géométrique disponible dans PDAL → **SMRF (A)** (meilleure
|
||||
couverture 90.4 % mais 5.4 min/tile). Sélectionnable via `--ground-classification smrf`.
|
||||
- « Gagnant » absolu de la littérature (rapide + robuste) → **PTD/PTIN
|
||||
(A)** : à intégrer (pas dans la stack PDAL actuelle).
|
||||
|
||||
## Références
|
||||
|
||||
- Axelsson (2000), PTIN/PTD, ISPRS Congress.
|
||||
- Pingel, Clarke & McBride (2013), SMRF, ISPRS J. P&RS 77:21-30.
|
||||
- Zhang et al. (2016), CSF, Remote Sensing 8(6):501.
|
||||
- Wack & Wimmer (2002), DMT par retour le plus bas, ISPRS Archives XXXIV/3A.
|
||||
- Moudrý et al. (2020), comparaison CSF/PTIN/PMF/SMRF, Measurement 150:107047.
|
||||
- Cai et al. (2019), CS+PTD, Remote Sensing 11(9):1037.
|
||||
- Qin et al. (2021), OpenGF, CVPR Workshops (arXiv:2101.09641).
|
||||
- Qin et al. (2023), dataset + evaluation + survey, ISPRS J. P&RS 202:246-261.
|
||||
- Lê et al. (2022), DeepTerRa/ALS2DTM, IEEE JSTARS 15:2778 (arXiv:2206.03778).
|
||||
- Bittner et al. (2023), DSM2DTM, ISPRS Annals X-1/W1-2023:925.
|
||||
- lidR book (comparaison PTD/CSF/PMF) : https://r-lidar.github.io/lidRbook/gnd.html
|
||||
Reference in New Issue
Block a user