Le MNT de chaque dalle s'étend d'une bande de 100 m remplie avec les
points sol des 8 tuiles voisines (option « Raccord des bords ») : les
rendus à grand noyau (openness, SVF, LRM) deviennent continus d'une
dalle à l'autre, les images restent recadrées sur le kilomètre exact.
Pendant une génération, la carte encadre les dalles du run : orange
pulsant en cours de rendu, rouge en échec — les coins WGS84 sont portés
par /api/status pour toutes les dalles non terminées.
La file de génération trie les dalles du nord au sud et passe à 10
workers GPU.
Trois chantiers liés à la qualité et au coût des rendus :
- Calage vertical des faisceaux : les passes d'une tuile peuvent être biaisées
de quelques cm (±2,5 cm mesurés sur 1000_6882), créant des marches aux
recouvrements. Les offsets par PointSourceId sont mesurés sur les points
sol de la tuile (réf. médiane itérée) et retranchés ≥ 0,5 cm avant
rastérisation, avec sidecar de cache et application au plancher bare-earth.
- Openness décimée ×2 : lancé de rayons sur grille par blocs (max/min) puis
rééchantillonnage bilinéaire — 532 s → 40 s par tuile à 0,2 m sur CPU,
signal archéologique préservé. Réglable --openness-downsample.
- Génération webapp concentrée sur les couches affichées : les défauts
/api/generate, /api/preview et le sélecteur génèrent le panneau complet
(slope, aspect, pos_open) au lieu d'aspect seul.
- 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
- Ajout classification automatique du sol (SMRF/PMF/CSF) avec détection
heuristique (ratio retours uniques > 0.6 → PMF urbain, sinon SMRF)
- Pré-traitement PDAL recommandé avant classification: ELM + outlier
removal (cell=5.0, threshold=2.0 adapté au calcaire rocailleux)
- Options CLI: --ground-classification {auto,smrf,pmf,csf} et
--force-classification pour forcer la reclassification
- Fix double logging (logger.propagate = False)
- Fix --force non transmis dans run.sh (réécriture parsing arguments)
- Fix warning numpy 'partition will ignore mask': conversion MaskedArray
en ndarray avant np.percentile()
- Ajout liblaszip8 + lazrs pour support LAZ dans Docker et laspy
- Tests unitaires pour PMF, CSF et auto-détection
- Suppression de generate_solar (éclairage solaire) des visualisations
- Accélération GPU de hillshade, slope, aspect, curvature, depressions,
anomalies, roughness, texture GLCM, flow (sink filling)
- Nettoyage mémoire GPU entre visualisations (gpu_cleanup)
- Correction OOM texture GLCM: calcul entropie bin par bin au lieu d'un
tableau 3D massif sur GPU
- Correction bug: xp_minimum_filter manquant dans imports visualizations
- Option --file accepte plusieurs noms complets sans extension
- run.sh affiche l'aide si appelé sans arguments
- Option --test pour exécuter les tests unitaires dans Docker
- Filtre ReturnNumber>=1 intégré dans le pipeline PDAL (plus d'erreur SMRF)
- 60 tests unitaires: GPU, visualisations, rendering, DTM, pipeline, CLI
- Ajout pytest au Dockerfile