mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Port to current main: main reserved layer-state token 0 for street-level, so air-quality takes the next free token, 4 (registry, ledger, and the allocation tests shift by one). Main moved source contracts into sourceComposition.js, so air-quality registers its getSnapshot contract there. Package boundaries keep main's lists plus this branch's air-quality modules and packages.
196 lines
7.5 KiB
JavaScript
196 lines
7.5 KiB
JavaScript
import { resolveCatalogSources } from './sourceComposition.js';
|
|
import { createWeatherClock } from '../layers/weather/clock.js';
|
|
import { createWeatherLayer } from '../layers/weather/index.js';
|
|
import { createCyclonesLayer } from '../layers/cyclones/index.js';
|
|
import { createWindLayer } from '../layers/wind/index.js';
|
|
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 { createApplicationDirections } from './layers/directions.js';
|
|
import { createApplicationRecentImagery } from './layers/recentImagery.js';
|
|
import { createApplicationTransit } from './layers/transit.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 { createApplicationLocalAdsb } from './layers/localAdsb.js';
|
|
import { createApplicationAwareness } from './layers/militaryAwareness.js';
|
|
import { createApplicationFirms } from './layers/firms.js';
|
|
import { createApplicationEarthquakes } from './layers/earthquakes.js';
|
|
import { createApplicationAirQuality } from './layers/airQuality.js';
|
|
import { createApplicationFirePerimeters } from './layers/perimeters.js';
|
|
import { createApplicationGnssIntegrity } from './layers/gnss.js';
|
|
import { createApplicationCables } from './layers/submarineCables.js';
|
|
import { createApplicationStreetLevel } from './layers/streetLevel.js';
|
|
import { createInfrastructureLayers } from '../data/infrastructure.js';
|
|
import { localGeoJsonServices } from './localGeojsonServices.js';
|
|
import { createBhoteKoshiEventLayer } from '../data/bhoteKoshiEvent.js';
|
|
import { createBhoteKoshiLocatorLayer } from '../data/bhoteKoshiLocator.js';
|
|
|
|
/**
|
|
* Hardware-local layers are registered like any other but never enter share
|
|
* links or stored layer state: another browser cannot have this receiver.
|
|
*/
|
|
export const LOCAL_ONLY_LAYER_METADATA = Object.freeze([
|
|
Object.freeze({ id: 'local-adsb', disposition: 'local-only' }),
|
|
]);
|
|
|
|
/** Serialization metadata for every layer the application catalog constructs. */
|
|
export const APPLICATION_LAYER_METADATA = Object.freeze([
|
|
...LAYER_STATE_REGISTRY,
|
|
...LOCAL_ONLY_LAYER_METADATA,
|
|
]);
|
|
|
|
/** 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({
|
|
surface,
|
|
sources,
|
|
signal,
|
|
metadata = APPLICATION_LAYER_METADATA,
|
|
vesselOptions,
|
|
resolveAsset,
|
|
nepalBoundaryResolver,
|
|
streetLevelProviders,
|
|
}) {
|
|
if (!signal?.addEventListener)
|
|
throw new TypeError('An application lifetime signal is required');
|
|
signal.throwIfAborted();
|
|
if (!surface?.groundFloor || !surface?.terrain)
|
|
throw new TypeError('Application surface services are required');
|
|
|
|
const sourceComposition = resolveCatalogSources(sources);
|
|
sources = sourceComposition.sources;
|
|
const militaryRegistry = createMilitaryRegistry();
|
|
const weatherClock = createWeatherClock();
|
|
const dispose = () => {
|
|
signal.removeEventListener('abort', dispose);
|
|
militaryRegistry.dispose();
|
|
weatherClock.destroy();
|
|
};
|
|
signal.addEventListener('abort', dispose, { once: true });
|
|
try {
|
|
if (sourceComposition.isConfigured('military'))
|
|
militaryRegistry.configureSource(sources.military, { signal });
|
|
const flights = createApplicationFlights({
|
|
surface,
|
|
source: sources.flights,
|
|
militaryRegistry,
|
|
resolveAsset,
|
|
});
|
|
const military = createApplicationMilitary({
|
|
surface,
|
|
source: sources.military,
|
|
militaryRegistry,
|
|
resolveAsset,
|
|
});
|
|
const vessels = createApplicationVessels({
|
|
source: sources.vessels,
|
|
options: vesselOptions,
|
|
});
|
|
const installations = createApplicationInstallations({
|
|
surface,
|
|
source: sources.installations,
|
|
});
|
|
const satellites = createApplicationSatellites({
|
|
source: sources.satellites,
|
|
});
|
|
const catalog = createLayerCatalog(
|
|
[
|
|
createBhoteKoshiEventLayer(),
|
|
createBhoteKoshiLocatorLayer({
|
|
boundaryResolver: nepalBoundaryResolver,
|
|
}),
|
|
flights,
|
|
military,
|
|
createApplicationLocalAdsb({
|
|
surface,
|
|
enrichment: sources.flights,
|
|
displayParams: () => flights.getParams(),
|
|
...(resolveAsset ? { resolveAsset } : {}),
|
|
}),
|
|
createApplicationEarthquakes({ source: sources.earthquakes }),
|
|
createApplicationAirQuality({ source: sources['air-quality'] }),
|
|
createApplicationFirePerimeters({
|
|
source: sources['fire-perimeters'],
|
|
}),
|
|
createApplicationGnssIntegrity({
|
|
source: sources['gnss-integrity'],
|
|
}),
|
|
createApplicationAlpr({ surface, source: sources.alpr }),
|
|
createApplicationStreetLevel({
|
|
surface,
|
|
sources: { mapillary: sources.mapillary },
|
|
providers: streetLevelProviders,
|
|
}),
|
|
satellites,
|
|
createApplicationLaunches({ source: sources.launches, satellites }),
|
|
createApplicationTraffic({ source: sources.traffic, surface }),
|
|
createApplicationCctv({ surface, source: sources.cctv }),
|
|
createApplicationRadio({ surface, source: sources.radio }),
|
|
createApplicationTransit({ surface, source: sources.transit }),
|
|
createApplicationBikeshare({ source: sources.bikeshare }),
|
|
createApplicationDirections({ source: sources.directions }),
|
|
createApplicationRecentImagery({ source: sources['recent-imagery'] }),
|
|
vessels,
|
|
installations,
|
|
createApplicationAwareness({
|
|
flights,
|
|
military,
|
|
vessels,
|
|
installations,
|
|
}),
|
|
createWindLayer({ feed: sources.wind, clock: weatherClock }),
|
|
createWeatherLayer({
|
|
feed: sources.weather,
|
|
id: 'weather-radar',
|
|
clock: weatherClock,
|
|
}),
|
|
createWeatherLayer({
|
|
feed: sources.weather,
|
|
id: 'weather-satellite',
|
|
clock: weatherClock,
|
|
}),
|
|
createWeatherLayer({
|
|
feed: sources.weather,
|
|
id: 'weather-lightning',
|
|
clock: weatherClock,
|
|
}),
|
|
createCyclonesLayer({ feed: sources.cyclones }),
|
|
...createInfrastructureLayers(localGeoJsonServices),
|
|
createApplicationCables({ source: sources.cables }),
|
|
createApplicationFirms({
|
|
surface,
|
|
id: 'local-firms',
|
|
name: 'FIRMS Active Fires',
|
|
icon: '▲',
|
|
source: 'NASA FIRMS · LIVE',
|
|
feed: sources.firms,
|
|
}),
|
|
],
|
|
metadata,
|
|
);
|
|
return Object.freeze({
|
|
...catalog,
|
|
getSourceAvailability: sourceComposition.createAvailabilityLookup(
|
|
catalog.layers,
|
|
),
|
|
militaryRegistry,
|
|
surface,
|
|
weatherClock,
|
|
});
|
|
} catch (error) {
|
|
dispose();
|
|
throw error;
|
|
}
|
|
}
|