mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 19:04:02 +00:00
refactor: construct application layers from supplied sources
This commit is contained in:
1 parent
cd704d0e9b
commit
8160ac5fe4
53 files changed
+1152
-400
No files matched your search
@@ -0,0 +1,130 @@
|
||||
import { createLayerCatalog } from './catalog.js';
|
||||
import { LAYER_STATE_REGISTRY } from '../data/layerState.js';
|
||||
import { createMilitaryRegistry } from '../layers/aircraft/classification.js';
|
||||
import { createApplicationFlights } from './layers/flights.js';
|
||||
import { createApplicationMilitary } from './layers/militaryFlights.js';
|
||||
import { createApplicationVessels } from './layers/aisLiveVessels.js';
|
||||
import { createApplicationCctv } from './layers/cctv.js';
|
||||
import { createApplicationRadio } from './layers/radio.js';
|
||||
import { createApplicationTraffic } from './layers/traffic.js';
|
||||
import { createApplicationBikeshare } from './layers/bikeshare.js';
|
||||
import { createApplicationInstallations } from './layers/militaryInstallations.js';
|
||||
import { createApplicationSatellites } from './layers/satellites.js';
|
||||
import { createApplicationLaunches } from './layers/rocketLaunches.js';
|
||||
import { createApplicationAlpr } from './layers/alprCameras.js';
|
||||
import { createApplicationAwareness } from './layers/militaryAwareness.js';
|
||||
import { createApplicationFirms } from './layers/firms.js';
|
||||
import { createApplicationEarthquakes } from './layers/earthquakes.js';
|
||||
import { createApplicationCables } from './layers/submarineCables.js';
|
||||
import { createInfrastructureLayers } from '../data/infrastructure.js';
|
||||
import { localGeoJsonServices } from '../data/localGeojson.js';
|
||||
|
||||
const SOURCE_METHODS = Object.freeze({
|
||||
flights: ['getSnapshot'],
|
||||
military: ['getSnapshot'],
|
||||
vessels: ['getSnapshot'],
|
||||
cctv: ['getCatalog', 'getHealth', 'getFrameUrl', 'getMediaUrl'],
|
||||
radio: ['getDirectory', 'recordClick'],
|
||||
traffic: [
|
||||
'requestRoads',
|
||||
'getStatus',
|
||||
'fetchFlowForBounds',
|
||||
'getFlowSessionStats',
|
||||
'resetFlowTileCache',
|
||||
],
|
||||
bikeshare: ['getStations'],
|
||||
installations: ['getMappedSites', 'searchNearby'],
|
||||
satellites: ['readGroup'],
|
||||
launches: ['getLaunches', 'getActiveTle'],
|
||||
alpr: ['fetch'],
|
||||
firms: ['getSnapshot'],
|
||||
earthquakes: ['getSnapshot'],
|
||||
cables: ['fetch'],
|
||||
});
|
||||
|
||||
/** Construct the current catalog without choosing any source provider.
|
||||
* Scene engines remain page-owned; layers and classification have this app's lifetime.
|
||||
* The manager owns layer destruction, while abort releases classification even if startup fails.
|
||||
*/
|
||||
export function createApplicationCatalog({
|
||||
sources,
|
||||
signal,
|
||||
metadata = LAYER_STATE_REGISTRY,
|
||||
vesselOptions,
|
||||
resolveAsset,
|
||||
}) {
|
||||
if (!signal?.addEventListener)
|
||||
throw new TypeError('An application lifetime signal is required');
|
||||
signal.throwIfAborted();
|
||||
for (const [name, methods] of Object.entries(SOURCE_METHODS)) {
|
||||
if (
|
||||
methods.some((method) => typeof sources?.[name]?.[method] !== 'function')
|
||||
)
|
||||
throw new TypeError(`Invalid catalog source: ${name}`);
|
||||
}
|
||||
const militaryRegistry = createMilitaryRegistry();
|
||||
const dispose = () => {
|
||||
signal.removeEventListener('abort', dispose);
|
||||
militaryRegistry.dispose();
|
||||
};
|
||||
signal.addEventListener('abort', dispose, { once: true });
|
||||
try {
|
||||
militaryRegistry.configureSource(sources.military, { signal });
|
||||
const flights = createApplicationFlights({
|
||||
source: sources.flights,
|
||||
militaryRegistry,
|
||||
resolveAsset,
|
||||
});
|
||||
const military = createApplicationMilitary({
|
||||
source: sources.military,
|
||||
militaryRegistry,
|
||||
resolveAsset,
|
||||
});
|
||||
const vessels = createApplicationVessels({
|
||||
source: sources.vessels,
|
||||
options: vesselOptions,
|
||||
});
|
||||
const installations = createApplicationInstallations({
|
||||
source: sources.installations,
|
||||
});
|
||||
const satellites = createApplicationSatellites({
|
||||
source: sources.satellites,
|
||||
});
|
||||
const catalog = createLayerCatalog(
|
||||
[
|
||||
flights,
|
||||
military,
|
||||
createApplicationEarthquakes({ source: sources.earthquakes }),
|
||||
createApplicationAlpr({ source: sources.alpr }),
|
||||
satellites,
|
||||
createApplicationLaunches({ source: sources.launches, satellites }),
|
||||
createApplicationTraffic({ source: sources.traffic }),
|
||||
createApplicationCctv({ source: sources.cctv }),
|
||||
createApplicationRadio({ source: sources.radio }),
|
||||
createApplicationBikeshare({ source: sources.bikeshare }),
|
||||
vessels,
|
||||
installations,
|
||||
createApplicationAwareness({
|
||||
flights,
|
||||
military,
|
||||
vessels,
|
||||
installations,
|
||||
}),
|
||||
...createInfrastructureLayers(localGeoJsonServices),
|
||||
createApplicationCables({ source: sources.cables }),
|
||||
createApplicationFirms({
|
||||
id: 'local-firms',
|
||||
name: 'FIRMS Active Fires',
|
||||
icon: '▲',
|
||||
source: 'NASA FIRMS · LIVE',
|
||||
feed: sources.firms,
|
||||
}),
|
||||
],
|
||||
metadata,
|
||||
);
|
||||
return Object.freeze({ ...catalog, militaryRegistry });
|
||||
} catch (error) {
|
||||
dispose();
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { createApplicationCatalog } from './constructCatalog.js';
|
||||
import { createStandaloneLayerSources } from '../standalone/layerSources.js';
|
||||
import { catalogControlServices } from './catalog.js';
|
||||
|
||||
function fixtureSources(ids, calls) {
|
||||
const sources = createStandaloneLayerSources();
|
||||
sources.military = {
|
||||
getSnapshot: async () => {
|
||||
throw new Error('Use identity acquisition');
|
||||
},
|
||||
async getIdentities(_query, { signal }) {
|
||||
calls.push(signal);
|
||||
return ids;
|
||||
},
|
||||
};
|
||||
return sources;
|
||||
}
|
||||
|
||||
test('catalogs construct distinct layers and classification from their supplied source', async (t) => {
|
||||
const a = new AbortController();
|
||||
const b = new AbortController();
|
||||
t.after(() => {
|
||||
a.abort();
|
||||
b.abort();
|
||||
});
|
||||
const callsA = [];
|
||||
const callsB = [];
|
||||
const first = createApplicationCatalog({
|
||||
sources: fixtureSources(['abc123'], callsA),
|
||||
signal: a.signal,
|
||||
});
|
||||
const second = createApplicationCatalog({
|
||||
sources: fixtureSources(['def456'], callsB),
|
||||
signal: b.signal,
|
||||
});
|
||||
assert.equal(first.layers.length, 17);
|
||||
assert.deepEqual(
|
||||
first.layers.map(({ id }) => id),
|
||||
second.layers.map(({ id }) => id),
|
||||
);
|
||||
for (const layer of first.layers)
|
||||
assert.notEqual(layer, second.get(layer.id));
|
||||
assert.equal(
|
||||
catalogControlServices(first).satellitesLayer,
|
||||
first.get('satellites'),
|
||||
);
|
||||
assert.equal(callsA.length, 0, 'construction must not acquire');
|
||||
await first.militaryRegistry.refreshMilitaryRegistryIfStale();
|
||||
await second.militaryRegistry.refreshMilitaryRegistryIfStale();
|
||||
assert.equal(first.militaryRegistry.isMilitaryIcao('abc123'), true);
|
||||
assert.equal(first.militaryRegistry.isMilitaryIcao('def456'), false);
|
||||
assert.equal(second.militaryRegistry.isMilitaryIcao('def456'), true);
|
||||
a.abort();
|
||||
assert.equal(callsA[0].aborted, true);
|
||||
assert.equal(first.militaryRegistry.isMilitaryIcao('abc123'), false);
|
||||
assert.equal(callsB[0].aborted, false);
|
||||
assert.equal(second.militaryRegistry.isMilitaryIcao('def456'), true);
|
||||
});
|
||||
|
||||
test('invalid or already cancelled construction fails before classification can acquire', () => {
|
||||
const lifetime = new AbortController();
|
||||
assert.throws(
|
||||
() => createApplicationCatalog({ sources: {}, signal: lifetime.signal }),
|
||||
/catalog source/,
|
||||
);
|
||||
lifetime.abort();
|
||||
assert.throws(
|
||||
() =>
|
||||
createApplicationCatalog({
|
||||
sources: createStandaloneLayerSources(),
|
||||
signal: lifetime.signal,
|
||||
}),
|
||||
{ name: 'AbortError' },
|
||||
);
|
||||
});
|
||||
+1
-1
@@ -49,5 +49,5 @@ export function createApplicationData({
|
||||
dataManager.buildTogglePanel(document.getElementById('data-toggles'));
|
||||
styleManager.attachDataManager(dataManager);
|
||||
|
||||
return { dataManager };
|
||||
return { dataManager, catalog };
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { createVesselLayer } from '../../layers/vessels/index.js';
|
||||
import * as context from '../../data/contextStore.js';
|
||||
import * as trails from '../../data/trailRenderer.js';
|
||||
import * as labels from '../../data/detectionDraw.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
import * as overlay from '../../overlays/worldOverlay.js';
|
||||
import * as geoid from '../../data/geoid.js';
|
||||
import * as sprites from '../../data/spriteOrder.js';
|
||||
import * as focus from '../../data/focusDeemphasis.js';
|
||||
import * as worldFocus from '../../worldFocus.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationVessels({ source, options = {} }) {
|
||||
return createVesselLayer({
|
||||
source,
|
||||
options,
|
||||
services: {
|
||||
context,
|
||||
trails,
|
||||
labels,
|
||||
picking,
|
||||
overlay,
|
||||
geoid,
|
||||
sprites,
|
||||
focus,
|
||||
worldFocus,
|
||||
render,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { createAlprCamerasLayer } from '../../layers/alpr/index.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
import * as context from '../../data/contextStore.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
import * as groundFloor from '../../data/groundFloor.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationAlpr({ source }) {
|
||||
return createAlprCamerasLayer({
|
||||
source,
|
||||
services: { render, context, picking, groundFloor },
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { createBikeshareLayer } from '../../layers/bikeshare/index.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
import * as sprites from '../../data/spriteOrder.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
import * as overlays from '../../overlays/worldOverlay.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationBikeshare({ source }) {
|
||||
return createBikeshareLayer({
|
||||
source,
|
||||
services: { render, sprites, picking, overlays },
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { createCctvLayer } from '../../layers/cctv/index.js';
|
||||
import * as sprites from '../../data/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 '../../data/pickRegistry.js';
|
||||
import * as terrain from '../../data/terrainHeights.js';
|
||||
import * as ground from '../../data/groundFloor.js';
|
||||
import * as mesh from '../../data/meshFloorSampler.js';
|
||||
import * as focus from '../../data/focusDeemphasis.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationCctv({ source }) {
|
||||
return createCctvLayer({
|
||||
source,
|
||||
services: {
|
||||
sprites,
|
||||
activation,
|
||||
overlays,
|
||||
locations,
|
||||
picking,
|
||||
terrain,
|
||||
ground,
|
||||
mesh,
|
||||
focus,
|
||||
render,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { createEarthquakesLayer } from '../../layers/earthquakes/index.js';
|
||||
import { overlayHost } from './overlayHost.js';
|
||||
/** Wire earthquake observations to the application overlay host. */
|
||||
export function createApplicationEarthquakes(options) {
|
||||
return createEarthquakesLayer({ overlayHost, ...options });
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import * as Cesium from 'cesium';
|
||||
import { createFirmsHeatmapLayer as createLayer } from '../../layers/firms/index.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
import * as sprites from '../../data/spriteOrder.js';
|
||||
import * as context from '../../data/contextStore.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
import * as anchors from '../../data/fireAnchors.js';
|
||||
import * as overlays from '../../overlays/worldOverlay.js';
|
||||
import * as focus from '../../worldFocus.js';
|
||||
export const firmsServices = {
|
||||
render,
|
||||
sprites,
|
||||
context,
|
||||
picking,
|
||||
anchors,
|
||||
overlays,
|
||||
focus,
|
||||
};
|
||||
|
||||
/** Bind a supplied fire feed to the application scene service owners. */
|
||||
export function createApplicationFirms(options) {
|
||||
return createLayer({
|
||||
...options,
|
||||
icon: options.icon ?? '▲',
|
||||
source: options.source ?? 'NASA FIRMS',
|
||||
feed: options.feed,
|
||||
services: firmsServices,
|
||||
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)),
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { createCivilFlightLayer } from '../../layers/flights/index.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
import * as sprites from '../../data/spriteOrder.js';
|
||||
import * as trails from '../../data/trailRenderer.js';
|
||||
import * as aircraftPresentation from '../../data/tr3bRegistry.js';
|
||||
import * as camera from '../../data/trackedCamera.js';
|
||||
import * as labels from '../../data/detectionDraw.js';
|
||||
import * as groundFloor from '../../data/groundFloor.js';
|
||||
import * as meshFloor from '../../data/meshFloorSampler.js';
|
||||
import * as geoid from '../../data/geoid.js';
|
||||
import * as focus from '../../data/focusDeemphasis.js';
|
||||
import * as readout from '../../data/trackedReadout.js';
|
||||
import * as context from '../../data/contextStore.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
import * as groundSnap from '../../data/groundSnap.js';
|
||||
import * as recession from '../../data/aircraftRecession.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationFlights({
|
||||
source,
|
||||
militaryRegistry,
|
||||
resolveAsset = (url) =>
|
||||
`${import.meta.env?.BASE_URL || '/'}${url.replace(/^\//, '')}`,
|
||||
}) {
|
||||
return createCivilFlightLayer({
|
||||
source,
|
||||
resolveAsset,
|
||||
services: {
|
||||
picking,
|
||||
sprites,
|
||||
trails,
|
||||
aircraftPresentation,
|
||||
camera,
|
||||
militaryRegistry,
|
||||
labels,
|
||||
groundFloor,
|
||||
meshFloor,
|
||||
geoid,
|
||||
focus,
|
||||
readout,
|
||||
context,
|
||||
render,
|
||||
groundSnap,
|
||||
recession,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { createAwarenessLayer } from '../../layers/awareness/index.js';
|
||||
import * as navigation from '../../navigationPolicy.js';
|
||||
import * as geometry from '../../celestialRing.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
/** Bind Contacts to the same catalog instances used for rendering. */
|
||||
export function createApplicationAwareness({
|
||||
flights,
|
||||
military,
|
||||
vessels,
|
||||
installations,
|
||||
}) {
|
||||
return createAwarenessLayer({
|
||||
services: {
|
||||
flights,
|
||||
military,
|
||||
vessels,
|
||||
installations,
|
||||
navigation,
|
||||
geometry,
|
||||
render,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import { createMilitaryFlightLayer } from '../../layers/military/index.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
import * as sprites from '../../data/spriteOrder.js';
|
||||
import * as trails from '../../data/trailRenderer.js';
|
||||
import * as aircraftPresentation from '../../data/tr3bRegistry.js';
|
||||
import * as camera from '../../data/trackedCamera.js';
|
||||
import * as labels from '../../data/detectionDraw.js';
|
||||
import * as groundFloor from '../../data/groundFloor.js';
|
||||
import * as meshFloor from '../../data/meshFloorSampler.js';
|
||||
import * as geoid from '../../data/geoid.js';
|
||||
import * as focus from '../../data/focusDeemphasis.js';
|
||||
import * as readout from '../../data/trackedReadout.js';
|
||||
import * as context from '../../data/contextStore.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
import * as groundSnap from '../../data/groundSnap.js';
|
||||
import * as recession from '../../data/aircraftRecession.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationMilitary({
|
||||
source,
|
||||
militaryRegistry,
|
||||
resolveAsset = (url) =>
|
||||
`${import.meta.env?.BASE_URL || '/'}${url.replace(/^\//, '')}`,
|
||||
}) {
|
||||
return createMilitaryFlightLayer({
|
||||
source,
|
||||
resolveAsset,
|
||||
services: {
|
||||
picking,
|
||||
sprites,
|
||||
trails,
|
||||
aircraftPresentation,
|
||||
camera,
|
||||
militaryRegistry,
|
||||
labels,
|
||||
groundFloor,
|
||||
meshFloor,
|
||||
geoid,
|
||||
focus,
|
||||
readout,
|
||||
context,
|
||||
render,
|
||||
groundSnap,
|
||||
recession,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { createInstallationsLayer } from '../../layers/installations/index.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
import * as context from '../../data/contextStore.js';
|
||||
import * as ground from '../../data/groundFloor.js';
|
||||
import * as anchors from '../../data/fireAnchors.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationInstallations({ source }) {
|
||||
return createInstallationsLayer({
|
||||
source,
|
||||
services: { render, context, ground, anchors, picking },
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import {
|
||||
clearOverlaySource,
|
||||
setOverlayEntries,
|
||||
setOverlaySourceVisible,
|
||||
} from '../../overlays/worldOverlay.js';
|
||||
export const overlayHost = Object.freeze({
|
||||
clearSource: clearOverlaySource,
|
||||
setEntries: setOverlayEntries,
|
||||
setVisible: setOverlaySourceVisible,
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { createRadioLayer } from '../../layers/radio/index.js';
|
||||
import * as ground from '../../data/groundFloor.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
import * as overlays from '../../overlays/worldOverlay.js';
|
||||
import * as globe from '../../celestialRing.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationRadio({ source }) {
|
||||
return createRadioLayer({
|
||||
source,
|
||||
services: { ground, picking, overlays, globe, render },
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { createRocketLaunchesLayer } from '../../layers/launches/index.js';
|
||||
import * as geometry from '../../celestialRing.js';
|
||||
import * as overlays from '../../overlays/worldOverlay.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationLaunches({ source, satellites }) {
|
||||
return createRocketLaunchesLayer({
|
||||
source,
|
||||
services: { satellites, geometry, overlays, render },
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { createSatellitesLayer } from '../../layers/satellites/index.js';
|
||||
import * as picking from '../../data/pickRegistry.js';
|
||||
import * as focus from '../../data/focusDeemphasis.js';
|
||||
import * as readout from '../../data/trackedReadout.js';
|
||||
import * as overlays from '../../overlays/worldOverlay.js';
|
||||
import * as context from '../../data/contextStore.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
import * as layerState from '../../data/layerState.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationSatellites({ source }) {
|
||||
return createSatellitesLayer({
|
||||
source,
|
||||
services: {
|
||||
picking,
|
||||
focus,
|
||||
readout,
|
||||
overlays,
|
||||
context,
|
||||
render,
|
||||
layerState,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import * as Cesium from 'cesium';
|
||||
import { createSubmarineCableLayer } from '../../layers/submarineCables/index.js';
|
||||
import { overlayHost } from './overlayHost.js';
|
||||
/** Wire cable source geometry to the application overlay host. */
|
||||
export function createApplicationCables(options) {
|
||||
return createSubmarineCableLayer({
|
||||
overlayHost,
|
||||
screenSpaceEventHandlerFactory: (canvas) =>
|
||||
new Cesium.ScreenSpaceEventHandler(canvas),
|
||||
mapStackEventTarget: typeof window !== 'undefined' ? window : null,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { createTrafficLayer } from '../../layers/traffic/index.js';
|
||||
import * as credits from '../../data/dataCredits.js';
|
||||
import * as render from '../../renderGovernor.js';
|
||||
|
||||
/** Construct one layer using the application scene owners and a supplied source. */
|
||||
export function createApplicationTraffic({ source }) {
|
||||
return createTrafficLayer({
|
||||
source,
|
||||
services: { credits, render },
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user