Au rechargement de la page, l'index obsolète du worker (16 couches)
polluait le /api/tiles fusionné et mergeTilesData réajoutait les couches
retirées au menu. viz_meta est désormais filtré aux couches du panneau
(PANEL_VIZ) côté serveur, et le panneau client est figé au chargement
(clés VIZ_META initiales) : aucun flux ne peut réintroduire de couche
hors panneau, même avec un index distant périmé.
Le bouton ⌖ recentre la carte sur la position GPS du téléphone. L'API
Geolocation exige un contexte sécurisé : la webapp sert désormais du HTTP
et le TLS est porté par le reverse proxy (Traefik, labels dans l'override
local) ; le webapp est transparent au proxy (URLs relatives, X-Forwarded-For
pour la restriction LIDAR_REGEN_CIDR). Ajoute le modèle d'override
docker-compose.webapp.override.yml.example, un rebuild d'index à la demande
et met à jour doc/déploiement ; les tuiles sont servies à la demande.
- POST /api/stop : SIGTERM au pipeline (groupe isolé via start_new_session),
SIGKILL du groupe après 15 s ; forwardé au worker en mode deux machines
- « Régénérer » n'implique plus la reclassification : le DTM en cache est
réutilisé tant que la méthode ne change pas ; nouvelle case « Reclasser le
sol » (--force-classification) et rappel de la classification existante
- Tâche marquée « Interrompu » (returncode négatif ou nul) au lieu d'Échec
Les images (visualisations, vignettes, sous-tuiles) sont rapatriées depuis
la machine de traitement par HTTP au moment où elles sont affichées, puis
servies depuis le disque : une image absente est téléchargée, une image
périmée ( ?v= plus récent que sa mtime, tuile régénérée) est rafraîchie.
/api/tiles fusionne l'index du worker (cache 60 s) avec le cache local, si
bien que les tuiles non cachées apparaissent quand même sur la carte.
Worker hors ligne : disjoncteur 2 min après 3 échecs, index local seul,
/api/status répond running=null — aucune erreur cliente.
- URLs images versionnées (?v=mtime) : une tuile recalculée change d'URL et
force le rechargement navigateur (cache heuristique contourné), y compris
en plein run via /api/tiles ; veille permanente 15 s sur la carte
- simulation locale du mode deux machines (docker-compose.local-2m.yml) :
worker GPU :8974 + webapp légère :8973 au cache séparé output-webapp/
- override webapp pour le Pi 5 (192.168.3.3) : volume /srv/lidar/output,
rsync vers le worker, labels Traefik (proxy/websecure/myresolver)
- purge 0,5 m : worker/process et politique générale passés à 0,2 m seul
- intègre le travail parallèle non commité : export mosaïque multi-dalles
(export.py + /api/export), sous-tuilage intégral des couches, légendes
VIZ_LEGENDS, docs et tests associés (213 tests verts)
index.py rewritten as a continuous Leaflet map: rotated L93 tiles, stackable
visualization layers (per-layer opacity, drag-reorder persisted in
localStorage), tile info panel, live rebuild after each tile during a run.
Leaflet is vendored in assets/vendor/ so the map works fully offline;
georeferencing falls back rasterio -> pyproj -> affine so the lightweight
webapp (no GDAL) is supported.
docker-compose.worker.yml adds the tile generator service (full image + GPU)
that remote webapps call via LIDAR_GENERATION_URL, plus a one-shot process
profile. webapp.py gains LIDAR_AUTO_SYNC_SECONDS periodic cache refresh and
LIDAR_REGEN_CIDR restricting generation to the local network. run.sh
--serve-webapp now mounts ~/.ssh read-only so the rsync sync works.
docs/DEPLOY_WEBAPP.md completed for Raspberry Pi deployment: prerequisites,
git clone install, SSH key setup, first sync, update procedure and
troubleshooting.
La webapp (carte + vignettes) et la génération de tuiles se déploient sur
deux machines : image légère Dockerfile.webapp (FastAPI + Pillow AVIF
natif + pyproj) sur Raspberry Pi, pipeline complet sur la machine de
traitement. LIDAR_GENERATION_URL délègue /api/generate, /api/preview et
/api/status ; /api/sync ramène les tuiles par rsync puis régénère
vignettes et index localement. Token partagé optionnel
(LIDAR_API_TOKEN/LIDAR_REMOTE_TOKEN). Retire du dépôt les journaux
internes (.swival, audit-findings) et les données (data/, notebooks/).
Doc : docs/DEPLOY_WEBAPP.md.
- Web map: multi-select picker in the generation bar (aspect, slope,
positive openness, anisotropic openness, wavelet) passed to the API;
the layer panel is restricted to the same shortlist (PANEL_VIZ) and
a refresh button rebuilds the index when new layers appear on disk;
jobs started outside the UI are now adopted into the visible queue
- Uniform colors across tiles: openness/anisotropic/sailore now store
local z-scores, and all renderers use fixed ranges (0-3 sigma, SVF
0-1 physical, slope 0-30 deg) instead of per-tile percentile stretches
- Ray-tracing falls back to CPU when VRAM is exhausted so openness and
SVF no longer fail silently on shared GPUs
- build_index merges visualizations available at only one resolution
into the displayed tile so in-progress layers stay visible
- 11 new tests (142 passing)
- 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