Commit Graph

54 Commits

Author SHA1 Message Date
b4a0e384c9 Change minimap zoom to level 10 for wider view and faster download
Zoom 10 gives ~150m/px with 30km context (274px image), ideal for a
small inset. Much faster to download than zoom 12 (1100px).
2026-05-15 12:03:19 +02:00
9e89686ac5 Reduce location map context to 30km and use zoom 12
The 80km context made the red LiDAR zone rectangle too small to see.
30km (15km radius) at zoom 12 gives a clear view where the 1km data
zone is visible as a distinct red rectangle in the inset map.
2026-05-15 12:01:37 +02:00
5af53a390f Add multi-GPU support and fix scale bar / location map overlap
Multi-GPU:
- gpu.py: lazy CuPy initialization so CUDA_VISIBLE_DEVICES takes
  effect before context creation in worker processes
- gpu.py: detect GPU count via nvidia-smi (no CUDA import needed)
- gpu.py: add set_active_gpu() to assign workers to specific GPUs
- pipeline.py: distribute files across GPUs (file % num_gpus) in
  parallel mode so both GPUs are used simultaneously
- pipeline.py: log GPU count when multiple GPUs detected

Layout fixes:
- rendering.py: move scale bar left of location map to avoid overlap
  (scale bar ends at fig_x=0.78, map starts at 0.82)
- rendering.py: expand location map inset to 0.16x0.13 fig coords
- rendering.py: return bounds from _download_location_map so imshow
  extent matches the actual IGN tile coverage (80km context)
- ign.py: add min_zoom parameter to download_ign_tiles, fixing the
  location map that was broken (zoom 10 blocked by hardcoded min_zoom=15)
2026-05-15 12:00:34 +02:00
4848f25326 Upgrade colormaps to Crameri scientific palette and fix IGN location map
- Replace RdBu_r with Crameri roma for all 6 relief-family colormaps
  (curvature, mslrm, lrm, tpi, sailore, aniso_open): perceptually
  uniform, CVD-friendly, dark center makes near-zero values visible
- Replace hsv with twilight for aspect: perceptually uniform cyclic
  colormap with no hue discontinuity
- Add cmcrameri dependency (falls back to RdBu_r if unavailable)
- Fix IGN location map: pass min_zoom=8 to download_ign_tiles so zoom
  10 context maps work (was hardcoded to min_zoom=15, blocking the
  loop entirely for zoom_level=10)
- Expand location map context from 3x extent to 80km fixed radius for
  better regional context at zoom 10
- Remove dead code: flow colormap entry, _nice_scale dead loop,
  aspect='auto' in location map imshow, outdated PDF report order list
- Fix SVF docstring: 8 directions → 16 directions
2026-05-15 11:50:15 +02:00
c634db573a Fix corrupted COPC detection, add CSF→SMRF fallback, improve MSRM colormap, add SVF and anisotropic openness
- validate_laz: verify point data accessibility (not just headers) to detect
  corrupted COPC files that pass header checks but fail on data reads
- classify_ground: fallback from CSF to SMRF when CSF produces no ground
  points or PDAL errors (fixes 2/9 failing tiles)
- MSRM: preserve sign in weighted combination so RdBu_r colormap shows
  both red (elevated) and blue (depressed) instead of red only
- Add Sky-View Factor (SVF) visualization: cos²(horizon angle) over 16
  directions, excellent for archaeological earthwork detection
- Add Anisotropic Openness: directional weighting (NW-SE/NE-SW) enhances
  linear feature detection aligned with common settlement patterns
- Remove anomalies and flow visualizations (replaced by SVF + aniso_open)
- Location inset: use IGN topographic map at zoom 10 instead of simplified
  France outline, with red rectangle marker and fallback
- Remove flow (hydrological accumulation) from VIZ_STEPS
2026-05-15 01:38:09 +02:00
da454bd23e Improve visualizations: adaptive scales, revert z-score to std normalization
- MSRM/TPI/roughness/anomalies: revert z-score (x-mean)/std to std normalization x/std
  to preserve contrast and visibility of linear features (paths, ditches, trenches)
