Files
lidar_rendu/CLAUDE.md
Jacquin Antoine f01683819c 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

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-10 17:15:37 +02:00

4.7 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

LiDAR archaeological processing pipeline that generates 17 terrain visualizations from LAZ/LAS point clouds. Runs in Docker with optional NVIDIA GPU acceleration (CuPy). Designed for French LiDAR HD data in Lambert 93 (EPSG:2154).

Commands

All commands run inside Docker. Use ./run.sh as the primary interface.

./run.sh -g                                    # Standard run with GPU
./run.sh -g -w 4                               # GPU + 4 parallel workers
./run.sh -g -r 0.2                             # High resolution (0.2m/px)
./run.sh --test                                 # Run unit tests
./run.sh -g --file LHD_FXX_1000_6882_PTS_LAMB93_IGN69.copc  # Single file
./run.sh --ground-classification pmf            # Force PMF ground classification
./run.sh -g --keep-tif                          # Keep intermediate TIFF files
./run.sh -g --no-viewer                         # Skip web viewer generation
./run.sh serve                                  # Start web map server
./run.sh                                        # Print help (no args)

Direct Docker:

docker build -t lidar-lidar .
docker run --rm --gpus all -v $(pwd)/input:/data/input:ro -v $(pwd)/output:/data/output lidar-lidar

Architecture

Module responsibilities

  • cli.py — argparse + logging setup. Entry point via python -m lidar_pipeline.
  • pipeline.pyLidarArchaeoPipeline orchestrator. VIZ_STEPS registry maps names to generate functions. FilePrefixFilter for parallel logging.
  • dtm.py — PDAL ground classification (SMRF/PMF/CSF + auto-detection) and DTM generation via scipy binned_statistic_2d.
  • visualizations.py — 15 generate_* functions + 2 IGN overlay lambdas. All take (dem_file, basename, vis_dir, resolution) and return a TIF path or None.
  • gpu.py — CuPy/numpy abstraction: HAS_GPU, to_gpu(), to_cpu(), xp_gaussian_filter(), xp_uniform_filter(), xp_minimum_filter(), gpu_cleanup(). Falls back to CPU gracefully.
  • ign.py — IGN WMTS tile download + overlay generation for orthophoto and topographic maps.
  • rendering.pyCOLORMAPS dict maps filename keywords to (cmap, title, legend, description). tif_to_png() converts TIF→WebP with legend/scale/north arrow. convert_to_cog() converts TIF→Cloud Optimized GeoTIFF. generate_cog_metadata() creates metadata JSON for web viewer. generate_pdf_report() creates A3 PDF.
  • viewer.py — Generates MapLibre GL JS HTML viewer with layer controls, opacity sliders, and IGN/OSM basemaps.
  • server.py — TiTiler-based Starlette server for serving COG tiles and viewer HTML. Entry point via python -m lidar_pipeline.server.

Adding a visualization

Three places must be updated:

  1. visualizations.py — add generate_X(dem_file, basename, vis_dir, resolution) function
  2. pipeline.py VIZ_STEPS — add ('name', generate_X) entry
  3. rendering.py COLORMAPS — add entry keyed by the output filename keyword

Ground classification

Auto-detection in dtm.py detect_ground_method():

  • Single-return ratio > 0.6 → PMF (urban terrain)
  • Height std > 30m → CSF (complex/mountainous terrain)
  • Default → SMRF (natural terrain)

Override with --ground-classification {auto,smrf,pmf,csf}.

NaN handling

DTM small gaps (< 1m from existing data) are filled using rasterio.fill.fillnodata. Large gaps remain as NaN. Visualization functions use _fill_nans() and _filter_nanaware() to avoid NaN propagation through filters.

Parallel processing

Uses ProcessPoolExecutor with 'spawn' start method (required for CUDA). Each worker gets its own temp directory (temp_{basename}). _process_file_standalone() configures its own logger with _file_filter for per-file log prefixes.

Key conventions

  • Language: UI messages and comments in French. Code identifiers in English.
  • Logging: Use logger = logging.getLogger("lidar"). Prefix per-file logs via _file_filter.basename.
  • GPU pattern: arr_gpu = to_gpu(arr) → compute → result = to_cpu(arr_gpu)gpu_cleanup() between visualizations.
  • Output format: Visualizations saved as WebP (not PNG). TIFF intermediates deleted unless --keep-tif or viewer enabled. COGs generated for web viewer by default. PDF reports use PILImage.open().convert('RGB').
  • Web viewer: MapLibre GL JS + TiTiler. COGs served as raster tiles. ./run.sh serve starts server on port 8000.
  • Flow accumulation: Uses numba JIT for D8 accumulation loop. Falls back to pure Python if numba unavailable.
  • Tests: Run only inside Docker via ./run.sh --test. Synthetic DEM fixture in tests/conftest.py.