From 45455aec93b01b08600421464873d9afbf9daa47 Mon Sep 17 00:00:00 2001 From: Antoine Jacquin Date: Sun, 27 Sep 2026 18:17:18 +0200 Subject: [PATCH] =?UTF-8?q?Remplacer=20la=20fiche=20de=20dalle=20flottante?= =?UTF-8?q?=20par=20une=20bulle=20et=20une=20fiche=20d=C3=A9taill=C3=A9e?= =?UTF-8?q?=20dans=20le=20panneau?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- lidar_pipeline/mapserve.py | 5 ++ lidar_pipeline/tests/test_mapserve.py | 36 +++++++++++ lidar_pipeline/web/map.css | 21 +++---- lidar_pipeline/web/map.html | 19 +++--- lidar_pipeline/web/map.js | 91 ++++++++++++++++++++++----- 5 files changed, 132 insertions(+), 40 deletions(-) diff --git a/lidar_pipeline/mapserve.py b/lidar_pipeline/mapserve.py index 70ef4c6..63dfe8f 100644 --- a/lidar_pipeline/mapserve.py +++ b/lidar_pipeline/mapserve.py @@ -1071,6 +1071,7 @@ def map_tile_info(lat: float, lng: float): IGN se charge à part (/api/map/ign). """ from .index import _collect_tile_metadata, _res_suffix_str, scan_tiles + from .quality import read_quality x, y = tiles_mod.wgs84_to_l93(lng, lat) col, row = int(x // 1000), int(y // 1000) + 1 x0, y0, x1, y1 = col * 1000, (row - 1) * 1000, (col + 1) * 1000, row * 1000 @@ -1084,6 +1085,10 @@ 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): diff --git a/lidar_pipeline/tests/test_mapserve.py b/lidar_pipeline/tests/test_mapserve.py index fa0a08f..8a15d4f 100644 --- a/lidar_pipeline/tests/test_mapserve.py +++ b/lidar_pipeline/tests/test_mapserve.py @@ -246,6 +246,28 @@ def test_map_tile_info(tmp_path, monkeypatch): assert mapserve.map_tile_info(lat=45.0, lng=1.0)["found"] is False +def test_map_tile_includes_quality(tmp_path, monkeypatch): + """/api/map/tile joint la qualité (densité, dates d'acquisition) si connue.""" + mapserve = _setup(tmp_path, monkeypatch, layers=("relief_oriente",)) + from lidar_pipeline.quality import write_quality, QUALITY_VERSION + name = "LHD_FXX_1054_6882_PTS_LAMB93_IGN69" + write_quality(tmp_path, name, {"version": QUALITY_VERSION, "ground_density": 12.5, + "density_grid": [[12.5]], "empty_fraction": 0.1, + "acq_start": "2021-03-02", "acq_end": "2021-03-02", + "acq_source": "gps"}) + lat, lon = _center() + d = mapserve.map_tile_info(lat=lat, lng=lon) + assert d["quality"] == {"ground_density": 12.5, "acq_start": "2021-03-02", + "acq_end": "2021-03-02"} + + +def test_map_tile_quality_absent_is_none(tmp_path, monkeypatch): + """Sans sidecar qualité, la clé vaut None (pas d'erreur).""" + mapserve = _setup(tmp_path, monkeypatch, layers=("relief_oriente",)) + lat, lon = _center() + assert mapserve.map_tile_info(lat=lat, lng=lon)["quality"] is None + + def test_healthz_and_assets(tmp_path, monkeypatch): """Sonde de santé et assets de l'interface (revalidés, jamais immuables).""" from fastapi import HTTPException @@ -302,6 +324,20 @@ def test_map_ui_tile_load_indicator_and_selection_pane(): assert "pane: 'tileSel'" in _MAP_JS +def test_ui_tile_popup_and_details_view(): + """La fiche de dalle est une bulle Leaflet + une vue détaillée dans le panneau.""" + from lidar_pipeline.mapui import _MAP_CSS, _MAP_HTML, _MAP_JS + assert 'id="tilecard"' not in _MAP_HTML + for id_ in ("tileView", "tileBack", "tileTitle", "tileBody"): + assert f'id="{id_}"' in _MAP_HTML, id_ + for fn in ("function showTilePopup(", "function openTileDetails(", "function closeTileViews("): + assert fn in _MAP_JS, fn + assert "L.popup(" in _MAP_JS and "Détails" in _MAP_JS + # Pas de bulle pendant le déplacement du cadre d'export ni un tracé + click = _MAP_JS[_MAP_JS.index("map.on('click'"):] + assert "genDrawing" in click[:400] and "PRINT.dragging" in click[:400] + + def test_defaults_roundtrip(tmp_path, monkeypatch): """L'affichage réglé depuis la carte devient la configuration servie à tous.""" import lidar_pipeline.mapserve as mapserve diff --git a/lidar_pipeline/web/map.css b/lidar_pipeline/web/map.css index f64be18..10978de 100644 --- a/lidar_pipeline/web/map.css +++ b/lidar_pipeline/web/map.css @@ -58,13 +58,6 @@ html, body { height: 100%; overflow: hidden; background: var(--bg); color: var(- −30 % de CPU (moteur de rendu + GPU) en déplacement, mesuré sous Chrome. */ .leaflet-tile-pane .leaflet-layer.base-dark { filter: brightness(0.38) contrast(1.1) saturate(0.7); } -.card { position: fixed; z-index: var(--z-panel); background: var(--surface); color: var(--text); - border: 1px solid var(--border); border-radius: var(--r-md); - box-shadow: var(--shadow-lg); - backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); } -/* Fiche de dalle : à droite du panneau (ordinateur), en haut (téléphone). */ -#tilecard { left: max(var(--sp-3), var(--panel-w)); top: 12px; width: 340px; max-width: calc(100vw - 24px); - max-height: calc(100vh - 24px); overflow-y: auto; } .info-sec { margin-top: 10px; } .info-sec h4 { margin: 0 0 4px; font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); } @@ -76,10 +69,14 @@ html, body { height: 100%; overflow: hidden; background: var(--bg); color: var(- .info-dl:hover { background: color-mix(in srgb, var(--accent) 30%, transparent); } .rose-cap { font-size: var(--fs-xs); color: var(--text); line-height: 1.3; } .rose-cap span { color: var(--muted); font-size: var(--fs-xs); } -.card-head { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-bottom: 1px solid var(--border); } -.card-title { font-size: var(--fs-sm); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); } -.card-body { padding: 6px 8px 8px; max-height: min(60vh, 520px); overflow-y: auto; } -.card-foot { display: flex; gap: 8px; padding: 8px 4px 2px; margin-top: 6px; border-top: 1px solid var(--border); } +.tile-head .sec-title { margin: 0; flex: 1; } +.leaflet-popup-content-wrapper, .leaflet-popup-tip { background: var(--surface); color: var(--text); + box-shadow: var(--shadow-lg); } +.leaflet-popup-content-wrapper { border-radius: var(--r-md); border: 1px solid var(--border); } +.leaflet-popup-content { margin: var(--sp-2) var(--sp-3); font-size: var(--fs-sm); line-height: 1.45; } +.leaflet-container a.leaflet-popup-close-button { color: var(--muted); } +.tile-pop b { font-size: var(--fs-md); } +.tile-pop .row { margin-top: var(--sp-2); } /* --- composants communs --------------------------------------------------- */ .btn, button { display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-1); @@ -205,7 +202,6 @@ body.drawing .leaflet-container { cursor: crosshair !important; } background: rgba(0,0,0,0.35); border: 1px solid var(--border); border-radius: var(--r-sm); padding: 6px 8px; max-height: 130px; overflow-y: auto; white-space: pre-wrap; word-break: break-all; margin: 6px 0; } -#tools button.accent { color: var(--accent); border-color: var(--accent); } #tools button.busy { color: var(--accent); border-color: var(--accent); } /* Cadres des dalles du run : orange pulsant = rendu en cours, bleu = en attente, rouge = échec. Les dalles faites n'ont pas de cadre. */ @@ -254,6 +250,7 @@ body.panel-collapsed { --panel-w: 84px; } #panel[data-sheet="closed"] { height: 72px; } #panel[data-sheet="half"] { height: 45vh; } #panel[data-sheet="full"] { height: calc(100vh - var(--sp-4)); } + #panel[data-sheet="full"] { height: calc(100dvh - var(--sp-4)); } #panel[data-sheet="closed"] .panel-body { display: none; } #panelCollapse { display: none; } .sheet-grip { display: flex; justify-content: center; padding: var(--sp-2) 0 0; cursor: grab; touch-action: none; } diff --git a/lidar_pipeline/web/map.html b/lidar_pipeline/web/map.html index 2dceb79..7425449 100644 --- a/lidar_pipeline/web/map.html +++ b/lidar_pipeline/web/map.html @@ -74,7 +74,7 @@
-
+
-
+