mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-06 11:24:00 +00:00
feat(maps): map sources for the Navara engine
createDefaultMapSources takes the engine kind. On Navara, Google 3D is available from the browser key alone (Navara builds the tiles itself and has no ion route to them), so it is the default and the recovery stack when a key is set; without one the default is Esri imagery. Bing (Cesium ion imagery) has no Navara path and is unavailable with a reason. World terrain still needs an ion token and falls back to the keyless terrain. MapStackController passes the kind of the engine it is given; Cesium sources are unchanged.
This commit is contained in:
1 parent
d112ecf296
commit
72fec292d4
4 files changed
+109
-10
No files matched your search
@@ -9,7 +9,13 @@ export class MapStackController extends MapSourceController {
|
||||
constructor(viewer, options = {}) {
|
||||
const googleApiKey =
|
||||
typeof window !== 'undefined' ? window.__GOOGLE_MAPS_API_KEY__ : '';
|
||||
const registry = createDefaultMapSources({ ...options, googleApiKey });
|
||||
// Sources for the page's engine: Navara builds its own from the
|
||||
// descriptions (src/maps/defaultSources.js).
|
||||
const registry = createDefaultMapSources({
|
||||
...options,
|
||||
googleApiKey,
|
||||
engineKind: options.engine?.kind === 'navara' ? 'navara' : 'cesium',
|
||||
});
|
||||
super(viewer, {
|
||||
registry,
|
||||
initialStack: options.googleTileset
|
||||
|
||||
@@ -22,3 +22,28 @@ test('the map stack controller applies its stacks through a given globe engine',
|
||||
assert.equal(engine.fake.callsOf('maps.setPhotorealTiles')[1].args[0], null);
|
||||
controller.destroy();
|
||||
});
|
||||
|
||||
test('on a Navara engine the map stack controller opens on Google 3D from the browser key alone', async (t) => {
|
||||
const previous = globalThis.window;
|
||||
globalThis.window = { __GOOGLE_MAPS_API_KEY__: 'google-test' };
|
||||
t.after(() => {
|
||||
if (previous === undefined) delete globalThis.window;
|
||||
else globalThis.window = previous;
|
||||
});
|
||||
const engine = createFakeEngine({ kind: 'navara' });
|
||||
const controller = new MapStackController(null, { engine });
|
||||
assert.equal(controller.getActiveId(), 'photoreal');
|
||||
assert.equal(controller.isStackAvailable('bing-aerial'), false);
|
||||
await controller.setStack('photoreal');
|
||||
const [photoreal] = engine.fake.callsOf('maps.setPhotorealTiles')[0].args;
|
||||
assert.equal(photoreal.kind, 'photoreal');
|
||||
assert.equal('tileset' in photoreal, false);
|
||||
controller.destroy();
|
||||
window.__GOOGLE_MAPS_API_KEY__ = '';
|
||||
const keyless = new MapStackController(null, {
|
||||
engine: createFakeEngine({ kind: 'navara' }),
|
||||
});
|
||||
assert.equal(keyless.getActiveId(), 'esri-imagery');
|
||||
assert.equal(keyless.isStackAvailable('photoreal'), false);
|
||||
keyless.destroy();
|
||||
});
|
||||
@@ -4,12 +4,26 @@ import { keySetupRequirement } from '../keySetupCore.mjs';
|
||||
import { imageryFactoryFor, ESRI_ATTRIBUTION_HTML } from './imagery.js';
|
||||
import { terrainSourceFor } from './terrain.js';
|
||||
|
||||
/** Select sources and setup guidance without putting provider branches in the controller. */
|
||||
const NAVARA_ION_IMAGERY_REASON =
|
||||
'Bing imagery is not available on the experimental Navara engine';
|
||||
|
||||
/**
|
||||
* Select sources and setup guidance without putting provider branches in the
|
||||
* controller. `engineKind` is the globe engine kind the sources are for: Cesium
|
||||
* builds them from the factories (photoreal needs its loaded tileset); Navara
|
||||
* builds them from the descriptions, so photoreal needs only the browser key
|
||||
* (Navara has no ion route to Google tiles) and Cesium ion imagery (Bing) is
|
||||
* unavailable.
|
||||
*/
|
||||
export function createDefaultMapSources({
|
||||
googleTileset = null,
|
||||
cesiumToken = '',
|
||||
googleApiKey = '',
|
||||
engineKind = 'cesium',
|
||||
} = {}) {
|
||||
if (engineKind !== 'cesium' && engineKind !== 'navara')
|
||||
throw new TypeError(`Unknown globe engine: ${engineKind}`);
|
||||
const navara = engineKind === 'navara';
|
||||
const ionToken = String(cesiumToken || '').trim();
|
||||
const hasIon = Boolean(ionToken);
|
||||
// Engine-neutral descriptions ride beside the Cesium factories: a terrain
|
||||
@@ -22,24 +36,30 @@ export function createDefaultMapSources({
|
||||
};
|
||||
const googleKey = String(googleApiKey || '').trim();
|
||||
const hasGoogle = Boolean(googleKey);
|
||||
const photorealAvailable = navara ? hasGoogle : Boolean(googleTileset);
|
||||
return {
|
||||
defaultId: googleTileset ? 'photoreal' : 'esri-imagery',
|
||||
defaultId: photorealAvailable ? 'photoreal' : 'esri-imagery',
|
||||
unknownId: 'photoreal',
|
||||
recoveryId: googleTileset ? 'photoreal' : null,
|
||||
recoveryId: photorealAvailable ? 'photoreal' : null,
|
||||
state: { hasCesiumIonToken: hasIon },
|
||||
sources: MAP_STACKS.map((descriptor) => {
|
||||
const ionImageryOnNavara = navara && descriptor.kind === 'ion';
|
||||
const common = {
|
||||
descriptor,
|
||||
available: !descriptor.requiresIon || hasIon,
|
||||
unavailableReason: descriptor.requiresIon
|
||||
? keySetupRequirement('cesium-ion')
|
||||
: null,
|
||||
available: !ionImageryOnNavara && (!descriptor.requiresIon || hasIon),
|
||||
unavailableReason: ionImageryOnNavara
|
||||
? NAVARA_ION_IMAGERY_REASON
|
||||
: descriptor.requiresIon
|
||||
? keySetupRequirement('cesium-ion')
|
||||
: null,
|
||||
};
|
||||
if (descriptor.kind === 'photoreal')
|
||||
return {
|
||||
...common,
|
||||
available: Boolean(googleTileset),
|
||||
unavailableReason: photorealUnavailableReason(hasIon || hasGoogle),
|
||||
available: photorealAvailable,
|
||||
unavailableReason: photorealUnavailableReason(
|
||||
navara ? hasGoogle : hasIon || hasGoogle,
|
||||
),
|
||||
tileset: googleTileset,
|
||||
...(googleKey && { googleApiKey: googleKey }),
|
||||
...(hasIon && { cesiumToken: ionToken }),
|
||||
|
||||
@@ -239,3 +239,51 @@ test('default sources carry engine-neutral descriptions beside their Cesium fact
|
||||
assert.equal(osm.terrain.kind, 'keyless');
|
||||
assert.equal(osm.terrain.accessToken, undefined);
|
||||
});
|
||||
|
||||
test('on the Navara engine photoreal keys on the browser key and ion imagery is unavailable', () => {
|
||||
const byId = (registry, id) =>
|
||||
registry.sources.find(({ descriptor }) => descriptor.id === id);
|
||||
// Navara builds Google tiles from the browser key alone; no Cesium tileset.
|
||||
const keyed = createDefaultMapSources({
|
||||
engineKind: 'navara',
|
||||
googleApiKey: 'google-test',
|
||||
});
|
||||
assert.equal(keyed.defaultId, 'photoreal');
|
||||
assert.equal(keyed.recoveryId, 'photoreal');
|
||||
assert.equal(byId(keyed, 'photoreal').available, true);
|
||||
assert.equal(byId(keyed, 'photoreal').googleApiKey, 'google-test');
|
||||
assert.equal(byId(keyed, 'photoreal').tileset, null);
|
||||
// Bing (Cesium ion imagery) has no Navara path, with or without a token.
|
||||
for (const registry of [
|
||||
keyed,
|
||||
createDefaultMapSources({ engineKind: 'navara', cesiumToken: 'ion-test' }),
|
||||
]) {
|
||||
for (const id of ['bing-aerial', 'bing-labels']) {
|
||||
assert.equal(byId(registry, id).available, false);
|
||||
assert.match(byId(registry, id).unavailableReason, /Navara/);
|
||||
}
|
||||
assert.equal(byId(registry, 'esri-imagery').available, true);
|
||||
assert.equal(byId(registry, 'osm').available, true);
|
||||
}
|
||||
// The ion route to Google tiles is Cesium's; a token alone is not enough.
|
||||
const ionOnly = createDefaultMapSources({
|
||||
engineKind: 'navara',
|
||||
cesiumToken: 'ion-test',
|
||||
});
|
||||
assert.equal(byId(ionOnly, 'photoreal').available, false);
|
||||
assert.equal(ionOnly.defaultId, 'esri-imagery');
|
||||
assert.equal(byId(ionOnly, 'osm').terrain.kind, 'world');
|
||||
// No key: base imagery over keyless terrain.
|
||||
const keyless = createDefaultMapSources({ engineKind: 'navara' });
|
||||
assert.equal(keyless.defaultId, 'esri-imagery');
|
||||
assert.equal(keyless.recoveryId, null);
|
||||
assert.equal(byId(keyless, 'photoreal').available, false);
|
||||
assert.equal(byId(keyless, 'esri-imagery').terrain.kind, 'keyless');
|
||||
});
|
||||
|
||||
test('default sources reject an unknown engine', () => {
|
||||
assert.throws(
|
||||
() => createDefaultMapSources({ engineKind: 'unreal' }),
|
||||
/Unknown globe engine/,
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user