- MSRM: adaptive scales based on resolution, archaeological weight combination
- TPI: extend from 2 to 4 scales (3m/15m/50m/200m) with weighted combination
- Hillshade: 8 directions instead of 4, altitude 35° instead of 30°
- LRM: adaptive sigma based on resolution
- Openness: doubled radius (100m instead of 50m)
- Roughness: multi-scale (3m fine + 15m broad) instead of single 5x5 window
- Anomalies: uses MSRM multi-scale relief instead of single LRM 15m
- Wavelet: 8 adaptive scales, std normalization, archaeological weights
- Remove svf (Sky-View Factor) and local_dominance visualizations
- Add AVIF format support (default), quality 98
- Add multi-resolution support (-r 0.5,0.2)
- Improve Ctrl+C handling for immediate process termination
- Update rendering.py descriptions for all modified visualizations
2026-05-14 23:12:08 +02:00
57ffdbae67 Add multi-resolution support and remove PDF generation
- --resolution now accepts comma-separated values (e.g. 0.5,0.2)
- Additional resolutions get suffixed output dirs: basename_r0p2/
- DTM files are named basename_dtm_r0p2.tif for extra resolutions
- Ground classification is done once and shared across resolutions
- PDF report generation removed per user request
- Fix --file argument to accept full filenames with extensions
2026-05-14 21:29:45 +02:00
eccec302fe Fix --file argument to accept full filenames with extensions
Previously --file LHD_FXX_...copc.laz would fail because it appended
extensions. Now tries exact filename match first, then falls back to
adding extensions.
2026-05-14 21:17:03 +02:00
6aef7b8af3 Add WebP quality control and selective visualization (--only / --skip)
- WebP output now uses quality=85 by default (down from lossless),
  reducing file size by ~75% (35MB → 5-8MB per visualization)
- Added --quality N (1-100) and --lossless flags in CLI and run.sh
- Added --only and --skip to select/exclude specific visualizations
  (e.g., --only hillshade,svf,lrm or --skip ortho,topo)
- VIZ_STEPS filtering is done in LidarArchaeoPipeline.__init__
- SharedDEM is skipped when all selected visualizations already exist
- Invalid visualization names are validated at startup with clear error
2026-05-14 21:15:21 +02:00
5faa85b54b Handle empty point clouds gracefully at every pipeline stage
Fixes "zero-size array to reduction operation" crash on corrupt/incomplete
LAZ files. Added checks at each step:

- validate_laz(): check point_count > 0 via laspy header, parse PDAL
  info JSON for point count when using PDAL fallback
- detect_ground_method(): return 'smrf' default if point cloud is empty
  after PDAL conversion instead of crashing on np.max(empty_array)
- _read_with_pdal(): log warning and return None if converted file has
  0 points
- create_dtm_fast(): fail gracefully if ground file has 0 points
- classify_ground(): check output file size after PDAL pipeline to
  catch empty ground classifications early
2026-05-14 20:56:52 +02:00
96920b95cc List all processed LAZ files with status in pipeline summary
Show each file with ✓/✗ before the success/fail counts, so the user
can see at a glance which files succeeded and which failed.
2026-05-14 20:49:30 +02:00
a98d0836b7 Skip SharedDEM computation when all visualizations already exist
Two optimizations to avoid ~2min wasted per file on re-runs:

1. pipeline.py: Check which visualizations need regeneration before
   computing SharedDEM. If all WebP outputs exist, skip SharedDEM
   entirely. If only IGN overlays need updating, also skip SharedDEM.

2. visualizations.py: Make SharedDEM attributes lazy (filled, gradient,
   lrm_15) so only the data actually needed is computed. For example,
   if only hillshade is regenerated, LRM at 15m is never calculated.
2026-05-14 20:40:51 +02:00
c4322a3b88 Add download script for IGN LiDAR HD LAZ files
Supports tile download by coordinates, zone-based bulk download,
integrity checking, and auto-search across zones with resume support.
2026-05-14 20:34:50 +02:00
0d9e444118 Upgrade PDAL to 2.10 via conda-forge, add COPC v1.1 support
- Dockerfile: install PDAL 2.10.1 from conda-forge (was 2.3 from apt)
  Ubuntu 22.04's PDAL 2.3 cannot read COPC v1.1 files from IGN LiDAR HD
