Commit Graph

186 Commits

Author SHA1 Message Date
5f018fe2b6 Raccorder les bords de tuiles voisines et encadrer les rendus en cours
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.
2026-09-19 20:44:44 +02:00
204b2ad111 Preset Défaut : masquer la pente (openness + aspect 50 % + fond OSM 30 %) 2026-09-19 19:08:45 +02:00
2310676886 Preset Défaut : fond OSM visible à 30 % sous la pile de couches 2026-09-19 19:07:21 +02:00
4c189834c6 Inverser la pile du preset Défaut : openness en base, aspect 50 %, pente au sommet 2026-09-19 19:06:43 +02:00
2751d0fea1 Préconfiguration intégrée unique (pente 0, aspect 50, openness 100) 2026-09-19 19:03:56 +02:00
9546173c07 Préréglage carte par défaut et serve-webapp.sh compatible Traefik 2026-09-19 11:05:16 +02:00
e8a9b0187c Porter la carte au zoom 20 et passer le worker à 5 workers 2026-09-19 10:55:44 +02:00
41206f65de Caler les faisceaux de vol, décimer l'openness et cibler les couches affichées
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.
2026-09-19 00:53:22 +02:00
796e68c870 Supprimer le code mort (imports inutilisés, variable _xp, conseil GPU inatteignable) 2026-09-18 21:31:19 +02:00
91d31bcdf9 Numéroter les zones après tri, lire le journal par la fin et corriger l'aide -g 2026-09-18 21:24:57 +02:00
f3708f8449 Journaliser les replis CPU du GPU et retirer une copie VRAM inutile 2026-09-18 21:23:39 +02:00
93d1656d9f Coller les dalles directement dans le canevas habillé (pic mémoire divisé par 2) 2026-09-18 21:22:53 +02:00
5e13151998 Fermer les images PIL et borner le cache de cartes de localisation 2026-09-18 21:20:14 +02:00
394dd27375 Rendre robustes les tuiles WMTS IGN : retry, urlencode, User-Agent, latitude bornée 2026-09-18 21:19:28 +02:00
777b0c3f98 Téléchargement IGN atomique (.part + rename) et pagination du catalogue STAC 2026-09-18 21:18:06 +02:00
fd5ad283f7 Comparer le token d'API à temps constant 2026-09-18 21:16:23 +02:00
de8d84b94b Échapper les noms de dalles injectés dans l'interface (HTML et <script> inline) 2026-09-18 21:16:01 +02:00
1eed1f2029 Toujours supprimer le LAS temporaire du repli PDAL, même en échec 2026-09-18 21:13:22 +02:00
340743abe0 Poser le processus du job avant son fil de veille (double lancement possible) 2026-09-18 21:12:51 +02:00
c8c9f64db1 Plafonner la passe globale de complétion comme dans /api/preview 2026-09-18 21:12:18 +02:00
fbb56936f8 Étiqueter les événements de progression par run pour filtrer les retardataires 2026-09-18 21:11:47 +02:00
ecd21d5b46 Borner le nettoyage PDAL à notre run et supprimer le pkill à chaque sortie 2026-09-18 21:09:32 +02:00
bb086e308a Rendre effectif le délai de sécurité de 2 h des workers parallèles 2026-09-18 21:08:25 +02:00
4cdbf5a0e4 Rejeter proprement les tuiles 100 % nodata en détection d'anomalies 2026-09-18 21:07:32 +02:00
4c8fa68f71 Sol nu : ramener aussi les cellules sans mesure au retour le plus bas 2026-09-18 21:07:01 +02:00
c8e3b6abd9 Diviser le gradient par la résolution hors chemin partagé (pentes fausses) 2026-09-18 21:06:25 +02:00
476f246fe7 Masquer le nodata avant étalonnage colormap et colorbar en unités réelles 2026-09-18 21:05:55 +02:00
3c19dc4226 Blinder la normalisation terrain contre les tuiles d'altitude constante 2026-09-18 21:04:13 +02:00
92197e3e57 Restaurer le rayon réel de 100 m pour SVF et openness à 0,2 m 2026-09-18 21:03:24 +02:00
6d96da6546 Fusionner l'index du worker dans la coquille au rebuild (1er chargement complet)
- Sur la webapp légère, le rebuild ne voyait que le cache local : la
  coquille HTML embarquait un sous-ensemble des tuiles et le premier
  chargement n'affichait pas les tuiles récentes du worker — elles
  n'arrivaient qu'au sondage /api/tiles suivant (15 s).
