refactor(ui,voice,annotations,scenes): take vector maths from src/geo

Move the Cartesian3/Cartographic/Matrix4/Transforms/Ellipsoid/Math calls of
the second batch (cockpit camera, context and controller; camera orientation
controls; application shell; location navigation; the annotation resolver
and engine; voice actions and pointer pick; the scene director; the embed
app) to src/geo. Behaviour is unchanged: same argument order, same `result`
semantics.

Kept on Cesium: out-of-scope classes (HeadingPitchRange, BoundingSphere,
Intersect, EllipsoidalOccluder, EasingFunction, SceneTransforms, JulianDate),
WGS84 where it goes into pickEllipsoid or EllipsoidalOccluder,
Matrix4.IDENTITY handed to lookAtTransform, and the Cartesian2 window
positions that reach scene.pickPosition: Cesium keys its per-frame pick
cache on windowPosition.toString(), which a plain object would collapse to
one "[object Object]" key.

The Contacts-subject harness in gevActions.test stubbed
Cesium.Cartographic.fromCartesian to place its subject; it now builds a real
subject position at the same coordinates with geo.cartesian3.fromDegrees.
The cockpit-controls and scenes package-boundary groups now own the src/geo
files.
This commit is contained in:
German Khokhlov committed 2026-10-15 00:16:38 +04:00
1 parent d886be68a8
commit 1a69368ae6
14 files changed
+216 -200

No files matched your search

