diff --git a/scripts/package-boundaries.json b/scripts/package-boundaries.json index 34c075eae..afc4996ad 100644 --- a/scripts/package-boundaries.json +++ b/scripts/package-boundaries.json @@ -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"] }, diff --git a/src/annotations/annotationEngine.js b/src/annotations/annotationEngine.js index 27b049bb8..83e0d292a 100644 --- a/src/annotations/annotationEngine.js +++ b/src/annotations/annotationEngine.js @@ -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); } diff --git a/src/annotations/resolver.js b/src/annotations/resolver.js index 7d5f55d0d..117b50b9e 100644 --- a/src/annotations/resolver.js +++ b/src/annotations/resolver.js @@ -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; } diff --git a/src/app/embed.js b/src/app/embed.js index a1485fe7e..9ccabb19a 100644 --- a/src/app/embed.js +++ b/src/app/embed.js @@ -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, diff --git a/src/scenes/director.js b/src/scenes/director.js index d2343138e..bebd09ae4 100644 --- a/src/scenes/director.js +++ b/src/scenes/director.js @@ -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, diff --git a/src/ui/applicationShell.js b/src/ui/applicationShell.js index d400b54c2..76b708de0 100644 --- a/src/ui/applicationShell.js +++ b/src/ui/applicationShell.js @@ -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, diff --git a/src/ui/cameraOrientationControls.js b/src/ui/cameraOrientationControls.js index 887f59d0b..aac5a34a4 100644 --- a/src/ui/cameraOrientationControls.js +++ b/src/ui/cameraOrientationControls.js @@ -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(); diff --git a/src/ui/cockpitCamera.js b/src/ui/cockpitCamera.js index c33ba3c15..90b8eb022 100644 --- a/src/ui/cockpitCamera.js +++ b/src/ui/cockpitCamera.js @@ -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, ); diff --git a/src/ui/cockpitContext.js b/src/ui/cockpitContext.js index 70dac99f7..7d9b7323e 100644 --- a/src/ui/cockpitContext.js +++ b/src/ui/cockpitContext.js @@ -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); diff --git a/src/ui/cockpitController.js b/src/ui/cockpitController.js index 9aa19fd05..57c757d1c 100644 --- a/src/ui/cockpitController.js +++ b/src/ui/cockpitController.js @@ -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 diff --git a/src/ui/locationNavigation.js b/src/ui/locationNavigation.js index 83c20ddef..d86511e29 100644 --- a/src/ui/locationNavigation.js +++ b/src/ui/locationNavigation.js @@ -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( diff --git a/src/voice/gevActions.js b/src/voice/gevActions.js index 9e1e183d0..c0b4cf42a 100644 --- a/src/voice/gevActions.js +++ b/src/voice/gevActions.js @@ -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, }; }, diff --git a/src/voice/gevActions.test.mjs b/src/voice/gevActions.test.mjs index 3d0e35b3e..bb55af7fb 100644 --- a/src/voice/gevActions.test.mjs +++ b/src/voice/gevActions.test.mjs @@ -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; } } diff --git a/src/voice/pointerPick.js b/src/voice/pointerPick.js index 33ccab9cb..fc6514f46 100644 --- a/src/voice/pointerPick.js +++ b/src/voice/pointerPick.js @@ -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; }