ensureLayers and addPinLayers guard the layers, not just the source
`if (map.getSource('tapestry')) return` returns having added NOTHING whenever the
source outlives the layers — and that state is real, not hypothetical: setStyle()
wipes LAYERS, which is why paintAll is re-armed on 'style.load' at :1625. The
re-add is a genuine code path (the light/dark toggle) and this guard could silently
no-op it, leaving a map with a source, no polygons and no pins.
addPinLayers had the identical bug on getSource('upg'), which is why territories
and pins would disappear together: one mistake, made twice.
ensureSelectionLayers():652 ALREADY HAD THE RIGHT SHAPE — `if (!map ||
!map.getSource('tapestry')) return; if (map.getLayer('upg-sel-fill')) return`. The
correct pattern was sitting in this file and its two siblings did not copy it.
Presence of a source and presence of the layers drawn from it are two properties;
a function whose job is the second must not test the first.
EACH LAYER IS GUARDED SEPARATELY because addLayer THROWS on an id that already
exists — a half-built style is exactly the state this fix is for, so re-adding a
survivor would abort the function and skip everything after it.
⚠ THIS IS NOT THE CAUSE OF THE BLANK ENGLISH README SHOT, and I am recording that
because I diagnosed it as such and was wrong. I had a confident chain — source
survives layers, half-built style, hence en blank while ar painted — and started
fixing it as the cause. rega settled it with the measurement I did not have: the
leaf paints 9.5-16.5 s after load and the screenshot tool waited 7 s. A timeout,
not a defect. The chain explained the symptom without being true of it, and
claiming this commit fixes that shot would be exactly the false attribution I have
been correcting in other people's reports today.
Kept on its own merits. BUNDLE=my-upg-100-list vite build clean.
This commit is contained in:
parent
0952006343
commit
ea90e9b288
2 changed files with 95 additions and 65 deletions
|
|
@ -604,8 +604,24 @@ function buildMatchColorExpr(zones) {
|
|||
}
|
||||
|
||||
function ensureLayers() {
|
||||
if (map.getSource('tapestry')) return
|
||||
map.addSource('tapestry', { type: 'geojson', data: tapestry })
|
||||
// ⚠ GUARD ON THE LAYERS, NOT ONLY THE SOURCE — "the source exists" and "the layers exist" are two
|
||||
// properties, and this function's job is the second one. The old guard was
|
||||
// `if (map.getSource('tapestry')) return`, which returns and adds NOTHING whenever the source
|
||||
// survives while the layers are gone. That state is real: a style reload wipes LAYERS, and a source
|
||||
// can be present without them.
|
||||
// ⚠ THIS IS NOT THE CAUSE OF THE BLANK ENGLISH README SHOT, and I want that on record because I
|
||||
// diagnosed it as such and was wrong. rega settled that one with the measurement I did not have:
|
||||
// the leaf paints 9.5-16.5 s after load and the screenshot tool waited 7 s. A timeout, not a defect.
|
||||
// I had built a confident chain — source-survives-layers, half-built style, en/ar divergence — that
|
||||
// explained the symptom without being true of it.
|
||||
// THE GUARD BUG IS STILL REAL, on its own merits and on a different path: setStyle() (the
|
||||
// light/dark toggle) wipes LAYERS, and a source can outlive them, so the old guard returns having
|
||||
// added nothing. That is why paintAll is re-armed on 'style.load' at :1625 — the re-add is a real
|
||||
// code path, and this guard could silently no-op it.
|
||||
// ensureSelectionLayers():652 already had the right shape (source AND getLayer) — the correct
|
||||
// pattern was in this file and these two functions did not copy it. addPinLayers had the same bug.
|
||||
if (map.getSource('tapestry') && map.getLayer('tapestry-fill') && map.getLayer('tapestry-line')) return
|
||||
if (!map.getSource('tapestry')) map.addSource('tapestry', { type: 'geojson', data: tapestry })
|
||||
// 09b light-default L-D2: the neon cyber palette runs hot on white. ensureLayers
|
||||
// is called on the initial draw AND on every post-setStyle theme re-add, so we
|
||||
// read isDark.value HERE (JS state, not a map expression) to pick per-theme
|
||||
|
|
@ -614,22 +630,30 @@ function ensureLayers() {
|
|||
// the bright tapestry-LINE outline carries the glow on light either way.
|
||||
const deafOpacity = isDark.value ? 0.45 : 0.30
|
||||
const othersOpacity = isDark.value ? 0.65 : 0.45
|
||||
map.addLayer({
|
||||
id: 'tapestry-fill',
|
||||
type: 'fill',
|
||||
source: 'tapestry',
|
||||
paint: {
|
||||
'fill-color': matchColorExpr,
|
||||
'fill-opacity': ['case', ['==', ['get', 'zoneKey'], 'deaf'], deafOpacity, othersOpacity],
|
||||
},
|
||||
})
|
||||
map.addLayer({
|
||||
id: 'tapestry-line',
|
||||
type: 'line',
|
||||
source: 'tapestry',
|
||||
// F2-D2: brighter, thicker outline gives contrast on dark without washing out light.
|
||||
paint: { 'line-color': matchColorExpr, 'line-width': 1.2, 'line-opacity': 0.9 },
|
||||
})
|
||||
// ⚠ EACH LAYER IS GUARDED SEPARATELY, because the two can be lost independently — and addLayer
|
||||
// THROWS on an id that already exists, which would abort this function and skip everything after it.
|
||||
// A half-built style is exactly the state this fix exists for, so it must not be made worse by
|
||||
// re-adding a survivor.
|
||||
if (!map.getLayer('tapestry-fill')) {
|
||||
map.addLayer({
|
||||
id: 'tapestry-fill',
|
||||
type: 'fill',
|
||||
source: 'tapestry',
|
||||
paint: {
|
||||
'fill-color': matchColorExpr,
|
||||
'fill-opacity': ['case', ['==', ['get', 'zoneKey'], 'deaf'], deafOpacity, othersOpacity],
|
||||
},
|
||||
})
|
||||
}
|
||||
if (!map.getLayer('tapestry-line')) {
|
||||
map.addLayer({
|
||||
id: 'tapestry-line',
|
||||
type: 'line',
|
||||
source: 'tapestry',
|
||||
// F2-D2: brighter, thicker outline gives contrast on dark without washing out light.
|
||||
paint: { 'line-color': matchColorExpr, 'line-width': 1.2, 'line-opacity': 0.9 },
|
||||
})
|
||||
}
|
||||
|
||||
// ★ THE REAL READINESS SIGNAL. onLegendSelect() returns early unless map.getLayer('tapestry-fill')
|
||||
// exists, so a "Show on map" request that arrives before this function runs cannot hold a
|
||||
|
|
@ -2100,8 +2124,14 @@ onMounted(async () => {
|
|||
// Pin layer add, factored out so BOTH the initial draw() and the post-setStyle
|
||||
// theme re-add (handleToggleTheme) can call it. Idempotent: guards getSource('upg').
|
||||
addPinLayers = () => {
|
||||
if (map.getSource('upg')) return
|
||||
map.addSource('upg', { type: 'geojson', data: pinFC })
|
||||
// ⚠ SAME BUG, SAME FIX as ensureLayers():606 — guard on the LAYER, not only the source. The old
|
||||
// `if (map.getSource('upg')) return` adds nothing whenever the source survives a style reload
|
||||
// while 'upg-pins' does not. NOT the cause of the blank English README shot (that was a 7 s
|
||||
// screenshot wait against a 9.5-16.5 s first paint — rega measured it); this is the
|
||||
// setStyle/theme-toggle path, where the re-add is real and could silently no-op.
|
||||
if (map.getSource('upg') && map.getLayer('upg-pins')) return
|
||||
if (!map.getSource('upg')) map.addSource('upg', { type: 'geojson', data: pinFC })
|
||||
if (map.getLayer('upg-pins')) { attachPinHandlers(); return }
|
||||
map.addLayer({
|
||||
id: 'upg-pins', type: 'circle', source: 'upg', paint: {
|
||||
// BUG-UPG100-DOTS-HARD-TO-SEE (2026-09-19): the previous floor (2.5px @ low zoom,
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue