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.
This commit is contained in:
Antoine Jacquin
2026-09-13 23:28:24 +02:00
parent d847068288
commit df462ea86e
2 changed files with 50 additions and 16 deletions

View File

@ -1236,10 +1236,10 @@ _HTML_TEMPLATE = """<!DOCTYPE html>
</span>
</div>
<div class="preset-row">
<select id="presetSelect" class="gen-select" title="Préconfigurations : couches visibles, transparences et ordre de pile">
<select id="presetSelect" class="gen-select" title="Préconfigurations : couches visibles, niveaux de transparence (visualisations + fond de carte) et ordre de pile">
<option value="">Préconfigurations…</option>
</select>
<button id="presetSave" class="icon-btn" title="Enregistrer l'état actuel (couches, transparences, ordre) comme preset">💾</button>
<button id="presetSave" class="icon-btn" title="Enregistrer l'état actuel (couches, niveaux de transparence, ordre) comme preset">💾</button>
<button id="presetDelete" class="icon-btn" hidden title="Supprimer le preset sélectionné">✕</button>
</div>
<div id="vizLayers"></div>
@ -2243,22 +2243,31 @@ document.getElementById('osmRow').querySelector('.layer-name').title =
// ============================================================
// Préconfigurations de couches : un preset définit les couches
// visibles, leurs transparences et l'ordre de pile (bas → haut).
// Les presets intégrés couvrent les couches du panneau ; les presets
// personnels (couches + transparences + ordre) sont persistés en
// localStorage et se suppriment depuis la liste.
// visibles, leurs niveaux de transparence (opacités des
// visualisations + fond de carte OSM) et l'ordre de pile
// (bas → haut). Les presets intégrés couvrent les couches du
// panneau ; les presets personnels (persistés en localStorage)
// se suppriment depuis la liste.
// ============================================================
const PRESETS_LS = 'lidarPresets_v1';
// Les presets portent les niveaux de transparence : opacité de chaque
// visualisation + fond de carte OSM (visibilité, opacité, mode sombre).
const BUILTIN_PRESETS = [
{ label: 'Relief', on: ['aspect', 'positive_openness'],
opacity: { aspect: 1, positive_openness: 0.65 } },
opacity: { aspect: 1, positive_openness: 0.65 },
osm: { on: false } },
{ label: 'Pentes', on: ['aspect', 'slope'],
opacity: { aspect: 0.5, slope: 1 } },
opacity: { aspect: 0.5, slope: 1 },
osm: { on: true, opacity: 0.3 } },
{ label: 'Cavités', on: ['slope', 'positive_openness'],
opacity: { slope: 0.5, positive_openness: 1 } },
{ label: 'Rugosité', on: ['roughness'], opacity: {} },
opacity: { slope: 0.5, positive_openness: 1 },
osm: { on: false } },
{ label: 'Rugosité', on: ['roughness'],
opacity: {},
osm: { on: true, opacity: 0.3 } },
{ label: 'Tout', on: ['slope', 'aspect', 'positive_openness', 'roughness'],
opacity: { slope: 0.8, aspect: 0.8, positive_openness: 0.55, roughness: 0.8 } },
opacity: { slope: 0.8, aspect: 0.8, positive_openness: 0.55, roughness: 0.8 },
osm: { on: true, opacity: 0.85, dark: true } },
];
function loadCustomPresets() {
@ -2271,6 +2280,18 @@ function saveCustomPresets(list) {
try { localStorage.setItem(PRESETS_LS, JSON.stringify(list)); } catch (e) { /* privé */ }
}
// Niveaux de transparence d'un preset, lisibles dans la liste
// (opacité de chaque visualisation + fond de carte OSM).
function presetDetail(p) {
const parts = (p.on || []).filter(k => VIZ_META[k])
.map(k => (VIZ_META[k].label || k) + ' ' +
Math.round(((p.opacity && p.opacity[k] != null) ? Number(p.opacity[k]) : 1) * 100) + '%');
if (p.osm) parts.push('Fond ' + (p.osm.on
? Math.round((p.osm.opacity != null ? Number(p.osm.opacity) : 0.85) * 100) + '%'
: 'masqué'));
return parts.join(' · ');
}
function applyPreset(p) {
const want = (p.on || []).filter(k => VIZ_META[k]);
const L = state.layers;
@ -2282,8 +2303,15 @@ function applyPreset(p) {
L.on[k] = on;
if (on) L.opacity[k] = (p.opacity && k in p.opacity) ? Number(p.opacity[k]) : 1;
}
// Niveaux de transparence du fond de carte (visibilité, opacité, sombre)
if (p.osm) {
L.osm.on = !!p.osm.on;
if (p.osm.opacity != null) L.osm.opacity = Number(p.osm.opacity);
if (p.osm.dark != null) L.osm.dark = !!p.osm.dark;
}
saveLayers();
renderLayerPanel();
renderOsmRow();
syncTileLayers();
}
@ -2300,7 +2328,7 @@ function renderPresetSelect(selectedValue) {
for (const p of BUILTIN_PRESETS) {
const o = document.createElement('option');
o.value = 'builtin:' + p.label;
o.textContent = p.label;
o.textContent = p.label + ' — ' + presetDetail(p);
presetSelectEl.appendChild(o);
}
const customs = loadCustomPresets();
@ -2310,7 +2338,7 @@ function renderPresetSelect(selectedValue) {
for (const p of customs) {
const o = document.createElement('option');
o.value = 'custom:' + p.id;
o.textContent = p.label;
o.textContent = p.label + ' — ' + presetDetail(p);
g.appendChild(o);
}
presetSelectEl.appendChild(g);
@ -2332,11 +2360,14 @@ presetSaveEl.addEventListener('click', () => {
const name = prompt('Nom du preset :');
if (!name || !name.trim()) return;
const enabled = state.layers.order.filter(k => state.layers.on[k]);
const osm = state.layers.osm;
const p = {
id: Date.now().toString(36),
label: name.trim(),
on: enabled,
opacity: Object.fromEntries(enabled.map(k => [k, state.layers.opacity[k]])),
// Niveaux de transparence du fond de carte
osm: { on: osm.on, opacity: osm.opacity, dark: osm.dark },
};
const customs = loadCustomPresets();
customs.push(p);