- _merge_remote_index() applique au rebuild la même fusion que
  /api/tiles (l'index distant prime, le local complète) et réécrit
  index_tiles.json ET la liste embarquée dans index.html.
- AGENTS.md : avertissement — le Pi de prod tourne en compose+override
  (labels Traefik + /srv/lidar/output), jamais via serve-webapp.sh.
2026-09-17 08:01:01 +02:00
a87d049ef6 Bâcher l'interface dans l'image complète aussi, repli inscriptible
- Le Dockerfile principal (worker, --serve, local-2m) n'avait pas l'étape
  de bake : le repli de webapp.py tentait d'écrire webapp_assets/ dans le
  paquet installé (dist-packages, propriété de root) et faisait planter
  l'import de la webapp sous l'utilisateur lidar.
- Même étape de bake que Dockerfile.webapp, avec cd /tmp pour cibler le
  paquet installé (sinon la copie source /app capte l'import via sys.path).
- Le repli de webapp.py ne casse plus l'import si le dossier du paquet
  n'est pas inscriptible : réécriture dans un répertoire temporaire.
2026-09-17 07:46:14 +02:00
ac182da55e Sert l'interface (app.js/app.css) depuis l'image, plus depuis le volume
- Les assets de l'interface étaient écrits dans le volume (output/assets)
  et servis d'ici : sur la webapp légère, un app.js périmé restait servi
  même après rebuild de l'image.
- app.js/app.css (+ Leaflet vendorisé) sont désormais bâchés dans l'image
  au build (Dockerfile.webapp) et servis depuis l'image ; le volume ne
  porte que les données (index.html, vignettes, tuiles).
- _write_ui_assets() génère les assets dans un dossier cible ; repli de
  régénération au démarrage si non bâchés (dev). build_index continue
  d'écrire output/assets/ pour le mode serveur statique.
2026-09-17 00:42:12 +02:00
6fb2c4ee97 Ne plus réadopter les runs de génération vidés au rechargement de la page
- Le bouton « Vider » ne retirait que les tâches du côté client : au
  rechargement, la « dernière génération » du serveur
  (.generation.job.json) était réadoptée et les tâches finies
  réappaissaient.
- Les runs retirés sont mémorisés par horodatage serveur (sessionStorage) ;
  l'adoption au chargement les ignore désormais.
- Les tâches lancées immédiatement (sans passer par la file) captent
  l'horodatage de leur run à la fin, pour être retirables sans réadoption.
2026-09-16 23:48:27 +02:00
f024514427 Sélection de tuiles au clic, file d'attente et rafraîchissement fiable
- Clic sur la carte pour choisir des dalles précises, même sans données
  existantes (via /api/cell) ; les zones dessinées s'ajoutent à la
  sélection au lieu de la remplacer
- Une demande lancée pendant un run part en file d'attente côté serveur
  et démarre à la fin du travail en cours (plus de refus 409), file
  vidable depuis l'interface
- Tuiles et interface toujours fraîches : images servies sans cache
  navigateur (revalidation 304), rechargement de la carte seulement une
  fois le rebuild de l'index terminé
- serve-webapp.sh : sous-commande update retirée, documentation de
  déploiement corrigée en conséquence
2026-09-16 22:37:53 +02:00
26c05319fd Tuiles jointives : grille en outline et assets versionnés
La bordure 1px des tuiles insettait l'image (box-sizing: border-box) et
creusait un espace vide entre deux tuiles ; la grille est désormais un
outline dessiné par-dessus le bord des images, sans consommer de place
(hover/sélection/export/régénération adaptés). Les URLs de app.css et
app.js portent un hash de contenu : chaque évolution force le
rechargement chez tous les navigateurs, même avec une entrée de cache
antérieure aux en-têtes no-cache.
2026-09-16 21:42:46 +02:00
328af123ad Zoom animé : tuiles scalées d'un bloc comme le fond de carte
Les marqueurs Leaflet glissent pendant l'animation de zoom sans changer
de taille : les tuiles LiDAR nageaient sur le fond OSM puis sautaient à
la fin du zoom. Elles vivent désormais dans un pane dédié (lidarTiles)
qui reçoit la même mise à l'échelle que les couches de dalles (translate
+ scale au zoomanim, transition CSS partagée leaflet-zoom-animated) ;
markerZoomAnimation est désactivé pour éviter le double mouvement.
2026-09-16 21:34:44 +02:00
daed457adb Alléger la carte : rugosité retirée, vignettes 160 px, cap mémoire
Retire la couche Rugosité du panneau (DEFAULT_LAYERS restreint panneau,
presets et sélecteur de génération). Réduit la mémoire du navigateur :
vignettes de sous-tuiles à 160 px (régénérées sans ré-encoder les AVIF),
pleine résolution plafonnée à 24 images les plus proches du centre, src
des <img> libéré hors écran. Les changements de palier pré-décodent
l'image avant échange (zoom et pan sans flash).
2026-09-16 21:23:24 +02:00
8d29f03191 Rendre l'échelle de rugosité jointive entre tuiles
Le z-score par tuile et le vmax au percentile 98 par tuile donnaient une
échelle de couleur non jointive (écart-type variant de 0,05 a 0,58 m selon
la dalle). Références de normalisation figées (médianes mesurées sur 20
dalles réelles) et vmax fixe 3,8 (p98 médian) : même rugosité physique =
même couleur partout.
2026-09-16 20:33:56 +02:00
6780f2e25b Compler les NaN du MNT 8x plus vite via transformée de distance
Remplace NearestNDInterpolator (cKDTree sur les 25 M de points valides,
plusieurs secondes par dalle trouée en mode IGN pur) par
distance_transform_edt : plus proche voisin en une passe O(n).
Voisins équidistants arbitres differemment, sans effet sur les rendus.
2026-09-16 20:21:54 +02:00
06a8dd5604 Accélérer la rugosité 2.5x via écarts-types par sommes intégrales 2026-09-16 20:19:15 +02:00
0887d240f7 Accélérer le ray-tracing (SVF, openness) ~10x via accumulation des tangentes 2026-09-16 20:12:00 +02:00
264ccb028f Fix validation PreviewRequest : bbox et viz acceptent null (all_missing) 2026-09-14 19:49:07 +02:00
cea671c0ac Afficher l'IP client (x-forwarded-for) dans les logs des requêtes API 2026-09-14 19:30:08 +02:00
df462ea86e Inclure les niveaux de transparence du fond de carte dans les presets
Les presets portent désormais les niveaux de transparence complets :
opacité de chaque visualisation + fond de carte OSM (visibilité,
opacité, mode sombre). Les libellés du sélecteur affichent les
niveaux (ex. « Relief — Aspect 100% · Openness positive 65% · Fond
masqué ») et l'application d'un preset resynchronise la ligne du fond
de carte.
2026-09-13 23:28:24 +02:00
d847068288 Ajouter des préconfigurations de couches (couches, transparences, ordre)
L'onglet Couches propose un sélecteur de presets : cinq presets
intégrés (Relief, Pentes, Cavités, Rugosité, Tout) définissent les
couches visibles, leurs transparences et l'ordre de pile. 💾 enregistre
l'état actuel comme preset personnel (persisté en localStorage), ✕ le
supprime depuis la liste « Mes presets ».
2026-09-13 23:17:11 +02:00
0d3aa41008 Filtrer les couches retirées du flux /api/tiles et de la fusion en direct
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é.
2026-09-13 23:06:08 +02:00
f79608a92f Panéau et couches par défaut limités aux 4 couches conservées
La carte ne conserve que Pente, Aspect, Openness positive et Rugosité :
PANEL_VIZ est restreint à DEFAULT_LAYERS, le sélecteur de génération
suit le panneau, et ces 4 couches sont allumées par défaut via
default_layers (index.html + index_tiles.json). Les autres couches ne
sont plus ni affichées ni proposées.
2026-09-13 21:44:56 +02:00
e2533bac48 Centrer la carte sur le GPS du téléphone (HTTPS terminé par le proxy)
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.
2026-09-13 19:57:09 +02:00
24897367e0 Partage de vue : lien avec couches, transparences et fond OSM
Bouton « Partager » dans l'onglet Couches : copie un lien URL encodant
la vue (zoom/lat/lng), la pile de couches avec visibilité et opacité,
et le fond OSM (affiché, opacité, mode sombre). Le destinataire reçoit
l'état exact, le lien prime sur son localStorage local. Hash étendu :
#zoom,lat,lng&L=clé:opacité:visible,...&O=on:opacité:dark — le hash
simple #zoom,lat,lng reste rétro-compatible.
2026-09-12 23:43:36 +02:00
bc94ae3df0 Découpler le suffixe de résolution de l'import du pipeline dans l'index
_res_suffix_str importait LidarArchaeoPipeline (donc dtm→numpy) juste pour
le nommage des fichiers : sur la webapp légère sans numpy, build_index
échouait avec « No module named 'numpy' » et l'index n'était jamais
régénéré. Logique réimplémentée localement, synchronisée avec
pipeline._res_suffix et _strip_res_suffix.
2026-09-12 20:52:15 +02:00