Merge origin/main into german/navara

Main's camera, voice, Cockpit and layer work now runs on the globe
contract where this branch draws through it:

- The voice tilt to an angle, its pivot about the place under the
  crosshair and the frame limit from orbit run through the camera rig;
  src/globeInView.js measures a camera pose with src/geo instead of a
  Cesium camera. The free-look height limit and the globe-in-view
  recovery stay Cesium-only for now.
- Cockpit takes main's own-layer entry rule. Double-clicking the
  followed track goes through cockpitHost.routeDoubleClick, so it works
  on both engines.
- Space Missions' failed-entry rollback and GhostMaps' age filter run
  in the engine-neutral layer code. On Cesium an expired report is
  dropped in place; on Navara its product is redrawn.
- Wildlife Sightings joins the catalog Cesium-only: Navara leaves it
  out, and the shell builds its card only for the real layer, so a
  Navara page no longer fails to start on its stand-in.
- One instruction sentence is shorter, which keeps the Realtime prompt
  within its 55,500-character budget with the Sentinel-2 basemap.
This commit is contained in:
German Khokhlov committed 2026-11-07 01:07:26 +04:00
commit 92c8f8d9da
262 files changed
+32378 -959

No files matched your search

+15
View File
@@ -63,6 +63,7 @@ export function createGhostMapsCesiumRenderer(
},
});
pins.push({
index,
position,
get show() {
return entity.show;
@@ -130,6 +131,20 @@ export function createGhostMapsCesiumRenderer(
);
return {
ready,
// Take one report off in place: an expired event leaves its edition's
// data source, which stays mounted for the reports that remain.
drop(index) {
const prefix = `ghostmaps:${productId}:${index}:`;
for (const entity of [...dataSource.entities.values])
if (entity.id.startsWith(prefix))
dataSource.entities.remove(entity);
for (let i = pins.length - 1; i >= 0; i -= 1)
if (pins[i].index === index) {
allPins.delete(pins[i]);
pins.splice(i, 1);
}
return true;
},
destroy() {
disposed = true;
for (const pin of pins) allPins.delete(pin);