Files
gods-eye-view/src/layers/firms/lifecycle.js
T

120 lines
4.5 KiB
JavaScript

import * as Cesium from 'cesium';
import { FIRMS_OVERLAY_SOURCE_ID } from '../../data/firmsLabels.js';
export function createLifecycle({
layerState,
services,
components,
config,
feed,
}) {
const { registerPickOwner, unregisterPickOwner } = services.picking;
const { restoreSpriteOrderOnEnable } = services.sprites;
const { clearSelectedEntityContextForLayer } = services.context;
const { id, overlayHost } = config;
const methods = {
init(viewer) {
if (layerState._destroyed) return;
layerState._viewer = viewer;
layerState._dataSource = new Cesium.CustomDataSource(id);
layerState._dataSource.show = false;
viewer.dataSources.add(layerState._dataSource);
},
async enable(viewer) {
if (layerState._destroyed) return;
layerState._enabled = true;
layerState._viewer = viewer;
if (!layerState._dataSource) this.init(viewer);
if (layerState._dataSource) layerState._dataSource.show = true;
if (layerState._billboards) {
// The camera can have moved anywhere while the layer was off: moveEnd
// was not being listened to, and the preRender watcher is inert while
// disabled AND while the (untimed) refetch below is in flight. So the
// retained per-sprite show flags describe the OLD viewpoint. Re-cull
// BEFORE the collection becomes visible — otherwise re-enabling at a
// new location flashes far-side fires through the planet (and keeps
// near-side ones hidden) until the fetch resolves.
components.rendering.refreshHorizonCulling();
layerState._billboards.show = true;
}
overlayHost.setVisible(FIRMS_OVERLAY_SOURCE_ID, true);
components.viewport.installLodWatcher();
components.viewport.installMoveEndWatcher();
components.selection.installClickHandler();
registerPickOwner(id, (pickedId) =>
layerState._pickIndexById.has(pickedId),
);
if (!layerState._fires.length && !layerState._loading)
await components.ingestion.loadHeatmap();
if (
layerState._enabled &&
!layerState._destroyed &&
layerState._viewer === viewer
)
restoreSpriteOrderOnEnable('firms', viewer);
},
disable() {
layerState.request?.abort();
layerState.request = null;
layerState._loading = false;
layerState._enabled = false;
components.selection.clearFireSelection();
if (layerState._dataSource) layerState._dataSource.show = false;
if (layerState._billboards) layerState._billboards.show = false;
overlayHost.clearSource(FIRMS_OVERLAY_SOURCE_ID);
overlayHost.setVisible(FIRMS_OVERLAY_SOURCE_ID, false);
clearSelectedEntityContextForLayer(id);
components.selection.removeClickHandler();
components.viewport.removeMoveEndWatcher();
unregisterPickOwner(id);
components.viewport.removeLodWatcher();
},
destroy(viewer = layerState._viewer) {
layerState.request?.abort();
layerState.request = null;
layerState._loading = false;
if (layerState._destroyed) return;
layerState._destroyed = true;
layerState._enabled = false;
components.viewport.removeLodWatcher();
components.viewport.removeMoveEndWatcher();
components.selection.removeClickHandler();
unregisterPickOwner(id);
if (layerState._dataSource && viewer) {
viewer.dataSources.remove(layerState._dataSource, true);
}
layerState._dataSource = null;
components.rendering.removeDetectionCollections(viewer);
components.selection.clearContextRegistrations();
clearSelectedEntityContextForLayer(id);
layerState._fires = [];
layerState._firesByFrp = [];
layerState._cellCacheByGrid.clear();
layerState._count = 0;
layerState._cellCount = 0;
layerState._lastUpdate = null;
layerState._keyRequired = false;
layerState._stale = false;
layerState._error = null;
layerState._currentLodId = null;
overlayHost.clearSource(FIRMS_OVERLAY_SOURCE_ID);
overlayHost.setVisible(FIRMS_OVERLAY_SOURCE_ID, false);
layerState._currentLodIndex = -1;
layerState._lastViewRect = null;
layerState._selectedFire = null;
layerState._labelCandidates = [];
layerState._labelLodDistance = 0;
layerState._pickIndexById.clear();
layerState._fireByCardId.clear();
layerState._cullPositions.length = 0;
layerState._camSnapValid = false;
},
};
return { methods };
}