Convert voice action positions and distances through src/geo

Voice actions read degrees from ECEF positions with toLonLatH and
measure distances with src/geo, at the sites that only did maths. A
position that converts to NaN now reads as unknown, never as NaN
coordinates. The analyst test gives its subject a real ECEF position
instead of patching Cesium. Sites that keep a Cesium Cartographic, or
use the camera or picks, wait for the renderer ports.
This commit is contained in:
Sameh Khamis committed 2026-11-05 14:33:32 -08:00
1 parent bf758a0abb
commit 6060c2cee8
2 files changed
+23 -28

No files matched your search

+21 -20
View File
@@ -12,6 +12,7 @@ import { msg } from '../i18n/index.js';
import { useProviderSettingsStore } from '../ui/stores/providerSettings.js';
import { applicationPinia } from '../ui/vueRuntime.js';
import * as Cesium from 'cesium';
import { distance as chordM, toLonLatH } from '../geo/index.js';
import { CITY_POIS } from '../cityPois.js';
import { greatCircleKm } from '../geoDistance.js';
import {
@@ -2626,7 +2627,7 @@ async function frameOverhead(viewer, dataManager, styleManager, args = {}) {
.filter((entry) => entry.position)
.map((entry) => ({
...entry,
distance: Cesium.Cartesian3.distance(center, entry.position),
distance: chordM(center, entry.position),
}))
.filter((entry) => entry.distance <= radiusKm * 1000)
.sort((a, b) => a.distance - b.distance)
@@ -2926,7 +2927,7 @@ function adjustCameraZoom(viewer, args) {
const beforeHeightM = camera.positionCartographic.height;
const target = getViewTargetCartesian(viewer);
const targetDistanceM = target
? Cesium.Cartesian3.distance(beforePosition, target)
? chordM(beforePosition, target)
: Math.max(100, beforeHeightM);
const minimumDistanceM = direction === 'in' ? 20 : 50;
const movementM = Math.max(minimumDistanceM, targetDistanceM * fraction);
@@ -2953,7 +2954,7 @@ function adjustCameraZoom(viewer, args) {
viewer.scene.requestRender();
const afterPosition = camera.positionWC;
const movedM = Cesium.Cartesian3.distance(beforePosition, afterPosition);
const movedM = chordM(beforePosition, afterPosition);
const afterHeightM = camera.positionCartographic.height;
const moved = movedM >= 0.5;
return {
@@ -3751,11 +3752,10 @@ async function aircraftProximityWindowForQuery(
let lat = record?.lat;
let lon = record?.lon;
if (!Number.isFinite(lat) || !Number.isFinite(lon)) {
const carto = item.position
? Cesium.Cartographic.fromCartesian(item.position)
: null;
lat = carto ? Cesium.Math.toDegrees(carto.latitude) : null;
lon = carto ? Cesium.Math.toDegrees(carto.longitude) : null;
const at = item.position ? toLonLatH(item.position) : null;
const known = at && Number.isFinite(at.lat) && Number.isFinite(at.lon);
lat = known ? at.lat : null;
lon = known ? at.lon : null;
}
const row = {
...(record || {
@@ -3914,10 +3914,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);
if (!carto) return false;
const subjectLat = Cesium.Math.toDegrees(carto.latitude);
const subjectLon = Cesium.Math.toDegrees(carto.longitude);
const at = toLonLatH(subjectPosition);
if (!at) return false;
const subjectLat = at.lat;
const subjectLon = at.lon;
return (
greatCircleKm(
{ lat: subjectLat, lon: subjectLon },
@@ -4368,11 +4368,11 @@ function sampleViewportCartographics(viewer) {
Cesium.Ellipsoid.WGS84,
);
if (!isPickedWorldPosition(cartesian)) continue;
const carto = Cesium.Cartographic.fromCartesian(cartesian);
if (!carto) continue;
const at = toLonLatH(cartesian);
if (!at) continue;
samples.push({
latitude: Number(Cesium.Math.toDegrees(carto.latitude).toFixed(4)),
longitude: Number(Cesium.Math.toDegrees(carto.longitude).toFixed(4)),
latitude: Number(at.lat.toFixed(4)),
longitude: Number(at.lon.toFixed(4)),
});
}
return samples;
@@ -4840,11 +4840,12 @@ function analystProviders(
?.module?.getContextSnapshot?.();
const subject = snapshot?.subject;
if (!subject?.position) return null;
const carto = Cesium.Cartographic.fromCartesian(subject.position);
if (!carto) return null;
const at = toLonLatH(subject.position);
if (!at || !Number.isFinite(at.lat) || !Number.isFinite(at.lon))
return null;
return {
lat: Cesium.Math.toDegrees(carto.latitude),
lon: Cesium.Math.toDegrees(carto.longitude),
lat: at.lat,
lon: at.lon,
label: subject.label || subject.id || null,
};
},
+2 -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 { fromDegrees } 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';
@@ -2878,7 +2879,7 @@ 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;
const position = subject ? fromDegrees(-97.9, 29.9, 9000) : null;
const snapshotFlights = flights.slice(0, 20_000);
const snapshotMilitary = military.slice(0, 20_000);
return {
@@ -2945,7 +2946,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 = () => {
@@ -2978,11 +2978,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 {
@@ -2990,7 +2985,6 @@ async function withAwareness(harness, run) {
awareness.getAircraftQuerySnapshot = originals.aircraftSnapshot;
flightsLayer.getNearby = originals.flightsNearby;
militaryLayer.getNearby = originals.militaryNearby;
Cesium.Cartographic.fromCartesian = originals.cartoFrom;
}
}