mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
feat: add Nepal flood incident scene
This commit is contained in:
1 parent
76c20be277
commit
60768ccc0b
48 files changed
+15431
-161
No files matched your search
+16
-4
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user