Commit Graph

194 Commits

Author SHA1 Message Date
e5895df7b8 Installer depuis requirements.txt et retirer les paquets jamais importés 2026-09-18 21:28:14 +02:00
d2d8e4d85d Retirer l'entry point lidar-server pointant vers un module inexistant 2026-09-18 21:25:31 +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
0dc485d0bf Rendre le montage de la clé SSH désactivable (LIDAR_MOUNT_SSH=0) 2026-09-18 21:17:05 +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
93ac46393f Durcir Jupyter : utilisateur non root, token généré, input en lecture seule 2026-09-18 21:14:09 +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
dd1aca3cfe Laisser le compose override et webapp.env locaux à chaque machine
Le fichier de configuration de la webapp distante (montages du cache,
adresse du worker, labels reverse-proxy) dépend de la machine : chaque
clone garde sa copie, ignorée par git. webapp.env.example reste le
modèle versionné.
2026-09-13 00:17:40 +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
8e55fc5f98 Arrêt de génération et reclassification optionnelle depuis l'interface
- 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
2026-09-12 20:27:52 +02:00
bde2025714 Peupler le cache de la webapp à la visualisation, sans rsync
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.
2026-09-12 19:49:14 +02:00
68272cabf0 Tuiles visibles en direct après régénération et déploiement webapp distante
- 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)
2026-09-12 17:48:37 +02:00
78a2c328c3 Document code audit findings and architecture notes in AGENTS.md 2026-09-07 21:30:59 +02:00