Merge branch 'german/refactor-e6-tiles-fixture' into german/navara-refactor

# Conflicts:
#	scripts/qa-harness-baseline.json
This commit is contained in:
German Khokhlov committed 2026-11-10 15:54:13 +04:00
commit 1ac9f28c4a
18 files changed
+1857 -19

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
import { Cesium3DTileset } from 'cesium';
import { localTilesetPath } from '../../maps/qaTileset.js';
/** The QA source uses the controller's normal tileset ownership path. */
export function createQaTileset(url, { signal } = {}) {
signal?.throwIfAborted();
return Cesium3DTileset.fromUrl(localTilesetPath(url));
}
+16 -10
View File
@@ -22,6 +22,7 @@ import {
SENTINEL2_MAX_ZOOM,
SENTINEL2_URL,
} from '../../maps/sentinel2.js';
import { localTilesetPath } from '../../maps/qaTileset.js';
const OSM_URL = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
const OSM_CREDIT = {
@@ -280,12 +281,15 @@ export function createNavaraMaps(
return;
}
const key = String(source.googleApiKey || '').trim();
if (!key)
const tilesetUrl = localTilesetPath(source.tilesetUrl);
if (!tilesetUrl && !key)
throw new Error(
'Google 3D tiles on Navara need a browser key (googleApiKey)',
);
if (destroyed || generation !== generations.display) return;
const url = `${GOOGLE_TILES_ROOT}?key=${encodeURIComponent(key)}`;
const url = tilesetUrl
? new URL(tilesetUrl, globalThis.location.origin).href
: `${GOOGLE_TILES_ROOT}?key=${encodeURIComponent(key)}`;
setImageryShown(false);
currentBase = null;
tilesSource = source;
@@ -296,17 +300,19 @@ export function createNavaraMaps(
url,
{ type: '3d-tiles', url },
{ type: '3d-tiles', model: { maxSse: PHOTOREAL_MAX_SSE } },
[
(layer) => ({
attribution: 'Google',
logo: GOOGLE_LOGO,
creditLayerId: layer.id,
}),
],
tilesetUrl
? []
: [
(layer) => ({
attribution: 'Google',
logo: GOOGLE_LOGO,
creditLayerId: layer.id,
}),
],
);
// Google's terms want its copyright lines on screen, as Cesium shows
// them; Navara lists them in its attribution card, collapsed by default.
view.attribution?.show();
if (!tilesetUrl) view.attribution?.show();
},
releasePhotorealTiles(source) {
if (!knownTiles.delete(source)) return;
+1
View File
@@ -408,6 +408,7 @@ export class MapSourceController {
descriptor: source.descriptor,
kind: source.descriptor.kind,
credit: source.credit ?? null,
...(source.tilesetUrl && { tilesetUrl: source.tilesetUrl }),
...(source.googleApiKey && { googleApiKey: source.googleApiKey }),
...(source.cesiumToken && { cesiumToken: source.cesiumToken }),
...(tileset && { tileset }),
+14 -2
View File
@@ -7,6 +7,7 @@ import {
} from '../globe/cesium/mapImagery.js';
import { terrainSourceFor } from '../globe/cesium/terrain.js';
import { t } from '../i18n/index.js';
import { localTilesetPath, qaTilesetUrl } from './qaTileset.js';
const navaraIonImageryReason = () =>
t('Bing imagery is not available on the experimental Navara engine');
@@ -24,10 +25,12 @@ export function createDefaultMapSources({
cesiumToken = '',
googleApiKey = '',
engineKind = 'cesium',
tilesetUrl = qaTilesetUrl(),
} = {}) {
if (engineKind !== 'cesium' && engineKind !== 'navara')
throw new TypeError(`Unknown globe engine: ${engineKind}`);
const navara = engineKind === 'navara';
tilesetUrl = localTilesetPath(tilesetUrl);
const ionToken = String(cesiumToken || '').trim();
const hasIon = Boolean(ionToken);
// Engine-neutral descriptions ride beside the Cesium factories: a terrain
@@ -40,7 +43,8 @@ export function createDefaultMapSources({
};
const googleKey = String(googleApiKey || '').trim();
const hasGoogle = Boolean(googleKey);
const photorealAvailable = navara ? hasGoogle : Boolean(googleTileset);
const photorealAvailable =
Boolean(tilesetUrl) || (navara ? hasGoogle : Boolean(googleTileset));
return {
defaultId: photorealAvailable ? 'photoreal' : 'esri-imagery',
unknownId: 'photoreal',
@@ -69,7 +73,15 @@ export function createDefaultMapSources({
photorealUnavailableReason(
navara ? hasGoogle : hasIon || hasGoogle,
),
tileset: googleTileset,
tileset: tilesetUrl ? null : googleTileset,
...(tilesetUrl && {
tilesetUrl,
createTileset: async (options) => {
const { createQaTileset } =
await import('../globe/cesium/qaTileset.js');
return createQaTileset(tilesetUrl, options);
},
}),
...(googleKey && { googleApiKey: googleKey }),
...(hasIon && { cesiumToken: ionToken }),
};
+22
View File
@@ -0,0 +1,22 @@
/** Only a root-relative path on this page may replace the photoreal source. */
export function localTilesetPath(value, location = globalThis.location) {
if (!value) return null;
if (
typeof value !== 'string' ||
!/^\/(?!\/)/.test(value) ||
/[\\\s\u0000-\u001f\u007f]/.test(value) ||
!location?.origin
)
throw new TypeError('tilesetUrl must be a path on the page origin');
const url = new URL(value, location.origin);
if (url.origin !== location.origin || url.search || url.hash)
throw new TypeError('tilesetUrl must be a path on the page origin');
return url.pathname;
}
// Like parkedMs, this explicit QA parameter is inert on an ordinary page.
export function qaTilesetUrl() {
return localTilesetPath(
new URLSearchParams(globalThis.location?.search).get('qaTileset'),
);
}