feat: add Nepal flood incident scene

This commit is contained in:
manjunath22466 committed 2026-09-15 19:48:11 +05:30
1 parent 76c20be277
commit 60768ccc0b
48 files changed
+15431 -161

No files matched your search

+16 -4
View File
@@ -180,12 +180,24 @@ export class MapSourceController {
async _activateGlobeStack(stack, gen) {
const resolution = await this._getImageryProvider(stack);
if (gen !== this._switchGen) return;
this._removeImageryLayer();
this._imageryLayer = this._createImageryLayer(resolution.provider);
this._activeImageryProvider = resolution.provider;
this.viewer.imageryLayers.add(this._imageryLayer, 0);
// Scene shots reapply their map stack at every handoff. Keep the live
// layer (and its loaded tiles) when the resolved provider is unchanged;
// rebuilding it exposes the bare globe while imagery loads again.
if (
!this._imageryLayer ||
this._activeImageryProvider !== resolution.provider
) {
this._removeImageryLayer();
this._imageryLayer = this._createImageryLayer(resolution.provider);
this._activeImageryProvider = resolution.provider;
this.viewer.imageryLayers.add(this._imageryLayer, 0);
}
const source = this._sources.get(resolution.effectiveStackId);
this._credits.show(source?.credit || null);
// A repeated request still owns a new switch generation. Rebind its
// failure listener so fallback remains live without accumulating listeners.
this._removeImageryErrorListener?.();
this._removeImageryErrorListener = null;
this._watchProvider(resolution, gen);
this._showTileset(null);
this.viewer.scene.globe.show = true;
+55 -1
View File
@@ -124,14 +124,68 @@ test('an additional imagery source needs no controller branch and owns its cache
assert.equal(reads, 1);
assert.equal(terrainReads, 1);
assert.equal(env.imagery.length, 1);
assert.equal(env.removed[0].destroy, true);
assert.equal(
env.removed.length,
0,
'same provider keeps its loaded imagery layer',
);
env.controller.destroy();
env.controller.destroy();
await settle();
assert.equal(env.imagery.length, 0);
assert.equal(env.removed[0].destroy, true);
assert.equal(destroys, 1);
});
test('repeated Esri shot handoffs retain imagery and keep tile fallback live', async () => {
const env = publicFixture();
await env.controller.setStack('esri-imagery');
const layer = env.imagery[0];
const generation = env.controller.getSwitchGeneration();
const errors = env.providers.get('esri-imagery').errorEvent;
for (let i = 0; i < 3; i++) await env.controller.setStack('esri-imagery');
assert.equal(env.imagery[0], layer);
assert.equal(env.removed.length, 0);
assert.equal(errors.size, 1);
assert.equal(env.controller.getSwitchGeneration(), generation + 3);
errors.raise();
errors.raise();
await settle();
assert.equal(env.controller.getActiveId(), 'osm');
assert.equal(env.removed.length, 1);
assert.equal(errors.size, 0);
env.controller.destroy();
});
test('returning to the live provider supersedes a pending switch without rebuilding imagery', async () => {
const env = publicFixture();
await env.controller.setStack('esri-imagery');
const layer = env.imagery[0];
let resolve;
env.registry.sources.find(
(source) => source.descriptor.id === 'osm',
).imagery = () =>
new Promise((done) => {
resolve = done;
});
const pending = env.controller.setStack('osm');
await settle();
await env.controller.setStack('esri-imagery');
resolve(env.providers.get('osm'));
await pending;
assert.equal(env.controller.getActiveId(), 'esri-imagery');
assert.equal(env.imagery[0], layer);
assert.equal(env.removed.length, 0);
await env.controller.setStack('photoreal');
assert.equal(env.imagery.length, 0);
assert.equal(env.tileset.show, true);
await env.controller.setStack('esri-imagery');
assert.notEqual(env.imagery[0], layer, 'a removed layer must be recreated');
assert.equal(env.viewer.scene.globe.show, true);
assert.equal(env.tileset.show, false);
env.controller.destroy();
});
test('a destroyed controller aborts creation and disposes a late provider without touching the scene', async () => {
let resolve,
signal,
+61 -1
View File
@@ -2,7 +2,67 @@ import test from 'node:test';
import assert from 'node:assert/strict';
import * as Cesium from 'cesium';
import { createIonImagery } from './imagery.js';
import { createWorldTerrain } from './terrain.js';
import { createWorldTerrain, createKeylessTerrain } from './terrain.js';
import { createDefaultMapSources } from './defaultSources.js';
test('Esri uses Re:Earth without keys and preserves ion terrain when configured', async () => {
const originalTerrain = Cesium.CesiumTerrainProvider.fromUrl;
const originalResource = Cesium.IonResource.fromAssetId;
const calls = [];
try {
Cesium.CesiumTerrainProvider.fromUrl = async (resource) => {
calls.push(resource);
return { resource };
};
Cesium.IonResource.fromAssetId = async () =>
assert.fail('keyless mode must not acquire ion terrain');
const keyless = createDefaultMapSources();
const esri = keyless.sources.find(
({ descriptor }) => descriptor.id === 'esri-imagery',
);
assert.equal(esri.available, true);
assert.equal(esri.terrain.id, 'keyless');
assert.equal(esri.terrain.create, createKeylessTerrain);
await esri.terrain.create();
assert.deepEqual(calls, [
'https://terrain.reearth.land/cesium-mesh/ellipsoid',
]);
assert.equal(
keyless.sources.find(({ descriptor }) => descriptor.id === 'photoreal')
.available,
false,
);
for (const credentials of [
{ googleApiKey: 'test-key' },
{ cesiumToken: 'test-token' },
]) {
const keyed = createDefaultMapSources({
...credentials,
googleTileset: { show: true },
});
assert.equal(
keyed.sources.find(({ descriptor }) => descriptor.id === 'photoreal')
.available,
true,
);
assert.equal(
keyed.sources.find(({ descriptor }) => descriptor.id === 'esri-imagery')
.terrain.id,
credentials.cesiumToken ? 'world' : 'keyless',
);
const failedTileset = createDefaultMapSources(credentials);
assert.equal(
failedTileset.sources.find(
({ descriptor }) => descriptor.id === 'photoreal',
).available,
false,
);
}
} finally {
Cesium.CesiumTerrainProvider.fromUrl = originalTerrain;
Cesium.IonResource.fromAssetId = originalResource;
}
});
test('imagery and terrain pass their own ion token without relying on SDK defaults', async () => {
const originalImagery = Cesium.IonImageryProvider.fromAssetId;