fix(street-level): camera height over Google 3D, cast only when it helps, gate token

From the code review of #768:

- view.js measured the camera's height above ground with globe.getHeight,
  but Google 3D hides the globe, so coverage picked its zoom from the
  ellipsoidal height. Over a high city (Denver, ~1,600 m) a camera 500 m up
  read 2,100 m: coverage stayed at z12/z13, whose tiles are too big to cast,
  and lines stayed draped on the roofs. With the globe hidden, the bare-earth
  height from the ground caster now answers; coverage re-picks its zoom when
  the surface mode changes. Verified in Denver: terrain mode, z14, cast lines.
  The core's surface check uses the same helper (and no longer subtracts the
  2 m lift from the camera height).
- castTile rebuilt a tile even when no line could be cast (terrain proxy
  down, tile too big); it now leaves such tiles as they are.
- The feature gate read Street Level's share token as a literal `0`; it now
  takes it from LAYER_STATE_REGISTRY, since a rebase can reassign it.

New view.test.mjs covers the shown-globe, hidden-globe and no-sample cases.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Said TurkseverandClaude Opus 5.5 committed 2026-10-02 01:01:40 +01:00
1 parent e01ffb3cad
commit abbf69a512
6 files changed
+96 -22

No files matched your search

+15 -4
View File
@@ -1,13 +1,24 @@
import * as Cesium from 'cesium';
/**
* Camera height above the surface under the camera, in metres. Falls back to
* the ellipsoidal height when the globe has no height sample yet.
* Camera height above the surface under the camera, in metres. The globe's
* terrain answers when the globe is shown; Google 3D hides the globe, so
* there the bare-earth height from `groundAt(lon, lat)` answers instead
* (without it a camera over a city 1,600 m up reads 1,600 m too high). Falls
* back to the ellipsoidal height when neither has a sample yet.
* @param {object} viewer
* @param {{groundAt?: (lon: number, lat: number) => number|null}} [options]
*/
export function cameraHeightAboveGround(viewer) {
export function cameraHeightAboveGround(viewer, { groundAt } = {}) {
const carto = viewer?.camera?.positionCartographic;
if (!carto) return null;
const ground = viewer.scene?.globe?.getHeight?.(carto);
const globe = viewer.scene?.globe;
let ground = globe?.show === false ? null : globe?.getHeight?.(carto);
if (!Number.isFinite(ground))
ground = groundAt?.(
Cesium.Math.toDegrees(carto.longitude),
Cesium.Math.toDegrees(carto.latitude),
);
return carto.height - (Number.isFinite(ground) ? ground : 0);
}