- dtm.py: add _read_with_pdal() fallback for COPC files that laspy can't read
- dtm.py: validate_laz() now tries PDAL when laspy fails
- dtm.py: create_dtm_fast() and detect_ground_method() use PDAL fallback
- ign.py: auto-retry at lower zoom on 404 errors
- pipeline.py: check DTM resolution mismatch and regenerate if needed
- pipeline.py: propagate actual DTM resolution to visualizations
- pipeline.py: add --init to docker run for proper Ctrl+C signal handling
- Remove RRIM and Multi-Hillshade RGB visualizations
2026-05-14 19:01:05 +02:00
0d46c96681 Add LAZ integrity check to skip corrupted files early
Validate file readability before PDAL classification. Corrupted/truncated
files are detected instantly via laspy header read and skipped with a clear
error message pointing to re-download, instead of wasting time on PDAL
and repair attempts that will fail anyway.
2026-05-14 17:59:32 +02:00
b3e644bd7d Auto-retry IGN tiles at lower zoom on 404
When zoom 20 tiles are unavailable (rural areas), fall back to zoom 19, 18,
etc. down to 15. Breaks out immediately on first-tile 404 to avoid wasting
requests at unsupported zoom levels.
2026-05-14 02:21:47 +02:00
f97e41eaea Remove RRIM and Multi-Hillshade RGB, fix DTM resolution reuse bug, add --init to docker run
- Remove generate_rrim, generate_multi_hillshade, _compute_openness_both
- Remove corresponding VIZ_STEPS entries, COLORMAPS, RGB_LEGENDS, and tests
- Fix DTM resolution mismatch: existing DTM at different resolution is now
  regenerated instead of silently reused
- Propagate actual DTM resolution to visualizations and rendering
- Add --init to docker run commands for proper signal handling on Ctrl+C
- Add .playwright-mcp/ to .gitignore
2026-05-14 02:19:42 +02:00
735f185773 Remove ETA display from visualization progress logs 2026-05-14 01:18:52 +02:00
978be54cf7 Fix lambda signatures for rrim and multi_hillshade to accept shared kwarg
Same issue as pos_open/neg_open — lambdas in VIZ_STEPS need shared=None
parameter since the pipeline passes shared=shared to all visualization functions.
2026-05-14 01:07:48 +02:00
53a1ff8bb2 Add unit tests for RRIM, Multi-Hillshade RGB, and Local Dominance
TestRRIM: TIF generation, 3-band RGB output, uint8 range, no NaN
TestMultiHillshade: TIF generation, 3-band RGB output, uint8 range
TestLocalDominance: TIF generation, values in [0,1], NaN mask preservation
2026-05-14 01:05:55 +02:00
989bb71497 Add RRIM, Multi-Hillshade RGB, and Local Dominance visualizations
Three new visualizations complementing existing SVF/openness/LRM/MSRM:

- RRIM (Red Relief Image Map): RGB composite combining positive openness
  (R), inverted slope (G), negative openness (B). Uses ray-tracing
  to compute both openness values in a single pass.

- Multi-Hillshade RGB: 3 azimuths (315°, 135°, 45°) mapped to R/G/B
  channels with slope blending. Color reveals structure orientation.

- Local Dominance: (dem - local_min) / (local_max - local_min) using
  min/max filters. Measures local height position — complements openness.

Also adds:
- _compute_openness_both() helper for shared ray-tracing (used by RRIM)
- xp_maximum_filter() in gpu.py (GPU/CPU abstraction)
- Entries in COLORMAPS, RGB_LEGENDS, VIZ_STEPS, and is_rgb detection
- All NaN handling follows existing patterns (nan_mask restoration)
2026-05-14 01:03:47 +02:00
56fa84b288 Remove PMF, fix NaN in gradient visualizations, fix pos_open/neg_open shared param
- Remove PMF from ground classification options (PDAL recommends SMRF over PMF)
- Auto-detection now uses CSF for urban/complex terrain instead of PMF
- Add z_std > 30m heuristic to auto-select CSF for complex terrain
- Fix pos_open/neg_open lambda missing 'shared' parameter (NameError in workers)
- Fix NaN mask not restored in hillshade, slope, aspect, curvature
  (gradient-based products computed on filled DEM lost NaN transparency)
- Add nan_mask parameter to _save_tif for centralized NaN restoration
- DTM TIF kept by default (no longer deleted after WebP conversion)
v1.0
2026-05-14 00:50:45 +02:00
15cd77456d Fix bugs and improve pipeline flexibility
- Fix gpu_cleanup import missing in visualizations.py (NameError in workers)
- Fix t_pdf referenced before assignment when PDF is skipped
- Skip classification+DTM when DTM exists regardless of --force
- --force now only regenerates WebP/PDF, not classification/DTM
- --force-classification forces reclassification when needed
- Add laspy repair fallback for corrupt LAZ files (EVLR errors)
- Keep DTM TIF by default for reuse (--no-keep-tif to delete)
- Increase space between image and bottom cartouche (0.12→0.19)
2026-05-14 00:08:25 +02:00
a1a5078e8b Skip ground classification when DTM already exists
If the DTM .tif exists and --force is not set, skip both ground
classification and DTM generation entirely. Previously, the pipeline
would spend 3+ minutes reclassifying ground even when the DTM was
already present and would be reused anyway.