+30 -2
View File
@@ -520,7 +520,21 @@
"src/cockpitMath.js",
"src/cockpitUtilityLayout.js",
"src/cockpitVisionPolicy.js",
"src/ui/panelRailGeometry.js"
"src/ui/panelRailGeometry.js",
"src/geo/index.js",
"src/geo/math.js",
"src/geo/ellipsoid.js",
"src/geo/cartographic.js",
"src/geo/cartesian2.js",
"src/geo/cartesian3.js",
"src/geo/matrix3.js",
"src/geo/matrix4.js",
"src/geo/quaternion.js",
"src/geo/transforms.js",
"src/geo/scaleToGeodeticSurface.js",
"src/geo/check.js",
"src/geo/debug.js",
"src/geo/developerError.js"
],
"external": ["cesium"]
},
@@ -788,7 +802,21 @@
"src/director/authoring.js",
"src/scenes/sharing.js",
"src/ui/sceneSharing.js",
"src/data/cameraArrival.js"
"src/data/cameraArrival.js",
"src/geo/index.js",
"src/geo/math.js",
"src/geo/ellipsoid.js",
"src/geo/cartographic.js",
"src/geo/cartesian2.js",
"src/geo/cartesian3.js",
"src/geo/matrix3.js",
"src/geo/matrix4.js",
"src/geo/quaternion.js",
"src/geo/transforms.js",
"src/geo/scaleToGeodeticSurface.js",
"src/geo/check.js",
"src/geo/debug.js",
"src/geo/developerError.js"
],
"external": ["cesium"]
},
+15 -14
View File
@@ -1,6 +1,7 @@
import { isUnavailableCapability } from '../sources/capability.js';
import { defaultGeospatial } from '../search/defaults.js';
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import {
holdContinuousRender,
releaseContinuousRender,
@@ -1013,13 +1014,13 @@ export function createAnnotationEngine({
return;
}
const cart = points.map((p) =>
Cesium.Cartesian3.fromDegrees(p.lon, p.lat, p.height || 0),
geo.cartesian3.fromDegrees(p.lon, p.lat, p.height || 0),
);
const sphere = Cesium.BoundingSphere.fromPoints(cart);
viewer.camera.flyToBoundingSphere(sphere, {
offset: new Cesium.HeadingPitchRange(
viewer.camera.heading,
Cesium.Math.toRadians(-35),
geo.math.toRadians(-35),
Math.max(900, sphere.radius * 2.6),
),
duration: 1.6,
@@ -1034,7 +1035,7 @@ export function createAnnotationEngine({
function isPointOnScreen(p) {
try {
const camera = viewer.camera;
const pos = Cesium.Cartesian3.fromDegrees(p.lon, p.lat, p.height || 0);
const pos = geo.cartesian3.fromDegrees(p.lon, p.lat, p.height || 0);
const cv = camera.frustum.computeCullingVolume(
camera.position,
camera.direction,
@@ -1075,7 +1076,7 @@ export function createAnnotationEngine({
: viewportRange(anno.viewport) || 600;
viewer.camera.flyToBoundingSphere(
new Cesium.BoundingSphere(
Cesium.Cartesian3.fromDegrees(
geo.cartesian3.fromDegrees(
target.lon,
target.lat,
anno.anchor.height || 0,
@@ -1085,7 +1086,7 @@ export function createAnnotationEngine({
{
offset: new Cesium.HeadingPitchRange(
viewer.camera.heading,
Cesium.Math.toRadians(-35),
geo.math.toRadians(-35),
range * 2.4,
),
duration: 1.8,
@@ -1275,10 +1276,10 @@ export function createAnnotationEngine({
if (destroyed) return;
try {
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(lon, lat, height),
destination: geo.cartesian3.fromDegrees(lon, lat, height),
orientation: {
heading: Cesium.Math.toRadians(heading),
pitch: Cesium.Math.toRadians(pitch),
heading: geo.math.toRadians(heading),
pitch: geo.math.toRadians(pitch),
roll: 0,
},
duration,
@@ -1395,9 +1396,9 @@ const VIEWPORT_ASSIST_RANGE_CAP_M = 120000;
function viewportRange(vp) {
if (!vp?.low || !vp?.high) return null;
try {
const span = Cesium.Cartesian3.distance(
Cesium.Cartesian3.fromDegrees(vp.low.longitude, vp.low.latitude),
Cesium.Cartesian3.fromDegrees(vp.high.longitude, vp.high.latitude),
const span = geo.cartesian3.distance(
geo.cartesian3.fromDegrees(vp.low.longitude, vp.low.latitude),
geo.cartesian3.fromDegrees(vp.high.longitude, vp.high.latitude),
);
return Number.isFinite(span) && span > 0
? Math.max(300, Math.min(span * 0.7, VIEWPORT_ASSIST_RANGE_CAP_M))
@@ -1422,9 +1423,9 @@ function ringRange(ring) {
if (lon < minLon) minLon = lon;
if (lon > maxLon) maxLon = lon;
}
const span = Cesium.Cartesian3.distance(
Cesium.Cartesian3.fromDegrees(minLon, minLat),
Cesium.Cartesian3.fromDegrees(maxLon, maxLat),
const span = geo.cartesian3.distance(
geo.cartesian3.fromDegrees(minLon, minLat),
geo.cartesian3.fromDegrees(maxLon, maxLat),
);
return Math.max(300, span * 0.7);
}
+14 -13
View File
@@ -14,6 +14,7 @@ import {
} from '../sources/featureGeometry.js';
import { defaultGeospatial } from '../search/defaults.js';
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import { lookupNeighborhoodRing } from '../data/neighborhoodPolygons.js';
import {
lookupNaturalRegionOutline,
@@ -1835,8 +1836,8 @@ export function createAnnotationResolver({
try {
const carto = viewer?.camera?.positionCartographic;
if (!carto) return null;
const lat = Cesium.Math.toDegrees(carto.latitude);
const lon = Cesium.Math.toDegrees(carto.longitude);
const lat = geo.math.toDegrees(carto.latitude);
const lon = geo.math.toDegrees(carto.longitude);
const radiusKm = Math.max((carto.height / 1000) * 3, 5);
if (![lat, lon, radiusKm].every(Number.isFinite)) return null;
return { lat, lon, radiusKm };
@@ -1850,10 +1851,10 @@ export function createAnnotationResolver({
try {
const rect = viewer?.camera?.computeViewRectangle?.();
if (!rect) return null;
const swLat = Cesium.Math.toDegrees(rect.south).toFixed(4);
const swLng = Cesium.Math.toDegrees(rect.west).toFixed(4);
const neLat = Cesium.Math.toDegrees(rect.north).toFixed(4);
const neLng = Cesium.Math.toDegrees(rect.east).toFixed(4);
const swLat = geo.math.toDegrees(rect.south).toFixed(4);
const swLng = geo.math.toDegrees(rect.west).toFixed(4);
const neLat = geo.math.toDegrees(rect.north).toFixed(4);
const neLng = geo.math.toDegrees(rect.east).toFixed(4);
if ([swLat, swLng, neLat, neLng].some((v) => v === 'NaN')) return null;
return `${swLat},${swLng}|${neLat},${neLng}`;
} catch {
@@ -1953,11 +1954,11 @@ export function createAnnotationResolver({
}
}
if (!isPickedWorldPosition(cart)) return null;
const carto = Cesium.Cartographic.fromCartesian(cart);
const carto = geo.cartographic.fromCartesian(cart);
if (!carto) return null;
return {
lat: Cesium.Math.toDegrees(carto.latitude),
lon: Cesium.Math.toDegrees(carto.longitude),
lat: geo.math.toDegrees(carto.latitude),
lon: geo.math.toDegrees(carto.longitude),
// The height the pick actually landed on — a roof, a hillside, or 0 on
// the ellipsoid. Callers that only want a coordinate ignore it; the draw
// tool's live preview needs it, or the rubber band sinks to sea level
@@ -1979,11 +1980,11 @@ export function createAnnotationResolver({
scene.clampToHeightSupported &&
typeof scene.clampToHeight === 'function'
) {
const carto = Cesium.Cartographic.fromDegrees(lon, lat);
const surface = Cesium.Cartographic.toCartesian(carto);
const carto = geo.cartographic.fromDegrees(lon, lat);
const surface = geo.cartographic.toCartesian(carto);
const clamped = scene.clampToHeight(surface);
if (clamped) {
const h = Cesium.Cartographic.fromCartesian(clamped).height;
const h = geo.cartographic.fromCartesian(clamped).height;
if (Number.isFinite(h)) return h;
}
}
@@ -1991,7 +1992,7 @@ export function createAnnotationResolver({
/* tiles not ready — fall through */
}
const globeHeight = scene.globe?.getHeight?.(
Cesium.Cartographic.fromDegrees(lon, lat),
geo.cartographic.fromDegrees(lon, lat),
);
return Number.isFinite(globeHeight) && globeHeight > 0 ? globeHeight : 0;
}
+4 -4
View File
@@ -11,7 +11,7 @@
* embedded or not.
*/
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import { announceNavigationAuthority } from '../navigationPolicy.js';
import { annotationsFromParams, createView } from '../view/index.js';
@@ -126,14 +126,14 @@ function flyTo(viewer, camera) {
announceNavigationAuthority('embed-view');
return new Promise((resolve) => {
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
destination: geo.cartesian3.fromDegrees(
camera.lon,
camera.lat,
camera.altitude_m,
),
orientation: {
heading: Cesium.Math.toRadians(camera.heading_deg),
pitch: Cesium.Math.toRadians(camera.pitch_deg),
heading: geo.math.toRadians(camera.heading_deg),
pitch: geo.math.toRadians(camera.pitch_deg),
roll: 0,
},
duration: FLIGHT_SECONDS,
+9 -8
View File
@@ -20,6 +20,7 @@ import { SceneControls } from '../ui/scenes.js';
import { buildPlaybackQueue, playSceneQueue } from '../director/playback.js';
import { createScenePlaybackAdapter } from './playbackAdapter.js';
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import {
SCENE_APPEND_RECIPES,
SCENE_RECIPES,
@@ -1577,15 +1578,15 @@ export class SceneDirector {
this.styleManager?.clearSearchedLocation?.();
this.viewer.camera.cancelFlight?.();
this.viewer.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(
destination: geo.cartesian3.fromDegrees(
cameraState.lon,
cameraState.lat,
cameraState.alt,
),
orientation: {
heading: Cesium.Math.toRadians(cameraState.heading || 0),
pitch: Cesium.Math.toRadians(cameraState.pitch ?? -35),
roll: Cesium.Math.toRadians(cameraState.roll || 0),
heading: geo.math.toRadians(cameraState.heading || 0),
pitch: geo.math.toRadians(cameraState.pitch ?? -35),
roll: geo.math.toRadians(cameraState.roll || 0),
},
});
return true;
@@ -2268,7 +2269,7 @@ export class SceneDirector {
0.2,
Number(durationSec) || DEFAULT_SHOT_DURATION_SEC,
);
const destination = Cesium.Cartesian3.fromDegrees(
const destination = geo.cartesian3.fromDegrees(
cameraState.lon,
cameraState.lat,
cameraState.alt,
@@ -2288,9 +2289,9 @@ export class SceneDirector {
this.viewer.camera.flyTo({
destination,
orientation: {
heading: Cesium.Math.toRadians(cameraState.heading || 0),
pitch: Cesium.Math.toRadians(cameraState.pitch ?? -35),
roll: Cesium.Math.toRadians(cameraState.roll || 0),
heading: geo.math.toRadians(cameraState.heading || 0),
pitch: geo.math.toRadians(cameraState.pitch ?? -35),
roll: geo.math.toRadians(cameraState.roll || 0),
},
duration,
easingFunction: Cesium.EasingFunction.CUBIC_IN_OUT,
+10 -9
View File
@@ -30,6 +30,7 @@ import {
} from './cyberSonarControls.js';
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import { aircraftTrackingTarget } from '../cockpitTracking.js';
@@ -1317,12 +1318,12 @@ export class StyleManager extends ShellFacade {
const carto = this.viewer.camera.positionCartographic;
if (!carto) return null;
return {
lat: Cesium.Math.toDegrees(carto.latitude),
lon: Cesium.Math.toDegrees(carto.longitude),
lat: geo.math.toDegrees(carto.latitude),
lon: geo.math.toDegrees(carto.longitude),
alt: carto.height,
heading: Cesium.Math.toDegrees(this.viewer.camera.heading),
pitch: Cesium.Math.toDegrees(this.viewer.camera.pitch),
roll: Cesium.Math.toDegrees(this.viewer.camera.roll),
heading: geo.math.toDegrees(this.viewer.camera.heading),
pitch: geo.math.toDegrees(this.viewer.camera.pitch),
roll: geo.math.toDegrees(this.viewer.camera.roll),
};
}
@@ -1335,15 +1336,15 @@ export class StyleManager extends ShellFacade {
applyCameraState(cameraState, duration = 2.8) {
if (!cameraState) return;
this.viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
destination: geo.cartesian3.fromDegrees(
cameraState.lon,
cameraState.lat,
cameraState.alt,
),
orientation: {
heading: Cesium.Math.toRadians(cameraState.heading || 0),
pitch: Cesium.Math.toRadians(cameraState.pitch || -35),
roll: Cesium.Math.toRadians(cameraState.roll || 0),
heading: geo.math.toRadians(cameraState.heading || 0),
pitch: geo.math.toRadians(cameraState.pitch || -35),
roll: geo.math.toRadians(cameraState.roll || 0),
},
duration: Math.max(0.2, duration || 0),
easingFunction: Cesium.EasingFunction.CUBIC_IN_OUT,
+22 -25
View File
@@ -1,4 +1,5 @@
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import { isPickedWorldPosition } from '../data/scenePick.js';
function trackedTarget(viewer) {
@@ -11,17 +12,13 @@ function trackedTarget(viewer) {
);
}
export const OBLIQUE_PITCH = Cesium.Math.toRadians(-35);
export const STRAIGHT_DOWN_PITCH = Cesium.Math.toRadians(-89);
const OBLIQUE_THRESHOLD = Cesium.Math.toRadians(-60);
export const OBLIQUE_PITCH = geo.math.toRadians(-35);
export const STRAIGHT_DOWN_PITCH = geo.math.toRadians(-89);
const OBLIQUE_THRESHOLD = geo.math.toRadians(-60);
function normalizedHeading(heading) {
const wrapped = Cesium.Math.zeroToTwoPi(
Number.isFinite(heading) ? heading : 0,
);
return Math.abs(wrapped - Cesium.Math.TWO_PI) < Cesium.Math.EPSILON10
? 0
: wrapped;
const wrapped = geo.math.zeroToTwoPi(Number.isFinite(heading) ? heading : 0);
return Math.abs(wrapped - geo.math.TWO_PI) < geo.math.EPSILON10 ? 0 : wrapped;
}
/** Return the world position under the center of the canvas, when available. */
@@ -79,20 +76,20 @@ export function readCameraTargetFrame(viewer) {
if (!camera || !target || !isPickedWorldPosition(camera.positionWC))
return null;
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(target);
const inverse = Cesium.Matrix4.inverseTransformation(
const transform = geo.transforms.eastNorthUpToFixedFrame(target);
const inverse = geo.matrix4.inverseTransformation(
transform,
new Cesium.Matrix4(),
geo.matrix4.create(),
);
const localOffset = Cesium.Matrix4.multiplyByPoint(
const localOffset = geo.matrix4.multiplyByPoint(
inverse,
camera.positionWC,
new Cesium.Cartesian3(),
geo.cartesian3.create(),
);
const range = Cesium.Cartesian3.magnitude(localOffset);
const range = geo.cartesian3.magnitude(localOffset);
if (!Number.isFinite(range) || range < 1) return null;
const pitch = -Math.asin(Cesium.Math.clamp(localOffset.z / range, -1, 1));
const pitch = -Math.asin(geo.math.clamp(localOffset.z / range, -1, 1));
// Cesium places a lookAt camera at range * (-sin h cos p, -cos h cos p,
// -sin p) in the target's east-north-up frame, so recovering h means
// negating BOTH horizontal components. Negating only the north one reads
@@ -100,7 +97,7 @@ export function readCameraTargetFrame(viewer) {
// make north-up rotate the wrong way from three quarters of the compass.
const targetHeading = Math.atan2(-localOffset.x, -localOffset.y);
const heading = normalizedHeading(
pitch < Cesium.Math.toRadians(-88.5) ? camera.heading : targetHeading,
pitch < geo.math.toRadians(-88.5) ? camera.heading : targetHeading,
);
return { target, range, heading, pitch };
}
@@ -111,7 +108,7 @@ export function setCameraTargetFrame(viewer, frame) {
if (!camera || !frame?.target || !Number.isFinite(frame.range)) return false;
try {
const trackedTransform = viewer.trackedEntity
? Cesium.Matrix4.clone(camera.transform)
? geo.matrix4.clone(camera.transform)
: null;
camera.lookAt(
frame.target,
@@ -128,9 +125,9 @@ export function setCameraTargetFrame(viewer, frame) {
viewer.scene?.requestRender?.();
return true;
}
const destination = Cesium.Cartesian3.clone(camera.positionWC);
const direction = Cesium.Cartesian3.clone(camera.directionWC);
const up = Cesium.Cartesian3.clone(camera.upWC);
const destination = geo.cartesian3.clone(camera.positionWC);
const direction = geo.cartesian3.clone(camera.directionWC);
const up = geo.cartesian3.clone(camera.upWC);
camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
if (destination && direction && up) {
camera.setView({ destination, orientation: { direction, up } });
@@ -179,7 +176,7 @@ export function resetCameraNorth(viewer) {
}
function headingDegrees(camera) {
return Cesium.Math.toDegrees(normalizedHeading(camera?.heading));
return geo.math.toDegrees(normalizedHeading(camera?.heading));
}
/** Ease an orbit without handing off the entity that owns the follow camera. */
@@ -201,7 +198,7 @@ export function createCameraOrientationAnimator(
const entity = viewer.trackedEntity;
pending = destination;
const start = now();
const headingDelta = Cesium.Math.negativePiToPi(
const headingDelta = geo.math.negativePiToPi(
destination.heading - frame.heading,
);
remove = viewer.scene.preUpdate.addEventListener(() => {
@@ -209,7 +206,7 @@ export function createCameraOrientationAnimator(
cancel();
return;
}
const progress = Cesium.Math.clamp((now() - start) / duration, 0, 1);
const progress = geo.math.clamp((now() - start) / duration, 0, 1);
const eased = Cesium.EasingFunction.CUBIC_IN_OUT(progress);
const target = entity ? trackedTarget(viewer) : frame.target;
if (
@@ -218,7 +215,7 @@ export function createCameraOrientationAnimator(
...frame,
target,
heading: frame.heading + headingDelta * eased,
pitch: Cesium.Math.lerp(frame.pitch, destination.pitch, eased),
pitch: geo.math.lerp(frame.pitch, destination.pitch, eased),
})
) {
cancel();
+41 -45
View File
@@ -1,5 +1,5 @@
/** Camera placement, ground acquisition and motion correction for the Cockpit controller. */
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import {
cockpitAnchorCorrectionStep,
cockpitGroundSafeHeight,
@@ -77,7 +77,7 @@ export function update() {
}
if (!this.cockpitAnchorValid) {
Cesium.Cartesian3.clone(target, this.cockpitAnchor);
geo.cartesian3.clone(target, this.cockpitAnchor);
this.cockpitAnchorValid = true;
}
@@ -88,8 +88,8 @@ export function update() {
// display position at a bounded rate. This preserves the layer's required
// 15/30-second interpolation and per-frame cache without exposing its
// sample-boundary corrections to the camera.
const headingRad = Cesium.Math.toRadians(this.heading ?? 0);
const pitchRad = Cesium.Math.toRadians(COCKPIT_VIEW_PITCH_DEG);
const headingRad = geo.math.toRadians(this.heading ?? 0);
const pitchRad = geo.math.toRadians(COCKPIT_VIEW_PITCH_DEG);
const speedMps = Number.isFinite(info.velocityMps)
? Math.max(0, info.velocityMps)
: 0;
@@ -98,38 +98,34 @@ export function update() {
// A feed backoff has no authoritative velocity epoch to advance from.
// Hold the cockpit on the exact layer-rendered position so the camera
// cannot coast away while the icon correctly remains fixed.
Cesium.Cartesian3.clone(target, this.cockpitAnchor);
geo.cartesian3.clone(target, this.cockpitAnchor);
} else {
Cesium.Transforms.eastNorthUpToFixedFrame(
geo.transforms.eastNorthUpToFixedFrame(
this.cockpitAnchor,
Cesium.Ellipsoid.WGS84,
geo.ellipsoid.WGS84,
this.scratchEnu,
);
this.scratchLocal.x = Math.sin(headingRad);
this.scratchLocal.y = Math.cos(headingRad);
this.scratchLocal.z = 0;
Cesium.Matrix4.multiplyByPointAsVector(
geo.matrix4.multiplyByPointAsVector(
this.scratchEnu,
this.scratchLocal,
this.scratchHorizontal,
);
Cesium.Cartesian3.normalize(this.scratchHorizontal, this.scratchHorizontal);
Cesium.Cartesian3.multiplyByScalar(
geo.cartesian3.normalize(this.scratchHorizontal, this.scratchHorizontal);
geo.cartesian3.multiplyByScalar(
this.scratchHorizontal,
speedMps * dtSec,
this.scratchAdvance,
);
Cesium.Cartesian3.add(
geo.cartesian3.add(
this.cockpitAnchor,
this.scratchAdvance,
this.cockpitAnchor,
);
Cesium.Cartesian3.subtract(
target,
this.cockpitAnchor,
this.scratchCorrection,
);
const correctionDistanceM = Cesium.Cartesian3.magnitude(
geo.cartesian3.subtract(target, this.cockpitAnchor, this.scratchCorrection);
const correctionDistanceM = geo.cartesian3.magnitude(
this.scratchCorrection,
);
const correctionStepM = cockpitAnchorCorrectionStep(
@@ -138,12 +134,12 @@ export function update() {
dtSec,
);
if (correctionStepM > 0 && correctionDistanceM > 0) {
Cesium.Cartesian3.multiplyByScalar(
geo.cartesian3.multiplyByScalar(
this.scratchCorrection,
correctionStepM / correctionDistanceM,
this.scratchCorrection,
);
Cesium.Cartesian3.add(
geo.cartesian3.add(
this.cockpitAnchor,
this.scratchCorrection,
this.cockpitAnchor,
@@ -156,14 +152,14 @@ export function update() {
// between fixes. Clamp it against the same mesh-first shared floor used by
// aircraft rendering. For a slow contact whose floor cell is still cold,
// its already-clamped render position is a conservative temporary floor.
const anchorCartographic = Cesium.Cartographic.fromCartesian(
const anchorCartographic = geo.cartographic.fromCartesian(
this.cockpitAnchor,
Cesium.Ellipsoid.WGS84,
geo.ellipsoid.WGS84,
this.scratchAnchorCartographic,
);
const targetCartographic = Cesium.Cartographic.fromCartesian(
const targetCartographic = geo.cartographic.fromCartesian(
target,
Cesium.Ellipsoid.WGS84,
geo.ellipsoid.WGS84,
this.scratchTargetCartographic,
);
let cockpitFloorM = this.services.cachedGroundFloor(
@@ -189,8 +185,8 @@ export function update() {
const viewerCartographic = this.viewer.camera.positionCartographic;
this.services.sampleMeshFloorCells(this.viewer.scene, groundPoint, {
excludeObjects: [this.trackedEntity],
viewerLat: Cesium.Math.toDegrees(viewerCartographic.latitude),
viewerLon: Cesium.Math.toDegrees(viewerCartographic.longitude),
viewerLat: geo.math.toDegrees(viewerCartographic.latitude),
viewerLon: geo.math.toDegrees(viewerCartographic.longitude),
});
}
cockpitFloorM = this.services.cachedMeshFloor(
@@ -252,7 +248,7 @@ export function update() {
);
if (minimumAnchorHeightM !== anchorCartographic.height) {
anchorCartographic.height = minimumAnchorHeightM;
Cesium.Ellipsoid.WGS84.cartographicToCartesian(
geo.ellipsoid.WGS84.cartographicToCartesian(
anchorCartographic,
this.cockpitAnchor,
);
@@ -260,59 +256,59 @@ export function update() {
}
// Rebuild the local frame at the stabilized anchor after advancing it.
Cesium.Transforms.eastNorthUpToFixedFrame(
geo.transforms.eastNorthUpToFixedFrame(
this.cockpitAnchor,
Cesium.Ellipsoid.WGS84,
geo.ellipsoid.WGS84,
this.scratchEnu,
);
this.scratchLocal.x = Math.sin(headingRad);
this.scratchLocal.y = Math.cos(headingRad);
this.scratchLocal.z = 0;
Cesium.Matrix4.multiplyByPointAsVector(
geo.matrix4.multiplyByPointAsVector(
this.scratchEnu,
this.scratchLocal,
this.scratchHorizontal,
);
Cesium.Cartesian3.normalize(this.scratchHorizontal, this.scratchHorizontal);
geo.cartesian3.normalize(this.scratchHorizontal, this.scratchHorizontal);
this.scratchLocal.x = Math.sin(headingRad) * Math.cos(pitchRad);
this.scratchLocal.y = Math.cos(headingRad) * Math.cos(pitchRad);
this.scratchLocal.z = Math.sin(pitchRad);
Cesium.Matrix4.multiplyByPointAsVector(
geo.matrix4.multiplyByPointAsVector(
this.scratchEnu,
this.scratchLocal,
this.scratchForward,
);
Cesium.Cartesian3.normalize(this.scratchForward, this.scratchForward);
geo.cartesian3.normalize(this.scratchForward, this.scratchForward);
this.scratchLocal.x = -Math.sin(headingRad) * Math.sin(pitchRad);
this.scratchLocal.y = -Math.cos(headingRad) * Math.sin(pitchRad);
this.scratchLocal.z = Math.cos(pitchRad);
Cesium.Matrix4.multiplyByPointAsVector(
geo.matrix4.multiplyByPointAsVector(
this.scratchEnu,
this.scratchLocal,
this.scratchUp,
);
Cesium.Cartesian3.normalize(this.scratchUp, this.scratchUp);
geo.cartesian3.normalize(this.scratchUp, this.scratchUp);
Cesium.Cartesian3.multiplyByScalar(
geo.cartesian3.multiplyByScalar(
this.scratchHorizontal,
COCKPIT_FORWARD_OFFSET_M,
this.scratchCamera,
);
Cesium.Cartesian3.add(
geo.cartesian3.add(
this.cockpitAnchor,
this.scratchCamera,
this.scratchCamera,
);
Cesium.Matrix4.getTranslation(this.scratchEnu, this.scratchTarget);
Cesium.Cartesian3.normalize(this.scratchTarget, this.scratchTarget);
Cesium.Cartesian3.multiplyByScalar(
geo.matrix4.getTranslation(this.scratchEnu, this.scratchTarget);
geo.cartesian3.normalize(this.scratchTarget, this.scratchTarget);
geo.cartesian3.multiplyByScalar(
this.scratchTarget,
COCKPIT_UP_OFFSET_M,
this.scratchTarget,
);
Cesium.Cartesian3.add(
geo.cartesian3.add(
this.scratchCamera,
this.scratchTarget,
this.scratchCamera,
@@ -320,14 +316,14 @@ export function update() {
// Recheck at the final forward-offset camera coordinate because a taxiing
// aircraft can cross into an adjacent coarse floor cell between updates.
const cameraCartographic = Cesium.Cartographic.fromCartesian(
const cameraCartographic = geo.cartographic.fromCartesian(
this.scratchCamera,
Cesium.Ellipsoid.WGS84,
geo.ellipsoid.WGS84,
this.scratchCameraCartographic,
);
if (cameraCartographic) {
const cameraLat = Cesium.Math.toDegrees(cameraCartographic.latitude);
const cameraLon = Cesium.Math.toDegrees(cameraCartographic.longitude);
const cameraLat = geo.math.toDegrees(cameraCartographic.latitude);
const cameraLon = geo.math.toDegrees(cameraCartographic.longitude);
const cameraFloorM = this.services.cachedGroundFloor(cameraLat, cameraLon);
if (Number.isFinite(cameraFloorM)) {
cockpitFloorM = Math.max(
@@ -342,7 +338,7 @@ export function update() {
);
if (safeHeightM !== cameraCartographic.height) {
cameraCartographic.height = safeHeightM;
Cesium.Ellipsoid.WGS84.cartographicToCartesian(
geo.ellipsoid.WGS84.cartographicToCartesian(
cameraCartographic,
this.scratchCamera,
);
+4 -4
View File
@@ -1,5 +1,5 @@
/** Contact readouts and nearby-signal presentation for the Cockpit controller. */
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import {
bearingBetweenCoordinates,
formatCockpitContextScope,
@@ -117,13 +117,13 @@ export function updateContext(info, heading) {
Number.isFinite(info.latitude) &&
Number.isFinite(info.longitude)
) {
const cartographic = Cesium.Cartographic.fromCartesian(closest.position);
const cartographic = geo.cartographic.fromCartesian(closest.position);
const bearing = cartographic
? bearingBetweenCoordinates(
info.latitude,
info.longitude,
Cesium.Math.toDegrees(cartographic.latitude),
Cesium.Math.toDegrees(cartographic.longitude),
geo.math.toDegrees(cartographic.latitude),
geo.math.toDegrees(cartographic.longitude),
)
: null;
relative = relativeBearing(bearing, heading);
+14 -14
View File
@@ -44,7 +44,7 @@ import {
syncSignalLayout,
} from './cockpitLayout.js';
import { onKeyDown } from './cockpitInput.js';
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
export class CockpitViewController {
constructor(
@@ -209,20 +209,20 @@ export class CockpitViewController {
this.regionalBriefSubjectId = null;
this.contextLayoutFrame = null;
this.contextLayoutStamp = null;
this.scratchTarget = new Cesium.Cartesian3();
this.cockpitAnchor = new Cesium.Cartesian3();
this.scratchTarget = geo.cartesian3.create();
this.cockpitAnchor = geo.cartesian3.create();
this.cockpitAnchorValid = false;
this.scratchCamera = new Cesium.Cartesian3();
this.scratchAdvance = new Cesium.Cartesian3();
this.scratchCorrection = new Cesium.Cartesian3();
this.scratchForward = new Cesium.Cartesian3();
this.scratchHorizontal = new Cesium.Cartesian3();
this.scratchUp = new Cesium.Cartesian3();
this.scratchLocal = new Cesium.Cartesian3();
this.scratchEnu = new Cesium.Matrix4();
this.scratchAnchorCartographic = new Cesium.Cartographic();
this.scratchCameraCartographic = new Cesium.Cartographic();
this.scratchTargetCartographic = new Cesium.Cartographic();
this.scratchCamera = geo.cartesian3.create();
this.scratchAdvance = geo.cartesian3.create();
this.scratchCorrection = geo.cartesian3.create();
this.scratchForward = geo.cartesian3.create();
this.scratchHorizontal = geo.cartesian3.create();
this.scratchUp = geo.cartesian3.create();
this.scratchLocal = geo.cartesian3.create();
this.scratchEnu = geo.matrix4.create();
this.scratchAnchorCartographic = geo.cartographic.create();
this.scratchCameraCartographic = geo.cartographic.create();
this.scratchTargetCartographic = geo.cartographic.create();
this._listenerRemovers = [];
// Camera mutations belong before scene update/culling. Changing the camera
+3 -2
View File
@@ -1,4 +1,5 @@
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import { createStateChannel } from '../app/stateChannel.js';
import { LocationControls } from './location.js';
@@ -373,8 +374,8 @@ export class LocationNavigation {
cancelled,
heightKm: Math.round(GLOBE_VIEW.heightM / 1000),
centeredOn: {
latitude: Number(Cesium.Math.toDegrees(carto.latitude).toFixed(2)),
longitude: Number(Cesium.Math.toDegrees(carto.longitude).toFixed(2)),
latitude: Number(geo.math.toDegrees(carto.latitude).toFixed(2)),
longitude: Number(geo.math.toDegrees(carto.longitude).toFixed(2)),
},
};
this._resetGlobeBtn?.setAttribute(
+45 -50
View File
@@ -9,6 +9,7 @@ import { resolveDeicticArgs } from './deixis.js';
export { readLayerLifecycleSummary } from './layerSummary.js';
import { defaultGeospatial } from '../search/defaults.js';
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import {
CITY_POIS,
findPoiByName,
@@ -2454,7 +2455,7 @@ async function frameOverhead(viewer, dataManager, styleManager, args = {}) {
.filter((entry) => entry.position)
.map((entry) => ({
...entry,
distance: Cesium.Cartesian3.distance(center, entry.position),
distance: geo.cartesian3.distance(center, entry.position),
}))
.filter((entry) => entry.distance <= radiusKm * 1000)
.sort((a, b) => a.distance - b.distance)
@@ -2475,7 +2476,7 @@ async function frameOverhead(viewer, dataManager, styleManager, args = {}) {
entries.map((entry) => entry.position),
);
sphere.radius = Math.max(sphere.radius * 1.25, 8000);
const pitch = Cesium.Math.toRadians(isSatellites ? -35 : -62);
const pitch = geo.math.toRadians(isSatellites ? -35 : -62);
return runManagedVoiceNavigation(
styleManager,
'frame',
@@ -2583,8 +2584,8 @@ export async function getBasemapLabelContext(
};
}
const latitude = Number(Cesium.Math.toDegrees(target.latitude).toFixed(6));
const longitude = Number(Cesium.Math.toDegrees(target.longitude).toFixed(6));
const latitude = Number(geo.math.toDegrees(target.latitude).toFixed(6));
const longitude = Number(geo.math.toDegrees(target.longitude).toFixed(6));
const cachedViewportPlaces = viewportPlacesFromCache(
samples,
cameraHeightM,
@@ -2695,11 +2696,11 @@ function adjustCameraZoom(viewer, args) {
if (!fraction) throw new Error(`Unknown zoom amount: ${args.amount}`);
const camera = viewer.camera;
const beforePosition = Cesium.Cartesian3.clone(camera.positionWC);
const beforePosition = geo.cartesian3.clone(camera.positionWC);
const beforeHeightM = camera.positionCartographic.height;
const target = getViewTargetCartesian(viewer);
const targetDistanceM = target
? Cesium.Cartesian3.distance(beforePosition, target)
? geo.cartesian3.distance(beforePosition, target)
: Math.max(100, beforeHeightM);
const minimumDistanceM = direction === 'in' ? 20 : 50;
const movementM = Math.max(minimumDistanceM, targetDistanceM * fraction);
@@ -2726,7 +2727,7 @@ function adjustCameraZoom(viewer, args) {
viewer.scene.requestRender();
const afterPosition = camera.positionWC;
const movedM = Cesium.Cartesian3.distance(beforePosition, afterPosition);
const movedM = geo.cartesian3.distance(beforePosition, afterPosition);
const afterHeightM = camera.positionCartographic.height;
const moved = movedM >= 0.5;
return {
@@ -2771,8 +2772,8 @@ function nextIssPass(viewer, dataManager, args) {
if (latDeg == null || lonDeg == null) {
const carto = viewer?.camera?.positionCartographic;
if (!carto) throw new Error('Camera position unavailable');
latDeg = Cesium.Math.toDegrees(carto.latitude);
lonDeg = Cesium.Math.toDegrees(carto.longitude);
latDeg = geo.math.toDegrees(carto.latitude);
lonDeg = geo.math.toDegrees(carto.longitude);
}
const minElevDeg = Number.isFinite(args.minElevationDeg)
? args.minElevationDeg
@@ -3199,15 +3200,13 @@ function getCurrentViewState(
dataManager,
sceneDirector = null,
) {
const cartographic = Cesium.Cartographic.fromCartesian(
viewer.camera.positionWC,
);
const cartographic = geo.cartographic.fromCartesian(viewer.camera.positionWC);
return {
ok: true,
action: 'get_current_view_state',
camera: {
latitude: Cesium.Math.toDegrees(cartographic.latitude),
longitude: Cesium.Math.toDegrees(cartographic.longitude),
latitude: geo.math.toDegrees(cartographic.latitude),
longitude: geo.math.toDegrees(cartographic.longitude),
heightM: cartographic.height,
},
style: styleManager.activeStyle || 'normal',
@@ -3440,7 +3439,7 @@ async function getTargetContext(
}
const hasPosition = Number.isFinite(lat) && Number.isFinite(lon);
const viewTarget = hasPosition
? Cesium.Cartographic.fromDegrees(lon, lat)
? geo.cartographic.fromDegrees(lon, lat)
: getViewTargetCartographic(viewer);
const selected = describeTargetEntity(dataManager, target);
const scene = await getSceneContext(
@@ -3565,10 +3564,10 @@ async function aircraftProximityWindowForQuery(
let lon = record?.lon;
if (!Number.isFinite(lat) || !Number.isFinite(lon)) {
const carto = item.position
? Cesium.Cartographic.fromCartesian(item.position)
? geo.cartographic.fromCartesian(item.position)
: null;
lat = carto ? Cesium.Math.toDegrees(carto.latitude) : null;
lon = carto ? Cesium.Math.toDegrees(carto.longitude) : null;
lat = carto ? geo.math.toDegrees(carto.latitude) : null;
lon = carto ? geo.math.toDegrees(carto.longitude) : null;
}
const row = {
...(record || {
@@ -3727,10 +3726,10 @@ const SUBJECT_CENTER_TOLERANCE_KM = 1;
function centerMatchesSubject(center, subjectPosition) {
if (!Number.isFinite(center?.lat) || !Number.isFinite(center?.lon))
return false;
const carto = Cesium.Cartographic.fromCartesian(subjectPosition);
const carto = geo.cartographic.fromCartesian(subjectPosition);
if (!carto) return false;
const subjectLat = Cesium.Math.toDegrees(carto.latitude);
const subjectLon = Cesium.Math.toDegrees(carto.longitude);
const subjectLat = geo.math.toDegrees(carto.latitude);
const subjectLon = geo.math.toDegrees(carto.longitude);
return (
haversineKm(subjectLat, subjectLon, center.lat, center.lon) <=
SUBJECT_CENTER_TOLERANCE_KM
@@ -3758,8 +3757,8 @@ function visibleEntityContexts(
const height = canvas.clientHeight || canvas.height || 0;
const centerX = width / 2;
const centerY = height / 2;
const targetLat = target ? Cesium.Math.toDegrees(target.latitude) : null;
const targetLon = target ? Cesium.Math.toDegrees(target.longitude) : null;
const targetLat = target ? geo.math.toDegrees(target.latitude) : null;
const targetLon = target ? geo.math.toDegrees(target.longitude) : null;
const store = getContextStore();
const enabledLayerIds = new Set(
dataManager
@@ -3850,9 +3849,7 @@ async function getSceneContext(
viewTarget = null,
service = defaultGeospatial,
) {
const cartographic = Cesium.Cartographic.fromCartesian(
viewer.camera.positionWC,
);
const cartographic = geo.cartographic.fromCartesian(viewer.camera.positionWC);
const basemap = await getBasemapContext(viewer, viewTarget, service);
const enabledLayers = dataManager
.getAll()
@@ -3865,10 +3862,8 @@ async function getSceneContext(
}));
return {
camera: {
latitude: Number(Cesium.Math.toDegrees(cartographic.latitude).toFixed(6)),
longitude: Number(
Cesium.Math.toDegrees(cartographic.longitude).toFixed(6),
),
latitude: Number(geo.math.toDegrees(cartographic.latitude).toFixed(6)),
longitude: Number(geo.math.toDegrees(cartographic.longitude).toFixed(6)),
heightM: Math.round(cartographic.height),
},
basemap,
@@ -3885,7 +3880,7 @@ async function getBasemapContext(
const { reverseGeocodeCache, nearbyPlacesCache } = cachesFor(service);
const target = viewTarget;
const samples = sampleViewportCartographics(viewer);
const cameraCartographic = Cesium.Cartographic.fromCartesian(
const cameraCartographic = geo.cartographic.fromCartesian(
viewer.camera.positionWC,
);
const cameraHeightM = cameraCartographic.height;
@@ -3915,8 +3910,8 @@ async function getBasemapContext(
};
}
const latitude = Number(Cesium.Math.toDegrees(target.latitude).toFixed(6));
const longitude = Number(Cesium.Math.toDegrees(target.longitude).toFixed(6));
const latitude = Number(geo.math.toDegrees(target.latitude).toFixed(6));
const longitude = Number(geo.math.toDegrees(target.longitude).toFixed(6));
const inferredCountry = inferCountryFromSamples(samples);
const knownLandmarks = nearbyKnownLandmarks(
latitude,
@@ -4039,7 +4034,7 @@ function nearbyKnownLandmarks(latitude, longitude, cameraHeightM) {
}
function haversineKm(lat1, lon1, lat2, lon2) {
const toRad = (value) => Cesium.Math.toRadians(value);
const toRad = (value) => geo.math.toRadians(value);
const radiusKm = 6371.0088;
const dLat = toRad(lat2 - lat1);
const dLon = toRad(lon2 - lon1);
@@ -4095,7 +4090,7 @@ function getViewTargetCartographic(viewer) {
// center to project; normalize that to the same "no target" null the callers
// already handle for a missed pick.
const target = position
? Cesium.Cartographic.fromCartesian(position) || null
? geo.cartographic.fromCartesian(position) || null
: null;
viewTargetCache.set(viewer, {
signature,
@@ -4109,8 +4104,8 @@ function cameraViewSignature(viewer) {
const camera = viewer.camera;
const cartographic = camera.positionCartographic;
return [
Cesium.Math.toDegrees(cartographic.latitude).toFixed(5),
Cesium.Math.toDegrees(cartographic.longitude).toFixed(5),
geo.math.toDegrees(cartographic.latitude).toFixed(5),
geo.math.toDegrees(cartographic.longitude).toFixed(5),
Math.round(cartographic.height / 2),
camera.heading.toFixed(3),
camera.pitch.toFixed(3),
@@ -4189,15 +4184,15 @@ function sampleViewportCartographics(viewer) {
const samples = [];
for (const [x, y] of points) {
const cartesian = viewer.camera.pickEllipsoid(
new Cesium.Cartesian2(width * x, height * y),
geo.cartesian2.create(width * x, height * y),
Cesium.Ellipsoid.WGS84,
);
if (!isPickedWorldPosition(cartesian)) continue;
const carto = Cesium.Cartographic.fromCartesian(cartesian);
const carto = geo.cartographic.fromCartesian(cartesian);
if (!carto) continue;
samples.push({
latitude: Number(Cesium.Math.toDegrees(carto.latitude).toFixed(4)),
longitude: Number(Cesium.Math.toDegrees(carto.longitude).toFixed(4)),
latitude: Number(geo.math.toDegrees(carto.latitude).toFixed(4)),
longitude: Number(geo.math.toDegrees(carto.longitude).toFixed(4)),
});
}
return samples;
@@ -4466,7 +4461,7 @@ async function resolveWithin(promise, timeoutMs, fallback) {
function approximateCoordinateDistanceSq(latA, lonA, latB, lonB) {
const latDelta = latB - latA;
const lonDelta =
(lonB - lonA) * Math.cos(Cesium.Math.toRadians((latA + latB) / 2));
(lonB - lonA) * Math.cos(geo.math.toRadians((latA + latB) / 2));
return latDelta * latDelta + lonDelta * lonDelta;
}
@@ -4515,17 +4510,17 @@ function summarizeEntity(viewer, entity, { includeProperties = false } = {}) {
entity.__localBaseCartesian ||
entity.position?.getValue?.(now) ||
polygonCenter(entity, now);
const carto = position ? Cesium.Cartographic.fromCartesian(position) : null;
const carto = position ? geo.cartographic.fromCartesian(position) : null;
return {
id: String(entity.id || ''),
name: label || layerTitle(layerId),
layerId,
layerName: layerTitle(layerId),
latitude: carto
? Number(Cesium.Math.toDegrees(carto.latitude).toFixed(6))
? Number(geo.math.toDegrees(carto.latitude).toFixed(6))
: null,
longitude: carto
? Number(Cesium.Math.toDegrees(carto.longitude).toFixed(6))
? Number(geo.math.toDegrees(carto.longitude).toFixed(6))
: null,
properties: includeProperties ? compactProperties(props) : undefined,
};
@@ -4747,11 +4742,11 @@ function analystProviders(
?.module?.getContextSnapshot?.();
const subject = snapshot?.subject;
if (!subject?.position) return null;
const carto = Cesium.Cartographic.fromCartesian(subject.position);
const carto = geo.cartographic.fromCartesian(subject.position);
if (!carto) return null;
return {
lat: Cesium.Math.toDegrees(carto.latitude),
lon: Cesium.Math.toDegrees(carto.longitude),
lat: geo.math.toDegrees(carto.latitude),
lon: geo.math.toDegrees(carto.longitude),
label: subject.label || subject.id || null,
};
},
@@ -4762,8 +4757,8 @@ function analystProviders(
// country-level asks sweep wide. Clamped so "in view" is never absurd.
const viewRadiusKm = Math.max(25, Math.min(2500, altKm * 1.6));
return {
lat: Cesium.Math.toDegrees(carto.latitude),
lon: Cesium.Math.toDegrees(carto.longitude),
lat: geo.math.toDegrees(carto.latitude),
lon: geo.math.toDegrees(carto.longitude),
viewRadiusKm,
};
},
+3 -8
View File
@@ -3,6 +3,7 @@ import { createStandalonePlaceSearch } from '../standalone/placeSearch.js';
import { test } from 'node:test';
import assert from 'node:assert/strict';
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import { CCTV_FOCUS_RESULT } from '../data/cctv.js';
import { getContextStore, registerEntityContext } from '../data/contextStore.js';
import { DataLayerManager } from '../data/manager.js';
@@ -2820,7 +2821,8 @@ test('a nested Cockpit rollback result is translated too', async () => {
* analyst's 2 000-record last-fix slice). These pin the unified engine.
*/
function awarenessSubjectHarness({ subject, flights = [], military = [] }) {
const position = subject ? { __subject: true } : null;
// The Contacts subject sits at 29.9 N, 97.9 W, 9 000 m.
const position = subject ? geo.cartesian3.fromDegrees(-97.9, 29.9, 9000) : null;
const snapshotFlights = flights.slice(0, 20_000);
const snapshotMilitary = military.slice(0, 20_000);
return {
@@ -2887,7 +2889,6 @@ async function withAwareness(harness, run) {
aircraftSnapshot: awareness.getAircraftQuerySnapshot,
flightsNearby: flightsLayer.getNearby,
militaryNearby: militaryLayer.getNearby,
cartoFrom: Cesium.Cartographic.fromCartesian,
};
awareness.getContextSnapshot = () => harness.snapshot;
awareness.getAircraftQuerySnapshot = () => {
@@ -2920,11 +2921,6 @@ async function withAwareness(harness, run) {
};
flightsLayer.getNearby = () => harness.flights.slice();
militaryLayer.getNearby = () => harness.military.slice();
Cesium.Cartographic.fromCartesian = (value) => (
value?.__subject
? { latitude: Cesium.Math.toRadians(29.9), longitude: Cesium.Math.toRadians(-97.9), height: 9000 }
: originals.cartoFrom(value)
);
try {
return await run(awareness);
} finally {
@@ -2932,7 +2928,6 @@ async function withAwareness(harness, run) {
awareness.getAircraftQuerySnapshot = originals.aircraftSnapshot;
flightsLayer.getNearby = originals.flightsNearby;
militaryLayer.getNearby = originals.militaryNearby;
Cesium.Cartographic.fromCartesian = originals.cartoFrom;
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
import * as Cesium from 'cesium';
import * as geo from '../geo/index.js';
import { resolvePickedContext } from '../data/pickedContext.js';
import { cameraPoseKey } from './pointerContext.js';
import * as defaultAnnotationResolver from '../annotations/annotationResolver.js';
@@ -34,7 +34,7 @@ export function createPointerPicker({
if (!width || !height) return null;
let picked = null;
try {
picked = scene.pick(new Cesium.Cartesian2(x, y));
picked = scene.pick(geo.cartesian2.create(x, y));
} catch {
picked = null;
}