fix: Properly restore layers when switching view modes

Three bugs fixed:
1. Map mode now restores all hidden layers - using separate tracking
   arrays for fills, lines, and symbols that persist across mode switches
2. Satellite mode now hides ALL vector layers (fills, lines, symbols)
   for true satellite-only view
3. Hybrid mode keeps lines and symbols visible for road/label overlay

Each mode switch first restores all layers to a clean slate before
hiding the appropriate ones for that mode.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Matt 2026-05-02 02:19:28 +00:00
commit 66f91fd379

View file

@ -1323,81 +1323,113 @@ function updateSatellitePaint(map, themeId) {
} }
// Track which vector layers are hidden in satellite/hybrid mode // Track which vector layers are hidden in satellite/hybrid mode
let hiddenVectorLayers = [] // Track hidden layers for each mode - separate arrays for proper restoration
let hiddenFillLayers = []
let hiddenLineLayers = []
let hiddenSymbolLayers = []
/** Hide vector fill layers for satellite mode */ // Layers we never hide (our own overlays)
function hideVectorFills(map) { function isProtectedLayer(id) {
if (!map) return return id.startsWith('public-lands') ||
hiddenVectorLayers = [] id.startsWith('boundary') ||
id.startsWith('route') ||
id.startsWith('measure') ||
id.startsWith('contour') ||
id.startsWith('usfs') ||
id.startsWith('blm') ||
id.startsWith('hillshade') ||
id.startsWith('traffic') ||
id === SATELLITE_LAYER
}
const style = map.getStyle() /** Hide a layer and track it */
if (!style || !style.layers) return function hideLayer(map, layerId, trackingArray) {
if (!map.getLayer(layerId)) return
for (const layer of style.layers) { const vis = map.getLayoutProperty(layerId, 'visibility')
// Hide fill and background layers (land, water, parks, buildings, etc.) if (vis !== 'none') {
// But keep line, symbol, and circle layers trackingArray.push(layerId)
if (layer.type === 'fill' || layer.type === 'fill-extrusion' || layer.type === 'background') { map.setLayoutProperty(layerId, 'visibility', 'none')
// Don't hide our own overlay fills (public lands, etc)
if (layer.id.startsWith('public-lands') ||
layer.id.startsWith('boundary') ||
layer.id.startsWith('route')) continue
const visibility = map.getLayoutProperty(layer.id, 'visibility')
if (visibility !== 'none') {
hiddenVectorLayers.push(layer.id)
map.setLayoutProperty(layer.id, 'visibility', 'none')
}
}
} }
} }
/** Show all hidden vector layers */ /** Show all layers in a tracking array */
function showVectorFills(map) { function showLayers(map, trackingArray) {
if (!map) return for (const id of trackingArray) {
if (map.getLayer(id)) {
for (const layerId of hiddenVectorLayers) { map.setLayoutProperty(id, 'visibility', 'visible')
if (map.getLayer(layerId)) {
map.setLayoutProperty(layerId, 'visibility', 'visible')
} }
} }
hiddenVectorLayers = [] trackingArray.length = 0
} }
/** Set map to satellite-only mode */ /** Set map to satellite-only mode - hide ALL vector layers except our overlays */
function setSatelliteMode(map, themeId) { function setSatelliteMode(map, themeId) {
if (!map) return if (!map) return
// First restore any previously hidden layers to clean slate
showLayers(map, hiddenFillLayers)
showLayers(map, hiddenLineLayers)
showLayers(map, hiddenSymbolLayers)
addSatelliteLayer(map, themeId) addSatelliteLayer(map, themeId)
hideVectorFills(map)
// Also hide line layers in pure satellite mode (keep only labels for reference)
const style = map.getStyle() const style = map.getStyle()
if (style && style.layers) { if (!style?.layers) return
for (const layer of style.layers) {
if (layer.type === 'line' && !layer.id.startsWith('route') && for (const layer of style.layers) {
!layer.id.startsWith('boundary') && !layer.id.startsWith('measure')) { if (isProtectedLayer(layer.id)) continue
const visibility = map.getLayoutProperty(layer.id, 'visibility')
if (visibility !== 'none') { if (layer.type === 'fill' || layer.type === 'fill-extrusion' || layer.type === 'background') {
hiddenVectorLayers.push(layer.id) hideLayer(map, layer.id, hiddenFillLayers)
map.setLayoutProperty(layer.id, 'visibility', 'none') } else if (layer.type === 'line') {
} hideLayer(map, layer.id, hiddenLineLayers)
} } else if (layer.type === 'symbol') {
hideLayer(map, layer.id, hiddenSymbolLayers)
} }
} }
console.log('[Satellite] Hidden:', hiddenFillLayers.length, 'fills,', hiddenLineLayers.length, 'lines,', hiddenSymbolLayers.length, 'symbols')
} }
/** Set map to hybrid mode (satellite + labels/roads) */ /** Set map to hybrid mode - satellite + roads + labels */
function setHybridMode(map, themeId) { function setHybridMode(map, themeId) {
if (!map) return if (!map) return
// First restore any previously hidden layers to clean slate
showLayers(map, hiddenFillLayers)
showLayers(map, hiddenLineLayers)
showLayers(map, hiddenSymbolLayers)
addSatelliteLayer(map, themeId) addSatelliteLayer(map, themeId)
hideVectorFills(map)
// In hybrid mode, keep road lines and labels visible const style = map.getStyle()
// They're already visible by default, just fills are hidden if (!style?.layers) return
// In hybrid: hide fills/background, keep lines and symbols visible
for (const layer of style.layers) {
if (isProtectedLayer(layer.id)) continue
if (layer.type === 'fill' || layer.type === 'fill-extrusion' || layer.type === 'background') {
hideLayer(map, layer.id, hiddenFillLayers)
}
// Lines and symbols stay visible for hybrid mode
}
console.log('[Hybrid] Hidden:', hiddenFillLayers.length, 'fills, keeping lines and symbols visible')
} }
/** Set map back to normal map mode */ /** Set map back to normal map mode */
function setMapMode(map) { function setMapMode(map) {
if (!map) return if (!map) return
removeSatelliteLayer(map) removeSatelliteLayer(map)
showVectorFills(map)
// Restore all hidden layers
showLayers(map, hiddenFillLayers)
showLayers(map, hiddenLineLayers)
showLayers(map, hiddenSymbolLayers)
console.log('[Map] Restored all vector layers')
} }