Also includes: SharedDEM cache, enhanced WebP cartouche (compass rose,
adaptive scale bar, enriched info bar), removed COG/viewer, UTF-8
fix for parallel workers, skip logic for DTM and PDF.
2026-05-13 23:41:21 +02:00
a37b8848ab Interface web cartographique: COG + TiTiler + viewer MapLibre
- Ajout de convert_to_cog() et generate_cog_metadata() dans rendering.py
- Nouveau module viewer.py: génération HTML MapLibre GL JS avec couches et opacité
- Nouveau module server.py: serveur FastAPI avec TiTiler pour tuiles COG
- Pipeline: étapes 5 (COGs) et 6 (viewer web) après le rapport PDF
- CLI: flag --no-viewer pour désactiver la génération du viewer
- run.sh: commande 'serve' pour démarrer le serveur sur port 8000
- Dockerfile: ajout de rio-cogeo, titiler.core, fastapi, uvicorn, piexif
- setup.py: point d'entrée lidar-server
2026-05-10 17:15:37 +02:00
5c155e4999 Layout uniforme WebP: axes fixes + aspect='equal' pour superposition géolocalisée
- Positions d'axes fixes (data_left/bottom/width/height_frac) pour alignement
  pixel-parfait entre terrain et ortho/topo
- aspect='equal' au lieu de 'auto' pour conserver les proportions géographiques
- Colorbar descriptive pour les visualisations RGB (ortho/topo)
- Comblage des petits trous DTM (< 1m) via rasterio.fill.fillnodata
- Suppression de la visualisation "dépressions"
- Hillshade composite: 0.7*hillshade + 0.3*cos(slope)
- D8 flow accumulation accéléré par numba JIT (fallback Python)
- Flag --keep-tif pour conserver les TIFF intermédiaires
- --force supprime aussi les TIF existants avant régénération
- ETA affiché pendant la génération des visualisations
- Répertoires temp dans temp/ pour traitement parallèle
2026-05-10 14:46:31 +02:00
a88e430f02 Audit: corrections de bugs identifiés
- rendering.py: colorbar cassée quand NaN mask actif — créer un
  ScalarMappable avec le cmap sauvegardé au lieu de rely sur
  l'image RGBA qui n'a plus de cmap
- rendering.py: nettoyage du PNG temporaire avec try/finally et
  missing_ok=True pour éviter les fichiers orphelins
- gpu.py: to_gpu() convertit en float32 au lieu de float64 pour
  réduire la consommation mémoire GPU
- dtm.py: utiliser _file_basename() de pipeline.py au lieu de
  dupliquer la logique d'extraction du basename
- pipeline.py: docstring corrigé (18 visualisations, pas 19)
- cli.py: --file supporte aussi les noms sans .copc
  (recherche .copc.laz et .copc.las en plus de .laz et .las)
2026-05-10 12:11:13 +02:00
1c7f4870ce Fix SyntaxError: supprimer la définition dupliquée de main() 2026-05-10 12:04:52 +02:00
c244a12ed5 Fix basename: retirer .copc.laz au lieu de .laz seul
Les fichiers LiDAR HD IGN ont l'extension .copc.laz (double extension).
Path.stem ne retire que .laz, laissant .copc dans le basename.
Ajout de _file_basename() qui retire les extensions connues
dans l'ordre: .copc.laz, .copc.las, .laz, .las.
2026-05-10 12:02:32 +02:00
af8d9c4814 Nettoyage des processus PDAL orphelins à l'interruption
Ajout de signal handlers (SIGINT/SIGTERM) et atexit pour tuer
les processus pdal orphelins quand le pipeline est interrompu
ou se termine. Utilise pkill -f pdal pour nettoyer.
2026-05-10 11:58:30 +02:00
e73cf75060 Rendu: zones NaN transparentes au lieu d'interpolation DTM
L'interpolation fillnodata du DTM générait des artefacts visuels
(zones lissées artificielles). Revenu au DTM avec NaN conservés.

Nouvelle approche pour le rendu:
- NaN remplacés par la médiane des valeurs valides (valeur neutre)
- Après application de la colormap, un masque alpha rend les zones
  NaN transparentes au lieu de les afficher
- interpolation='bilinear' sur imshow pour un rendu lisse
- Figure adaptative: 20-40 pouces selon la taille des données
- DPI 200 pour les images > 3000px
2026-05-10 11:56:11 +02:00
62038b2d5b Fix crash quand valid_data est vide dans _apply_colormap
np.percentile crash avec IndexError quand valid_data est vide
(TIF entièrement NaN). Ajout d'un guard qui retourne une
colormap par défaut si aucune donnée valide n'existe.
2026-05-10 11:42:21 +02:00
0ff2b992ff Nettoyage des répertoires temporaires après traitement
- _process_file_standalone: supprime temp_{basename} après chaque fichier
- process_all: supprime aussi les répertoires temp_* orphelins des workers
- 18 Go de fichiers .las orphelins supprimés manuellement
2026-05-10 11:41:03 +02:00
c5e9a60fee Amélioration du rendu: interpolation DTM et affichage haute résolution
- DTM: interpolation des NaN avec rasterio.fill.fillnodata après
  binned_statistic_2d — comble les trous entre les cellules sans données
- Rendering: interpolation='bilinear' sur imshow pour lisser le
  sous-échantillonnage des données haute résolution
- Rendering: fig_width adaptatif (20-40 pouces) selon la taille des données
- Rendering: DPI 200 pour les images > 3000px de large
2026-05-10 11:34:41 +02:00
ba6fb64754 Suppression de la visualisation Texture GLCM
- Suppression de generate_texture() de visualizations.py
- Suppression de l'entrée 'texture' de VIZ_STEPS et COLORMAPS
- Suppression du test TestTexture
- Mise à jour README (19 → 18 visualisations)
- Mise à jour AGENTS.md (17 → 16 fonctions generate_*)
2026-05-10 03:30:07 +02:00
f1336e8bdd Orthophoto IGN: zoom adaptatif pour résolution optimale
- Zoom WMTS calculé automatiquement à partir de la résolution DTM
  (0.5m/px → zoom 19, 0.2m/px → zoom 20) au lieu de zoom 15 fixe
- Orthophoto: zoom max 20 (~0.15m/px), carte topo: zoom max 19
- Limite image 10000x10000px (au lieu de 5000x5000)
- Log du nombre de tuiles et de la taille avant téléchargement
2026-05-10 03:22:08 +02:00
b8d080885b Mise à jour du README: classification sol, options CLI, structure complète
- Section classification du sol (SMRF/PMF/CSF + auto-détection)
- Pré-traitement ELM + outlier dans le workflow
- Options --ground-classification et --force-classification
- Paramètres GPU et classification dans la table des options
- Structure des dossiers avec temp/ et tests/
- Section tests unitaires
- Aucun lien externe
2026-05-10 03:06:03 +02:00
67151c6409 Fix numpy warnings: MaskedArray partition et Mean of empty slice
- Convert MaskedArray to ndarray avant np.percentile() via
  np.asarray(data.compressed()) et np.ma.filled(data, np.nan)
- Supprimer RuntimeWarning "Mean of empty slice" dans MSRM et
  ondelette avec warnings.catch_warnings()
- Ajout import warnings dans visualizations.py
2026-05-10 03:02:36 +02:00
67380d0424 Pipeline LiDAR: classification sol auto + pré-traitement ELM + fix warnings
- 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
2026-05-10 03:00:33 +02:00
e7e6468a56 Préfixer les logs par le nom du fichier LAZ en cours
Ajout d'un FilePrefixFilter qui préfixe chaque message avec [basename]
quand un fichier est en cours de traitement. Les workers paralleles
affichent ainsi clairement quel fichier produit chaque log.
2026-05-10 01:32:19 +02:00
85aaf5f278 Logging multiprocessing: configure logger dans les workers spawn + compteur de progression 2026-05-10 01:30:01 +02:00
293ce3fae1 Supprimer les RuntimeWarnings: NaN dans nanmean et cast uint8 2026-05-10 01:29:03 +02:00
b5e41dd75a Préserver les zones sans données: NaN-aware filtering dans les visualisations
- DTM: plus d'interpolation, les zones sans LiDAR restent NaN
- Ajout _fill_nans() et _filter_nanaware(): remplissent les NaN par
  nearest-neighbor avant filtrage, puis restaurent le masque NaN
- Toutes les visualisations avec filtres (LRM, MSLRM, TPI, SAILORE,
  roughness, anomalies, wavelet) utilisent _filter_nanaware pour
  éviter l'érosion des bords de données
