refactor: construct application layers from supplied sources

This commit is contained in:
Sameh Khamis committed 2026-09-14 14:20:01 -07:00
1 parent cd704d0e9b
commit 8160ac5fe4
53 files changed
+1152 -400

No files matched your search

+4 -25
View File
@@ -1,17 +1,8 @@
import { createVesselLayer } from '../layers/vessels/index.js';
import { createAisStreamSource } from '../sources/live/standalone.js';
import * as context from './contextStore.js';
import * as trails from './trailRenderer.js';
import * as labels from './detectionDraw.js';
import * as picking from './pickRegistry.js';
import * as overlay from '../overlays/worldOverlay.js';
import * as geoid from './geoid.js';
import * as sprites from './spriteOrder.js';
import * as focus from './focusDeemphasis.js';
import * as worldFocus from '../worldFocus.js';
import * as render from '../renderGovernor.js';
import { createApplicationVessels } from '../app/layers/aisLiveVessels.js';
const aisLiveVesselsLayer = createVesselLayer({
import { createAisStreamSource } from '../sources/live/standalone.js';
const aisLiveVesselsLayer = createApplicationVessels({
source: createAisStreamSource({
apiUrl: import.meta.env?.VITE_AIS_LIVE_API_URL || '/api/ais-live',
}),
@@ -19,18 +10,6 @@ const aisLiveVesselsLayer = createVesselLayer({
maxRows: import.meta.env?.VITE_AIS_LIVE_MAX_ROWS,
maxLabels: import.meta.env?.VITE_AIS_LIVE_LABEL_MAX_ROWS,
},
services: {
context,
trails,
labels,
picking,
overlay,
geoid,
sprites,
focus,
worldFocus,
render,
},
});
export { AIS_FIRST_CONNECT_GRACE_MS } from '../layers/vessels/policy.js';
export const deriveAisFeedError = aisLiveVesselsLayer.deriveAisFeedError;
+3 -10
View File
@@ -1,12 +1,6 @@
import { createApplicationAlpr } from '../app/layers/alprCameras.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import {
createAlprCamerasLayer,
createOverpassAlprSource,
} from '../layers/alpr/index.js';
import * as render from '../renderGovernor.js';
import * as context from './contextStore.js';
import * as picking from './pickRegistry.js';
import * as groundFloor from './groundFloor.js';
import { createOverpassAlprSource } from '../layers/alpr/index.js';
export * from '../layers/alpr/index.js';
const slot = createSourceSlot(
createOverpassAlprSource(),
@@ -14,7 +8,6 @@ const slot = createSourceSlot(
'ALPR source',
);
export const configureAlprSource = slot.configure;
export default createAlprCamerasLayer({
export default createApplicationAlpr({
source: slot.source,
services: { render, context, picking, groundFloor },
});
+2 -7
View File
@@ -1,10 +1,6 @@
import { createApplicationBikeshare } from '../app/layers/bikeshare.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import { createBikeshareSource } from '../layers/bikeshare/source.js';
import { createBikeshareLayer } from '../layers/bikeshare/index.js';
import * as render from '../renderGovernor.js';
import * as sprites from './spriteOrder.js';
import * as picking from './pickRegistry.js';
import * as overlays from '../overlays/worldOverlay.js';
const sourceSlot = createSourceSlot(
createBikeshareSource(),
@@ -12,9 +8,8 @@ const sourceSlot = createSourceSlot(
'Bikeshare source',
);
export const configureBikeshareSource = sourceSlot.configure;
const layer = createBikeshareLayer({
const layer = createApplicationBikeshare({
source: sourceSlot.source,
services: { render, sprites, picking, overlays },
});
export const createBikeshareSelectedOverlayEntry =
layer.createBikeshareSelectedOverlayEntry;
+2 -24
View File
@@ -1,16 +1,6 @@
import { createApplicationCctv } from '../app/layers/cctv.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import { createCctvSource } from '../layers/cctv/source.js';
import { createCctvLayer } from '../layers/cctv/index.js';
import * as sprites from './spriteOrder.js';
import * as activation from '../cctvFocusRequest.js';
import * as overlays from '../overlays/worldOverlay.js';
import * as locations from '../locations.js';
import * as picking from './pickRegistry.js';
import * as terrain from './terrainHeights.js';
import * as ground from './groundFloor.js';
import * as mesh from './meshFloorSampler.js';
import * as focus from './focusDeemphasis.js';
import * as render from '../renderGovernor.js';
const sourceSlot = createSourceSlot(
createCctvSource(),
@@ -18,20 +8,8 @@ const sourceSlot = createSourceSlot(
'Cctv source',
);
export const configureCctvSource = sourceSlot.configure;
const layer = createCctvLayer({
const layer = createApplicationCctv({
source: sourceSlot.source,
services: {
sprites,
activation,
overlays,
locations,
picking,
terrain,
ground,
mesh,
focus,
render,
},
});
export const calibrationPatchMovesAnchor = layer.calibrationPatchMovesAnchor;
export const migrateRangeScaleForFloor = layer.migrateRangeScaleForFloor;
+4 -15
View File
@@ -1,22 +1,11 @@
import {
createEarthquakesLayer as createLayer,
createUsgsEarthquakeSource,
} from '../layers/earthquakes/index.js';
import {
clearOverlaySource,
setOverlayEntries,
setOverlaySourceVisible,
} from '../overlays/worldOverlay.js';
import { createUsgsEarthquakeSource } from '../layers/earthquakes/index.js';
import { createApplicationEarthquakes } from '../app/layers/earthquakes.js';
export * from '../layers/earthquakes/index.js';
/** Wire the standalone source and application overlay owner. */
export function createEarthquakesLayer({
source = createUsgsEarthquakeSource(),
overlayHost = {
setEntries: setOverlayEntries,
setVisible: setOverlaySourceVisible,
clearSource: clearOverlaySource,
},
...options
} = {}) {
return createLayer({ source, overlayHost });
return createApplicationEarthquakes({ source, ...options });
}
export default createEarthquakesLayer();
+4 -33
View File
@@ -1,33 +1,16 @@
import { createApplicationFirms, firmsServices } from '../app/layers/firms.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import * as Cesium from 'cesium';
import {
createFirmsHeatmapLayer as createLayer,
createFirmsHelpers,
createFirmsSource,
} from '../layers/firms/index.js';
import * as render from '../renderGovernor.js';
import * as sprites from './spriteOrder.js';
import * as context from './contextStore.js';
import * as picking from './pickRegistry.js';
import * as anchors from './fireAnchors.js';
import * as overlays from '../overlays/worldOverlay.js';
import * as focus from '../worldFocus.js';
const services = {
render,
sprites,
context,
picking,
anchors,
overlays,
focus,
};
const sourceSlot = createSourceSlot(
createFirmsSource(),
['getSnapshot'],
'Fire source',
);
export const configureFirmsSource = sourceSlot.configure;
const helpers = createFirmsHelpers({ services });
const helpers = createFirmsHelpers({ services: firmsServices });
export const mapAnalystRecord = helpers.mapAnalystRecord;
export const fireCullPosition = helpers.fireCullPosition;
export const applyHorizonCull = helpers.applyHorizonCull;
@@ -36,22 +19,10 @@ export const buildFireCard = helpers.buildFireCard;
export const buildCellCard = helpers.buildCellCard;
export const applyFirmsOverlayPolicy = helpers.applyFirmsOverlayPolicy;
/** Supply the local source and the application's scene service owners. */
/** Retain the existing default feed and helper exports for direct callers. */
export function createFirmsHeatmapLayer(options) {
return createLayer({
return createApplicationFirms({
...options,
icon: options.icon ?? '▲',
source: options.source ?? 'NASA FIRMS',
feed: options.feed ?? sourceSlot.source,
services,
overlayHost: options.overlayHost ?? {
setEntries: overlays.setOverlayEntries,
setVisible: overlays.setOverlaySourceVisible,
clearSource: overlays.clearOverlaySource,
hitTest: overlays.hitTestWorldOverlay,
},
screenSpaceEventHandlerFactory:
options.screenSpaceEventHandlerFactory ??
((viewer) => new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)),
});
}
+6 -39
View File
@@ -1,44 +1,11 @@
import { createCivilFlightLayer } from '../layers/flights/index.js';
import { createOpenSkySource } from '../sources/live/standalone.js';
import * as picking from './pickRegistry.js';
import * as sprites from './spriteOrder.js';
import * as trails from './trailRenderer.js';
import * as aircraftPresentation from './tr3bRegistry.js';
import * as camera from './trackedCamera.js';
import * as militaryRegistry from './militaryRegistry.js';
import * as labels from './detectionDraw.js';
import * as groundFloor from './groundFloor.js';
import * as meshFloor from './meshFloorSampler.js';
import * as geoid from './geoid.js';
import * as focus from './focusDeemphasis.js';
import * as readout from './trackedReadout.js';
import * as context from './contextStore.js';
import * as render from '../renderGovernor.js';
import * as groundSnap from './groundSnap.js';
import * as recession from './aircraftRecession.js';
import { createApplicationFlights } from '../app/layers/flights.js';
const flightsLayer = createCivilFlightLayer({
import { createOpenSkySource } from '../sources/live/standalone.js';
import * as militaryRegistry from './militaryRegistry.js';
const flightsLayer = createApplicationFlights({
source: createOpenSkySource(),
resolveAsset: (url) =>
`${import.meta.env?.BASE_URL || '/'}${url.replace(/^\//, '')}`,
services: {
picking,
sprites,
trails,
aircraftPresentation,
camera,
militaryRegistry,
labels,
groundFloor,
meshFloor,
geoid,
focus,
readout,
context,
render,
groundSnap,
recession,
},
militaryRegistry,
});
export { TRACKED_MODEL_MAX_PX } from '../layers/flights/policy.js';
export const _floorGroundedDisplayPositionForTest =
+6 -14
View File
@@ -1,22 +1,14 @@
import { createAwarenessLayer } from '../layers/awareness/index.js';
import { createApplicationAwareness } from '../app/layers/militaryAwareness.js';
import flights from './flights.js';
import military from './militaryFlights.js';
import vessels from './aisLiveVessels.js';
import installations from './militaryInstallations.js';
import * as navigation from '../navigationPolicy.js';
import * as geometry from '../celestialRing.js';
import * as render from '../renderGovernor.js';
const layer = createAwarenessLayer({
services: {
flights,
military,
vessels,
installations,
navigation,
geometry,
render,
},
const layer = createApplicationAwareness({
flights,
military,
vessels,
installations,
});
export const contextTargetFlyToAllowed = layer.contextTargetFlyToAllowed;
export const awarenessClearMatchesSubject = layer.awarenessClearMatchesSubject;
+6 -39
View File
@@ -1,44 +1,11 @@
import { createMilitaryFlightLayer } from '../layers/military/index.js';
import { createAdsbLolSource } from '../sources/live/standalone.js';
import * as picking from './pickRegistry.js';
import * as sprites from './spriteOrder.js';
import * as trails from './trailRenderer.js';
import * as aircraftPresentation from './tr3bRegistry.js';
import * as camera from './trackedCamera.js';
import * as militaryRegistry from './militaryRegistry.js';
import * as labels from './detectionDraw.js';
import * as groundFloor from './groundFloor.js';
import * as meshFloor from './meshFloorSampler.js';
import * as geoid from './geoid.js';
import * as focus from './focusDeemphasis.js';
import * as readout from './trackedReadout.js';
import * as context from './contextStore.js';
import * as render from '../renderGovernor.js';
import * as groundSnap from './groundSnap.js';
import * as recession from './aircraftRecession.js';
import { createApplicationMilitary } from '../app/layers/militaryFlights.js';
const militaryFlightsLayer = createMilitaryFlightLayer({
import { createAdsbLolSource } from '../sources/live/standalone.js';
import * as militaryRegistry from './militaryRegistry.js';
const militaryFlightsLayer = createApplicationMilitary({
source: createAdsbLolSource(),
resolveAsset: (url) =>
`${import.meta.env?.BASE_URL || '/'}${url.replace(/^\//, '')}`,
services: {
picking,
sprites,
trails,
aircraftPresentation,
camera,
militaryRegistry,
labels,
groundFloor,
meshFloor,
geoid,
focus,
readout,
context,
render,
groundSnap,
recession,
},
militaryRegistry,
});
export { TRACKED_MODEL_MAX_PX } from '../layers/military/policy.js';
export const _setTrackedMilitaryRefreshStateForTest =
+3 -11
View File
@@ -1,13 +1,6 @@
import { createApplicationInstallations } from '../app/layers/militaryInstallations.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import {
createInstallationsLayer,
createInstallationSource,
} from '../layers/installations/index.js';
import * as render from '../renderGovernor.js';
import * as context from './contextStore.js';
import * as ground from './groundFloor.js';
import * as anchors from './fireAnchors.js';
import * as picking from './pickRegistry.js';
import { createInstallationSource } from '../layers/installations/index.js';
const sourceSlot = createSourceSlot(
createInstallationSource(),
@@ -15,9 +8,8 @@ const sourceSlot = createSourceSlot(
'Installation source',
);
export const configureInstallationSource = sourceSlot.configure;
const layer = createInstallationsLayer({
const layer = createApplicationInstallations({
source: sourceSlot.source,
services: { render, context, ground, anchors, picking },
});
export const approximateSurfaceDistanceM = layer.approximateSurfaceDistanceM;
export const classifyGoogleMilitaryPlace = layer.classifyGoogleMilitaryPlace;
+2 -8
View File
@@ -1,11 +1,6 @@
import { createApplicationRadio } from '../app/layers/radio.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import { createRadioSource } from '../layers/radio/source.js';
import { createRadioLayer } from '../layers/radio/index.js';
import * as ground from './groundFloor.js';
import * as picking from './pickRegistry.js';
import * as overlays from '../overlays/worldOverlay.js';
import * as globe from '../celestialRing.js';
import * as render from '../renderGovernor.js';
const sourceSlot = createSourceSlot(
createRadioSource(),
@@ -13,9 +8,8 @@ const sourceSlot = createSourceSlot(
'Radio source',
);
export const configureRadioSource = sourceSlot.configure;
const layer = createRadioLayer({
const layer = createApplicationRadio({
source: sourceSlot.source,
services: { ground, picking, overlays, globe, render },
});
export const radioGlobeLabel = layer.radioGlobeLabel;
export const createRadioSelectedOverlayEntry =
+4 -9
View File
@@ -1,12 +1,7 @@
import { createApplicationLaunches } from '../app/layers/rocketLaunches.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import {
createRocketLaunchesLayer,
createLaunchSource,
} from '../layers/launches/index.js';
import { createLaunchSource } from '../layers/launches/index.js';
import * as satellites from './satellites.js';
import * as geometry from '../celestialRing.js';
import * as overlays from '../overlays/worldOverlay.js';
import * as render from '../renderGovernor.js';
const sourceSlot = createSourceSlot(
createLaunchSource(),
@@ -14,9 +9,9 @@ const sourceSlot = createSourceSlot(
'Launch source',
);
export const configureLaunchSource = sourceSlot.configure;
const layer = createRocketLaunchesLayer({
const layer = createApplicationLaunches({
source: sourceSlot.source,
services: { satellites, geometry, overlays, render },
satellites,
});
export const satelliteParamsForSpaceMissions =
layer.satelliteParamsForSpaceMissions;
+3 -13
View File
@@ -1,15 +1,6 @@
import { createApplicationSatellites } from '../app/layers/satellites.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import {
createSatellitesLayer,
createSatelliteSource,
} from '../layers/satellites/index.js';
import * as picking from './pickRegistry.js';
import * as focus from './focusDeemphasis.js';
import * as readout from './trackedReadout.js';
import * as overlays from '../overlays/worldOverlay.js';
import * as context from './contextStore.js';
import * as render from '../renderGovernor.js';
import * as layerState from './layerState.js';
import { createSatelliteSource } from '../layers/satellites/index.js';
const sourceSlot = createSourceSlot(
createSatelliteSource(),
@@ -17,9 +8,8 @@ const sourceSlot = createSourceSlot(
'Satellite source',
);
export const configureSatelliteSource = sourceSlot.configure;
const layer = createSatellitesLayer({
const layer = createApplicationSatellites({
source: sourceSlot.source,
services: { picking, focus, readout, overlays, context, render, layerState },
});
export const satelliteVisualsVisible = layer.satelliteVisualsVisible;
export const satelliteCatalogModeChanged = layer.satelliteCatalogModeChanged;
+4 -20
View File
@@ -1,26 +1,10 @@
import * as Cesium from 'cesium';
import {
createSubmarineCableLayer,
createCableOverlayPublisher as createPublisher,
} from '../layers/submarineCables/index.js';
import { createApplicationCables } from '../app/layers/submarineCables.js';
import { overlayHost } from '../app/layers/overlayHost.js';
import { createCableOverlayPublisher as createPublisher } from '../layers/submarineCables/index.js';
import { createBundledCableSource } from '../layers/submarineCables/bundledSource.js';
import {
clearOverlaySource,
setOverlayEntries,
setOverlaySourceVisible,
} from '../overlays/worldOverlay.js';
const overlayHost = Object.freeze({
clearSource: clearOverlaySource,
setEntries: setOverlayEntries,
setVisible: setOverlaySourceVisible,
});
export function createTeleGeographySubmarineCableLayer(options = {}) {
return createSubmarineCableLayer({
return createApplicationCables({
source: createBundledCableSource(),
overlayHost,
screenSpaceEventHandlerFactory: (canvas) =>
new Cesium.ScreenSpaceEventHandler(canvas),
mapStackEventTarget: typeof window !== 'undefined' ? window : null,
...options,
});
}
@@ -631,6 +631,8 @@ test('the depth decision is the dated Option-2 host migration, superseding Optio
test('cables create no native labels and no per-frame geometry callbacks', () => {
const source = [
'../../data/telegeographySubmarineCables.js',
'../../app/layers/submarineCables.js',
'../../app/layers/overlayHost.js',
'rendering.js',
'overlay.js',
'surface.js',
+2 -5
View File
@@ -1,8 +1,6 @@
import { createApplicationTraffic } from '../app/layers/traffic.js';
import { createSourceSlot } from '../app/sourceSlot.js';
import { createTrafficSource } from '../layers/traffic/source.js';
import { createTrafficLayer } from '../layers/traffic/index.js';
import * as credits from './dataCredits.js';
import * as render from '../renderGovernor.js';
const sourceSlot = createSourceSlot(
createTrafficSource(),
@@ -14,9 +12,8 @@ const sourceSlot = createSourceSlot(
},
);
export const configureTrafficSource = sourceSlot.configure;
const layer = createTrafficLayer({
const layer = createApplicationTraffic({
source: sourceSlot.source,
services: { credits, render },
});
export const getTrafficTimingDiagnostics = layer.getTrafficTimingDiagnostics;
export const deriveTrafficFlowError = layer.deriveTrafficFlowError;