L'ancienne carte n'est pas une carte à tuiles : une div Leaflet par dalle,
rotée en CSS pour coller la grille Lambert 93 sur le Web Mercator, trois
paliers d'images choisis à la main, un plafond d'images pleine résolution et
une mosaïque d'overview pour boucher les trous au dézoom. Des centaines de
nœuds DOM, des AVIF de 2500² à 5000² décodés dans le navigateur, un LOD
maison — et rien de réutilisable hors de cette page.
Nouvelle image légère (Pillow + pyproj, ni GDAL ni PDAL, port 8975) servant
une pyramide XYZ EPSG:3857 au schéma OpenStreetMap, rendue à la demande
depuis les dalles et mise en cache dans output/index_xyz/ :
- tiles.py : grille XYZ, reprojection par transformation projective dalle par
dalle (calage mesuré < 1 px), choix du palier source parmi ceux que le
pipeline produit déjà (vignette, intermédiaire, quadrant, dalle), cache
périmé dès qu'une dalle contributrice est plus récente, marqueur .empty
pour les zones sans donnée, cache d'images sources à budget mémoire ;
- mapserve.py : /tiles/{couche}/{z}/{x}/{y}.png (256 px canonique) et
@2x.webp (512 px, interface), TileJSON, WMTS, josm.imagery.xml, CORS —
les rendus deviennent un fond d'imagerie pour JOSM, iD, QGIS, uMap ;
- mapui.py : une L.tileLayer par couche dans un pane isolé — LOD, cache et
animation natifs de Leaflet ; pile réordonnable (glisser avec barre
d'insertion, ou boutons ▲▼ au doigt), modes de fusion CSS par couche,
configuration figeable comme défaut de tous les navigateurs.
Deux amonts pour les déploiements en deux machines : LIDAR_SOURCE_URL
(webapp du pipeline — inventaire complet, dalles rapatriées à la demande) et
LIDAR_MAPS_URL (autre instance carte). Charge bornée et réglable, taillée
par défaut pour une petite machine : 2 rendus et 2 téléchargements
simultanés, 192 Mo de cache de sources.
Mesuré sur 849 dalles réelles : première tuile d'une zone 0,9–3,2 s
(téléchargement compris), ~1 ms ensuite ; un chemin OSM se superpose
exactement à la trace du rendu de pente, et les coutures entre tuiles
restent sous le bruit naturel du terrain.
L'interface historique (port 8973) n'est pas touchée : génération et export
y restent, les deux cartes coexistent.
Pipeline LiDAR Archéologique
Workflow automatisé pour générer des visualisations exploitables à partir de données LiDAR HD (IGN) pour la détection de structures archéologiques. Tourne en Docker avec accélération GPU optionnelle (NVIDIA/CuPy).
Visualisations (18 par fichier)
Visualisations principales
| # | Visualisation | Utilité archéologique |
|---|---|---|
| 1 | Hillshade multidirectionnel | Murs, terrasses, structures linéaires, routes |
| 2 | Pente (Slope) | Murs de soutènement, talus, changements brusques |
| 3 | Aspect (Orientation) | Direction des pentes, exposition |
| 4 | Courbure (Curvature) | Fossés, terrasses, talus, concavité/convexité |
| 5 | Sky-View Factor | Structures, tumulus, fondations (ray-tracing 16 azimuts) |
| 6 | Local Relief Model | Micro-reliefs, fossés, levées de terrain |
| 7 | Positive Openness | Élévations, tumulus, bâtiments (ray-tracing 8 directions) |
| 8 | Negative Openness | Cavités, fossés, souterrains (ray-tracing 8 directions) |
Visualisations avancées
| # | Visualisation | Description | Détection |
|---|---|---|---|
| 9 | MSRM | Multi-Scale Relief Model (sigma 5/10/25/50/100m) | Tumulus, fossés, murs à toutes les échelles |
| 10 | TPI multi-échelle | Topographic Position Index (5m + 100m) | Crêtes, vallées, plateformes |
| 11 | Dépressions | Remplissage cuvettes + différence | Dolines, sinkholes, zones inondables |
| 12 | SAILORE | LRM adaptatif (noyau = f(pente)) | Terrain hétérogène, tout relief |
| 13 | Rugosité | Écart-type de l'élévation | Surfaces anthropiques vs naturelles |
| 14 | Anomalies statistiques | Z-score + Local Moran's I | Anomalies topographiques significatives |
| 15 | Ondelette Mexican Hat | CWT 2D multi-échelle | Tumulus, fossés circulaires |
| 16 | Accumulation de flux | Algorithme D8 hydrologique | Fossés d'enceinte, routes antiques |
Cartes de référence IGN
| # | Visualisation | Source |
|---|---|---|
| 17 | Photographie aérienne IGN | Orthophotographie WMTS |
| 18 | Carte topographique IGN | Plan IGN V2 WMTS |
Classification du sol
Le pipeline classifie automatiquement les points sol à partir du nuage de points bruit. Le pré-traitement suit le workflow recommandé par PDAL :
- Filtre ReturnNumber — élimine les points avec numéros de retour invalides
- Réinitialisation Classification — remet toutes les classifications à 0
- ELM (Extended Local Minimum) — marque les points bas aberrants comme bruit (Classification=7)
- Outlier statistique — supprime les points isolés (mean_k=8, multiplier=3.0)
- Classification sol — SMRF, PMF ou CSF
- Extraction — ne conserve que les points Classification=2
Méthodes de classification
| Méthode | Mode | Usage | Vitesse |
|---|---|---|---|
| SMRF | Auto (défaut) | Terrain naturel, forêt, rocaille | Rapide |
| PMF | Auto (si urbain) | Zones urbaines, bâtiments, routes | Rapide |
| CSF | Manuel uniquement | Terrain très complexe, falaises | Lent |
L'auto-détection analyse le ratio de retours uniques du nuage de points : ratio > 0.6 = milieu urbain → PMF, sinon → SMRF.
Pré-traitement ELM (terrain calcaire)
Les paramètres ELM sont adaptés au terrain calcaire rocailleux avec végétation basse :
cell=5.0m— résolution fine pour capturer le relief rocheuxthreshold=2.0m— seuil élevé pour ne pas marquer les affleurements comme bruit
Architecture modulaire
lidar_pipeline/
├── __init__.py # Exports publics
├── __main__.py # Point d'entrée: python -m lidar_pipeline
├── cli.py # argparse + logging + main()
├── gpu.py # CuPy/numpy abstraction (HAS_GPU, to_gpu, to_cpu, xp_*)
├── dtm.py # Classification PDAL (SMRF/PMF/CSF + auto) + génération DTM
├── visualizations.py # Fonctions generate_* (19 visualisations)
├── ign.py # Téléchargement tuiles IGN + overlay
├── rendering.py # Colormaps, tif_to_png, rapport PDF
├── pipeline.py # LidarArchaeoPipeline (orchestration + registry)
└── tests/ # Tests unitaires (pytest)
Ajouter une visualisation = 1 fonction + 1 entrée dans VIZ_STEPS + 1 entrée dans COLORMAPS.
Installation Docker
cd /votre/dossier/lidar
mkdir -p input
# Copiez vos fichiers .laz dans input/
cp /chemin/vos/fichiers/*.laz input/
# Build l'image Docker
docker build -t lidar-lidar .
Utilisation
Traitement complet avec GPU (recommandé)
./run.sh -g
Traitement standard (CPU seul)
./run.sh
Options du script run.sh
./run.sh [options]
-r RESOLUTION Résolution en m/px (défaut: 0.5)
-w WORKERS Nombre de workers parallèles (défaut: 1)
-g Activer l'accélération GPU NVIDIA
-v Mode verbeux (timestamps + niveaux)
--debug Mode debug (détails internes fichier:ligne)
-f / --force Régénérer tous les fichiers même si les WebP existent
--force-classification Reclassifier le sol même si le fichier .las existe déjà
--ground-classification Méthode de classification: auto, smrf, pmf, csf (défaut: auto)
--file NOM... Traiter un ou plusieurs fichiers LAZ spécifiques
--test Exécuter les tests unitaires
-h Afficher l'aide
Exemples
# Traitement standard avec GPU
./run.sh -g
# GPU + mode verbeux
./run.sh -g -v
# GPU + 4 workers parallèles
./run.sh -g -w 4
# Haute résolution (0.2m/px)
./run.sh -g -r 0.2
# Forcer la régénération de tous les fichiers
./run.sh -g --force
# Reclassifier le sol seulement (sans régénérer les visualisations)
./run.sh -g --force-classification
# Forcer la classification PMF au lieu de l'auto-détection
./run.sh -g --ground-classification pmf
# Forcer la classification CSF (lent mais robuste sur terrain complexe)
./run.sh -g --ground-classification csf
# Traiter un fichier spécifique (test rapide)
./run.sh -g --file LHD_FXX_1000_6882_PTS_LAMB93_IGN69.copc
# Traiter deux fichiers spécifiques
./run.sh -g --file LHD_FXX_1000_6881_PTS_LAMB93_IGN69.copc LHD_FXX_1000_6882_PTS_LAMB93_IGN69.copc
# Exécuter les tests unitaires
./run.sh --test
Utilisation directe Docker
# Traitement standard
docker run --rm -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output lidar-lidar
# Avec GPU + classification forcée
docker run --rm --gpus all -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output \
lidar-lidar python3 -m lidar_pipeline /data/input -o /data/output \
--ground-classification pmf
# Forcer la reclassification du sol
docker run --rm --gpus all -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output \
lidar-lidar python3 -m lidar_pipeline /data/input -o /data/output \
--force-classification
# Mode verbeux
docker run --rm --gpus all -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output \
lidar-lidar python3 -m lidar_pipeline /data/input -o /data/output -v
Structure des dossiers
.
├── input/ # Fichiers .laz (monté en read-only dans Docker)
├── output/ # Résultats générés
│ ├── DTM/ # Modèles numériques de terrain (GeoTIFF)
│ ├── temp/ # Fichiers temporaires (classification .las)
│ ├── visualisations/ # Images WebP par fichier LAZ
│ │ ├── fichier_6881/ # Un sous-dossier par fichier LAZ
│ │ │ ├── ..._hillshade_multi.webp
│ │ │ ├── ..._svf.webp
│ │ │ ├── ..._mslrm.webp
│ │ │ └── ... (19 visualisations)
│ │ └── fichier_6882/
│ │ └── ...
│ └── rapports/ # Rapports PDF A3 par fichier
│ ├── fichier_6881_rapport.pdf
│ └── fichier_6882_rapport.pdf
├── lidar_pipeline/ # Package Python modulaire
│ ├── cli.py # Arguments CLI + logging
│ ├── gpu.py # Abstraction CuPy/numpy
│ ├── dtm.py # Classification sol + DTM
│ ├── visualizations.py # 19 fonctions generate_*
│ ├── ign.py # Tuiles IGN
│ ├── rendering.py # Colormaps, WebP, PDF
│ ├── pipeline.py # Orchestration
│ └── tests/ # Tests unitaires
├── process_lidar.py # Point d'entrée compatible
├── Dockerfile
├── run.sh
└── README.md
Paramètres
| Paramètre | Option | Défaut | Description |
|---|---|---|---|
| Résolution | -r |
0.5 | Résolution en mètres par pixel |
| Workers | -w |
1 | Nombre de CPU pour traitement parallèle |
| GPU | -g |
off | Activer l'accélération NVIDIA GPU |
| Classification sol | --ground-classification |
auto | Méthode : auto, smrf, pmf, csf |
| Forcer classification | --force-classification |
off | Reclassifier le sol même si .las existe |
| Output | -o |
/data/output | Dossier de sortie |
| Force | -f/--force |
off | Régénérer même si les WebP existent |
| File | --file |
tous | Traiter un ou plusieurs fichiers LAZ |
| Verbose | -v |
off | Mode verbeux (timestamps + niveaux) |
| Debug | --debug |
off | Mode debug (détails internes) |
Résolution recommandée
0.2— Très fine, bâtiments individuels (lent)0.5— Recommandée archéologie (équilibre vitesse/détail)1.0— Rapide, grandes structures uniquement
Interprétation archéologique
Pour détecter les cavités et souterrains
- Negative Openness — Zones sombres = creux profonds
- Dépressions — Carte spécifique des dolines et sinkholes
- Local Relief Model — Zones bleues = dépressions
- Hillshade — Ombres inhabituelles en forme de trous
Pour détecter structures et bâtiments anciens
- MSRM — Détection multi-échelle de tous les reliefs
- Sky-View Factor — Structures géométriques claires
- SAILORE — LRM adaptatif pour terrain hétérogène
- Anomalies statistiques — Anomalies topographiques significatives
Pour hydrologie et fossés
- Accumulation de flux — Fossés d'enceinte, routes antiques
- Dépressions — Zones de collecte d'eau, dolines
- Negative Openness — Fossés et tranchées
Tests
./run.sh --test
Les tests tournent dans le conteneur Docker et couvrent la classification du sol (SMRF/PMF/CSF), l'auto-détection, le rendu, et les visualisations.
Dépannage
# Vérifier Docker
docker --version
# Shell dans le conteneur
docker run --rm -it -v $(pwd)/input:/data/input -v $(pwd)/output:/data/output \
--entrypoint bash lidar-lidar
# Reconstruire l'image
docker build --no-cache -t lidar-lidar .
# Nettoyer
docker system prune -a
Erreur mémoire
Augmenter la mémoire Docker à 16Go+ pour les gros fichiers LiDAR HD.
Données LiDAR HD (IGN)
Les fichiers COPC (.laz) de l'IGN sont supportés directement. Le pipeline détecte automatiquement la méthode de classification du sol (SMRF/PMF) en analysant le ratio de retours uniques du nuage de points.