- _save_tif() écrit nodata=float('nan') quand le tableau contient des NaN
- Les zones sans données restent vides dans les visualisations
- Les calculs ne sont pas faussés par des valeurs interpolées
2026-05-10 01:24:36 +02:00
9f7d01ac3a Pas d'interpolation dans le DTM: les zones sans données restent NaN
- Suppression de l'interpolation NearestNDInterpolator dans create_dtm_fast
- Les pixels sans données LiDAR restent NaN dans le DTM et les
  visualisations — pas de valeurs fictives qui faussent les calculs
- nodata=float('nan') dans le GeoTIFF de sortie pour identifier les vides
- _save_tif() détecte automatiquement les NaN et écrit le flag nodata
2026-05-10 01:17:48 +02:00
c6d0065eca Fix PDF report: lire WebP via PIL au lieu de matplotlib.imread
matplotlib ne supporte pas WebP. Remplace plt.imread() par
PILImage.open().convert('RGB') dans generate_pdf_report.
2026-05-10 01:06:21 +02:00
e66a71d885 Fix CUDA fork: spawn multiprocessing + graceful GPU fallback
- multiprocessing.set_start_method('spawn') pour éviter la corruption
  du contexte CUDA dans les processus forkés
- to_gpu() et xp_*_filter() attrapent les erreurs CUDA et tombent
  sur CPU au lieu de crasher
- _gpu_available() vérifie que le GPU est utilisable avant chaque opération
- gpu_cleanup() attrape les exceptions au cas où le GPU serait indisponible
2026-05-10 01:04:02 +02:00
e734c9c472 Suppression éclairage solaire, GPU accéléré, --file multi, tests unitaires
- 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
2026-05-10 00:57:39 +02:00
405b0d20f8 Refactor pipeline en modules + logging verbose/debug + options CLI
- Découpage du monolithe process_lidar.py (~2750 lignes) en package
  lidar_pipeline/ avec 9 modules (gpu, dtm, visualizations, ign,
  rendering, pipeline, cli, __init__, __main__)
- Logging configurable: -v (verbose avec timestamps) et --debug
  (détails internes fichier:ligne)
- Option --force pour régénérer tous les fichiers (par défaut skip
  les WebP existants)
- Option --file NOM pour traiter un seul fichier LAZ (tests rapides)
- ProcessPoolExecutor avec répertoires temporaires uniques par worker
- Suppression du code mort (geomorphons, hillshade_ne, nodata_mask)
- Aucun fichier TIFF résiduel après conversion WebP
- setup.py pour installation pip, stub process_lidar.py compatible
2026-05-10 00:15:29 +02:00
73bc42dae4 Pipeline LiDAR: accélération GPU (CuPy), sortie WebP, script run.sh
- Accélération GPU via CuPy pour SVF, Openness, LRM, MSRM, SAILORE, TPI, wavelet
- Fallback automatique vers numpy si GPU non disponible
- Sortie WebP sans perte (remplace PNG, fichiers plus petits)
- Script run.sh avec options -g (GPU), -w (workers), -r (résolution)
- Docker basé sur nvidia/cuda:12.4.0-devel pour support CuPy
- Docker tourne en uid/gid 1000:1000
- Légendes explicites différenciant LRM vs MSRM vs SAILORE
- Correction bug ordre elif (mslrm avant lrm)
- Retrait de geomorphons et VAT (demande utilisateur)
2026-05-09 22:22:28 +02:00
6f946d9d2d Pipeline LiDAR: 19 visualisations archéologiques, corrections SVF/Openness, légendes explicites
- Corriger SVF: ray-tracing 16 azimuts (inversion DEM remplacée)
- Corriger Openness: angle zénith/nadir sur 8 directions (min/max filter remplacé)
- Ajouter MSRM (LRM multi-échelle 5/10/25/50/100m)
- Ajouter TPI multi-échelle (5m + 100m)
- Ajouter détection dépressions (remplissage hydrologique)
- Ajouter SAILORE (LRM adaptatif f(pente))
- Ajouter rugosité de surface (écart-type local 5m)
- Ajouter anomalies statistiques (z-score + Moran's I)
- Ajouter ondelette Mexican Hat (CWT 5 échelles)
- Ajouter texture GLCM (contraste + entropie - homogénéité)
- Ajouter accumulation de flux (D8)
- Retirer geomorphons et VAT composite
- Répertoire par fichier LAZ dans visualisations/
- Support multi-CPU (-w/--workers)
- Légendes explicites avec différenciation entre techniques similaires
- Docker: uid/gid 1000:1000
2026-05-09 21:13:20 +02:00