Corriger la revue stage1 de la refonte : fiche de dalle, thème du fond, cadre d'export, tokens de couleur

Retour/Échap depuis la fiche détaillée ne retouche plus la hauteur du volet
téléphone (openTab remplacé par un rétablissement direct de l'onglet) ; le
fond OSM suit le thème sauf choix explicite (migration du localStorage et des
défauts serveur en v3, plus de dark:true hérité de l'ex-webapp) et part du
bon thème dès sa création (plus de flash sombre) ; l'onglet Export mémorisé ne
recadre plus la vue au premier rendu (lien partagé préservé) et referme son
cadre pendant que la fiche détaillée est ouverte ; la qualité affichée suit le
nom réel de la dalle rendue ; un second clic referme la fiche au lieu de
déplacer son contour derrière elle ; couleurs en dur restantes tokenisées
(--tile-sel, --gps, .gen-log) et lisibles en thème clair ; localStorage
corrompu (lidar-panel, lidar-print) n'y casse plus l'interface.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Antoine Jacquin
2026-09-27 18:52:30 +02:00
parent 56c9fa0ccd
commit 72b10cd228
5 changed files with 249 additions and 25 deletions

View File

@ -911,11 +911,15 @@ def _sanitize_defaults(req):
base_in = req.base if isinstance(req.base, dict) else {}
base = {"on": bool(base_in.get("on", True)),
"opacity": _clamp01(base_in.get("opacity"), 0.85),
"dark": bool(base_in.get("dark", True))}
# None = pas de choix explicite (le fond suit le thème côté carte) ;
# seule une valeur booléenne reçue devient un choix figé.
"dark": None if base_in.get("dark") is None else bool(base_in.get("dark"))}
# v: 3 distingue ce format (dark éventuellement None = pas choisi) de
# l'ancien, qui écrivait toujours dark:true (voir map_meta).
return {"main": req.main if req.main in known else None,
"mode": req.mode if req.mode in VIEW_MODES else "relief",
"precision_opacity": _clamp01(req.precision_opacity, DEFAULT_PRECISION_OPACITY),
"base": base, "saved_at": time.time()}
"base": base, "v": 3, "saved_at": time.time()}
class DefaultsRequest(BaseModel):
@ -974,6 +978,11 @@ def map_meta():
if main not in keys or main == PRECISION_VIZ:
main = default_main_layer(keys)
mode = saved.get("mode") if saved.get("mode") in VIEW_MODES else DEFAULT_VIEW_MODE
# Fichier d'avant v3 (ex-webapp) : base.dark:true systématique, jamais un
# vrai choix — servi comme "non choisi" (None, le fond suit le thème).
base_default = saved.get("base")
if isinstance(base_default, dict) and saved.get("v") != 3:
base_default = dict(base_default, dark=None)
return {
"layers": infos,
"default_main": main,
@ -981,7 +990,7 @@ def map_meta():
"default_mode": mode,
"default_precision_opacity": _clamp01(saved.get("precision_opacity"),
DEFAULT_PRECISION_OPACITY),
"default_base": saved.get("base"),
"default_base": base_default,
"defaults_saved": bool(saved),
# L'interface consomme des tuiles 512 px (2× moins de requêtes qu'en
# 256 : décisif en HTTP/1.1) ; les clients OSM gardent le 256 canonique.
@ -1085,16 +1094,20 @@ def map_tile_info(lat: float, lng: float):
# coins NO, NE, SE, SO (lat, lng) : cadre de sélection sur la carte
"corners": [[round(la, 7), round(lo, 7)] for lo, la in zip(lons, lats)],
}
q = read_quality(OUTPUT_DIR, base["name"])
base["quality"] = ({"ground_density": q.get("ground_density"),
"acq_start": q.get("acq_start"), "acq_end": q.get("acq_end")}
if q else None)
best = None
for t in scan_tiles(OUTPUT_DIR / "visualisations"):
if (t["col"], t["row"]) != (col, row):
continue
if best is None or t["resolution"] < best["resolution"]:
best = t
# Qualité (densité, dates) : sous le nom réel de la dalle rendue quand il y
# en a une (best["basename"] peut différer du nom nominal calculé depuis
# col/row) ; nom nominal sinon, faute de mieux.
quality_name = best["basename"] if best else base["name"]
q = read_quality(OUTPUT_DIR, quality_name)
base["quality"] = ({"ground_density": q.get("ground_density"),
"acq_start": q.get("acq_start"), "acq_end": q.get("acq_end")}
if q else None)
if best is None:
return {"found": False, **base}
meta = _collect_tile_metadata(best, OUTPUT_DIR / "DTM")