fix(fires): keep retained heat hidden when reenabling an empty filter

Add a lifecycle regression and register it in the format scope.
This commit is contained in:
Adrian Sbardella committed 2026-11-03 21:06:56 -03:00
1 parent dda9a48e5b
commit 37e751f1e3
4 files changed
+49 -1

No files matched your search

+2
View File
@@ -2231,6 +2231,8 @@ view), so the weak fires the heatmap shows stay on screen as markers when it
fades out; it reads each marker's already-built anchor instead of the ground fades out; it reads each marker's already-built anchor instead of the ground
floor cache, which only the close band warms. "N FIRES" cards from a 2° / 1° aggregation still label the hottest floor cache, which only the close band warms. "N FIRES" cards from a 2° / 1° aggregation still label the hottest
areas; their accent is the strongest fire's FRP color. areas; their accent is the strongest fire's FRP color.
Re-enabling Active Fires keeps the retained heat imagery hidden when the current
filtered set is empty, including while a new snapshot is pending.
The Active Fires row carries a "Fire intensity (FRP)" slider on a log scale The Active Fires row carries a "Fire intensity (FRP)" slider on a log scale
whose track is painted with the ramp and ticked at the same six values (its whose track is painted with the ramp and ticked at the same six values (its
+1
View File
@@ -408,6 +408,7 @@
"src/layers/firms/cards.js", "src/layers/firms/cards.js",
"src/layers/firms/index.js", "src/layers/firms/index.js",
"src/layers/firms/ingestion.js", "src/layers/firms/ingestion.js",
"src/layers/firms/heatVisibility.test.mjs",
"src/layers/firms/lifecycle.js", "src/layers/firms/lifecycle.js",
"src/layers/firms/model.js", "src/layers/firms/model.js",
"src/layers/firms/policy.js", "src/layers/firms/policy.js",
+44
View File
@@ -0,0 +1,44 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { createLifecycle } from './lifecycle.js';
test('reenabling an empty filtered layer never reveals the retained pre-filter heat raster', async () => {
let shown = false;
const noop = () => {};
const layerState = {
_enabled: false,
_viewer: {},
_dataSource: {},
_fires: [],
_loading: true,
_pickIndexById: new Map(),
_heatImagery: {
setShow(v) {
shown = v;
},
},
};
const lifecycle = createLifecycle({
layerState,
services: {
picking: { registerPickOwner: noop, unregisterPickOwner: noop },
sprites: { restoreSpriteOrderOnEnable: noop },
context: { clearSelectedEntityContextForLayer: noop },
},
config: { id: 'local-firms', overlayHost: { setVisible: noop } },
components: {
rendering: { applyHandoffFade: noop },
viewport: { installLodWatcher: noop, installMoveEndWatcher: noop },
selection: { installClickHandler: noop },
},
});
await lifecycle.methods.enable(layerState._viewer);
assert.equal(
shown,
false,
'empty current set must keep the old raster hidden while refresh is pending',
);
layerState._fires = [{ frp: null, confidence: null }];
await lifecycle.methods.enable(layerState._viewer);
assert.equal(shown, true, 'nonempty sets still resume their raster');
});
+2 -1
View File
@@ -54,7 +54,8 @@ export function createLifecycle({
layerState._billboards.show = true; layerState._billboards.show = true;
} }
overlayHost.setVisible(FIRMS_OVERLAY_SOURCE_ID, true); overlayHost.setVisible(FIRMS_OVERLAY_SOURCE_ID, true);
layerState._heatImagery?.setShow(true); // A filter can leave an old raster cached while the current set is empty.
layerState._heatImagery?.setShow(layerState._fires.length > 0);
// The camera can have crossed the hand-off while the layer was off. // The camera can have crossed the hand-off while the layer was off.
components.rendering.applyHandoffFade(true); components.rendering.applyHandoffFade(true);
components.viewport.installLodWatcher(); components.viewport.installLodWatcher();