mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
refactor(vessels,satellites,awareness): take vector maths from src/geo
Moves the Cartesian3/Cartographic/Matrix3/Matrix4/Math calls of the vessel, satellite and Contacts (awareness) layers, plus flights controller/enrichment, to src/geo. The satellites-layer package boundary now owns the src/geo modules. Awareness keeps Cesium.Cartesian3.clone for the resolved subject position, which reaches the installations anchor (anchor.test pins a Cesium instance).
This commit is contained in:
1 parent
1a69368ae6
commit
2b83606765
15 files changed
+97
-86
No files matched your search
@@ -1104,7 +1104,21 @@
|
|||||||
"src/layers/satellites/state.js",
|
"src/layers/satellites/state.js",
|
||||||
"src/layers/satellites/testing.js",
|
"src/layers/satellites/testing.js",
|
||||||
"src/layers/satellites/tracking.js",
|
"src/layers/satellites/tracking.js",
|
||||||
"src/data/inputOwnership.js"
|
"src/data/inputOwnership.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", "satellite.js"]
|
"external": ["cesium", "satellite.js"]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as Cesium from 'cesium';
|
||||||
|
import * as geo from '../../geo/index.js';
|
||||||
import { VESSEL_FOCUS_RADIUS_M } from './policy.js';
|
import { VESSEL_FOCUS_RADIUS_M } from './policy.js';
|
||||||
|
|
||||||
export function createFocus({ state: layerState, services, parts, source }) {
|
export function createFocus({ state: layerState, services, parts, source }) {
|
||||||
@@ -74,7 +75,7 @@ export function createFocus({ state: layerState, services, parts, source }) {
|
|||||||
layerId,
|
layerId,
|
||||||
id: String(known.id || known.mmsi),
|
id: String(known.id || known.mmsi),
|
||||||
label: known.label || known.name || known.callsign || String(id),
|
label: known.label || known.name || known.callsign || String(id),
|
||||||
position: Cesium.Cartesian3.clone(known.position),
|
position: geo.cartesian3.clone(known.position),
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -120,7 +121,7 @@ export function createFocus({ state: layerState, services, parts, source }) {
|
|||||||
let closestDistance = Infinity;
|
let closestDistance = Infinity;
|
||||||
for (const candidate of candidates) {
|
for (const candidate of candidates) {
|
||||||
if (!candidate?.position) continue;
|
if (!candidate?.position) continue;
|
||||||
const distance = Cesium.Cartesian3.distance(
|
const distance = geo.cartesian3.distance(
|
||||||
cameraPosition,
|
cameraPosition,
|
||||||
candidate.position,
|
candidate.position,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as Cesium from 'cesium';
|
||||||
|
import * as geo from '../../geo/index.js';
|
||||||
import {
|
import {
|
||||||
createCyberSonarSampler,
|
createCyberSonarSampler,
|
||||||
isCyberContactSonarActive as isCyberSonarActive,
|
isCyberContactSonarActive as isCyberSonarActive,
|
||||||
@@ -132,7 +133,7 @@ export function createRendering({
|
|||||||
|
|
||||||
const cameraHeading = layerState.viewer.camera.heading || 0;
|
const cameraHeading = layerState.viewer.camera.heading || 0;
|
||||||
const headingDeg =
|
const headingDeg =
|
||||||
(Math.round(Cesium.Math.toDegrees(cameraHeading)) + 360) % 360;
|
(Math.round(geo.math.toDegrees(cameraHeading)) + 360) % 360;
|
||||||
layerState.compassRing.style.setProperty(
|
layerState.compassRing.style.setProperty(
|
||||||
'--compass-rotation',
|
'--compass-rotation',
|
||||||
`${-headingDeg}deg`,
|
`${-headingDeg}deg`,
|
||||||
@@ -141,8 +142,8 @@ export function createRendering({
|
|||||||
layerState.compassHeading.style.left = `${geometry.centerX}px`;
|
layerState.compassHeading.style.left = `${geometry.centerX}px`;
|
||||||
layerState.compassHeading.style.top = `${geometry.centerY - compassRadius + 39}px`;
|
layerState.compassHeading.style.top = `${geometry.centerY - compassRadius + 39}px`;
|
||||||
for (const label of layerState.compassLabels) {
|
for (const label of layerState.compassLabels) {
|
||||||
const bearing = Cesium.Math.toRadians(Number(label.dataset.bearing));
|
const bearing = geo.math.toRadians(Number(label.dataset.bearing));
|
||||||
const angle = bearing - cameraHeading - Cesium.Math.PI_OVER_TWO;
|
const angle = bearing - cameraHeading - geo.math.PI_OVER_TWO;
|
||||||
const labelRadius = compassRadius - 17;
|
const labelRadius = compassRadius - 17;
|
||||||
label.style.left = `${geometry.centerX + Math.cos(angle) * labelRadius}px`;
|
label.style.left = `${geometry.centerX + Math.cos(angle) * labelRadius}px`;
|
||||||
label.style.top = `${geometry.centerY + Math.sin(angle) * labelRadius}px`;
|
label.style.top = `${geometry.centerY + Math.sin(angle) * labelRadius}px`;
|
||||||
@@ -166,19 +167,19 @@ export function createRendering({
|
|||||||
marker.hidden = true;
|
marker.hidden = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const direction = Cesium.Cartesian3.subtract(
|
const direction = geo.cartesian3.subtract(
|
||||||
item.position,
|
item.position,
|
||||||
layerState.subject.position,
|
layerState.subject.position,
|
||||||
layerState.DIRECTION_SCRATCH[index],
|
layerState.DIRECTION_SCRATCH[index],
|
||||||
);
|
);
|
||||||
if (Cesium.Cartesian3.magnitudeSquared(direction) < 1) {
|
if (geo.cartesian3.magnitudeSquared(direction) < 1) {
|
||||||
marker.hidden = true;
|
marker.hidden = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Cesium.Cartesian3.normalize(direction, direction);
|
geo.cartesian3.normalize(direction, direction);
|
||||||
const projection = celestialScreenAngle(
|
const projection = celestialScreenAngle(
|
||||||
Cesium.Cartesian3.dot(direction, layerState.viewer.camera.rightWC),
|
geo.cartesian3.dot(direction, layerState.viewer.camera.rightWC),
|
||||||
Cesium.Cartesian3.dot(direction, layerState.viewer.camera.upWC),
|
geo.cartesian3.dot(direction, layerState.viewer.camera.upWC),
|
||||||
marker._lastAngle,
|
marker._lastAngle,
|
||||||
);
|
);
|
||||||
if (projection.stable) marker._lastAngle = projection.angle;
|
if (projection.stable) marker._lastAngle = projection.angle;
|
||||||
@@ -201,12 +202,12 @@ export function createRendering({
|
|||||||
marker._arrow.style.transform = `translate(-50%, -50%) rotate(${projection.angle}rad)`;
|
marker._arrow.style.transform = `translate(-50%, -50%) rotate(${projection.angle}rad)`;
|
||||||
marker._label.style.transform = `translate(-50%, -50%) translate(${-Math.cos(projection.angle) * 56}px, ${-Math.sin(projection.angle) * 56}px)`;
|
marker._label.style.transform = `translate(-50%, -50%) translate(${-Math.cos(projection.angle) * 56}px, ${-Math.sin(projection.angle) * 56}px)`;
|
||||||
const label = formatAwarenessLabel(item);
|
const label = formatAwarenessLabel(item);
|
||||||
const subjectCartographic = Cesium.Cartographic.fromCartesian(
|
const subjectCartographic = geo.cartographic.fromCartesian(
|
||||||
layerState.subject.position,
|
layerState.subject.position,
|
||||||
undefined,
|
undefined,
|
||||||
layerState.SUBJECT_CARTOGRAPHIC_SCRATCH,
|
layerState.SUBJECT_CARTOGRAPHIC_SCRATCH,
|
||||||
);
|
);
|
||||||
const targetCartographic = Cesium.Cartographic.fromCartesian(
|
const targetCartographic = geo.cartographic.fromCartesian(
|
||||||
item.position,
|
item.position,
|
||||||
undefined,
|
undefined,
|
||||||
layerState.TARGET_CARTOGRAPHIC_SCRATCH[index],
|
layerState.TARGET_CARTOGRAPHIC_SCRATCH[index],
|
||||||
@@ -214,10 +215,10 @@ export function createRendering({
|
|||||||
const bearing =
|
const bearing =
|
||||||
subjectCartographic && targetCartographic
|
subjectCartographic && targetCartographic
|
||||||
? bearingBetweenCoordinates(
|
? bearingBetweenCoordinates(
|
||||||
Cesium.Math.toDegrees(subjectCartographic.latitude),
|
geo.math.toDegrees(subjectCartographic.latitude),
|
||||||
Cesium.Math.toDegrees(subjectCartographic.longitude),
|
geo.math.toDegrees(subjectCartographic.longitude),
|
||||||
Cesium.Math.toDegrees(targetCartographic.latitude),
|
geo.math.toDegrees(targetCartographic.latitude),
|
||||||
Cesium.Math.toDegrees(targetCartographic.longitude),
|
geo.math.toDegrees(targetCartographic.longitude),
|
||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
const bearingText = Number.isFinite(bearing)
|
const bearingText = Number.isFinite(bearing)
|
||||||
@@ -243,9 +244,9 @@ export function createRendering({
|
|||||||
|
|
||||||
function renderVisual(subject) {
|
function renderVisual(subject) {
|
||||||
if (!layerState.viewer || !subject?.position) return;
|
if (!layerState.viewer || !subject?.position) return;
|
||||||
const cartographic = Cesium.Cartographic.fromCartesian(subject.position);
|
const cartographic = geo.cartographic.fromCartesian(subject.position);
|
||||||
if (!cartographic) return;
|
if (!cartographic) return;
|
||||||
const groundCenter = Cesium.Cartesian3.fromRadians(
|
const groundCenter = geo.cartesian3.fromRadians(
|
||||||
cartographic.longitude,
|
cartographic.longitude,
|
||||||
cartographic.latitude,
|
cartographic.latitude,
|
||||||
0,
|
0,
|
||||||
@@ -256,12 +257,11 @@ export function createRendering({
|
|||||||
// Move it only after a meaningful displacement so live tracking does not
|
// Move it only after a meaningful displacement so live tracking does not
|
||||||
// churn ten large geometries for sub-pixel motion every 750 ms.
|
// churn ten large geometries for sub-pixel motion every 750 ms.
|
||||||
if (
|
if (
|
||||||
Cesium.Cartesian3.distance(layerState.visual.center, groundCenter) >=
|
geo.cartesian3.distance(layerState.visual.center, groundCenter) >= 250
|
||||||
250
|
|
||||||
) {
|
) {
|
||||||
for (const entity of layerState.visual.entities)
|
for (const entity of layerState.visual.entities)
|
||||||
entity.position.setValue(groundCenter);
|
entity.position.setValue(groundCenter);
|
||||||
Cesium.Cartesian3.clone(groundCenter, layerState.visual.center);
|
geo.cartesian3.clone(groundCenter, layerState.visual.center);
|
||||||
// Content actually changed — buy exactly one frame instead of holding.
|
// Content actually changed — buy exactly one frame instead of holding.
|
||||||
governorRequestRender('awareness-visual');
|
governorRequestRender('awareness-visual');
|
||||||
}
|
}
|
||||||
@@ -289,7 +289,7 @@ export function createRendering({
|
|||||||
layerState.visual = {
|
layerState.visual = {
|
||||||
key,
|
key,
|
||||||
entities,
|
entities,
|
||||||
center: Cesium.Cartesian3.clone(groundCenter),
|
center: geo.cartesian3.clone(groundCenter),
|
||||||
};
|
};
|
||||||
governorRequestRender('awareness-visual');
|
governorRequestRender('awareness-visual');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,16 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
|
|
||||||
export function createState({ services }) {
|
export function createState({ services }) {
|
||||||
const state = {};
|
const state = {};
|
||||||
|
|
||||||
state.DIRECTION_SCRATCH = Array.from(
|
state.DIRECTION_SCRATCH = Array.from({ length: 3 }, () =>
|
||||||
{ length: 3 },
|
geo.cartesian3.create(),
|
||||||
() => new Cesium.Cartesian3(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
state.SUBJECT_CARTOGRAPHIC_SCRATCH = new Cesium.Cartographic();
|
state.SUBJECT_CARTOGRAPHIC_SCRATCH = geo.cartographic.create();
|
||||||
|
|
||||||
state.TARGET_CARTOGRAPHIC_SCRATCH = Array.from(
|
state.TARGET_CARTOGRAPHIC_SCRATCH = Array.from({ length: 3 }, () =>
|
||||||
{ length: 3 },
|
geo.cartographic.create(),
|
||||||
() => new Cesium.Cartographic(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Object.assign(state, {
|
Object.assign(state, {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
AWARENESS_RELATIONSHIP,
|
AWARENESS_RELATIONSHIP,
|
||||||
} from '../../data/militaryAwarenessEngine.js';
|
} from '../../data/militaryAwarenessEngine.js';
|
||||||
import * as Cesium from 'cesium';
|
import * as Cesium from 'cesium';
|
||||||
|
import * as geo from '../../geo/index.js';
|
||||||
import {
|
import {
|
||||||
AWARENESS_QUERY_LIMIT,
|
AWARENESS_QUERY_LIMIT,
|
||||||
SOURCE_LABEL,
|
SOURCE_LABEL,
|
||||||
@@ -218,7 +219,7 @@ export function createSubject({ state: layerState, services, parts, source }) {
|
|||||||
subject,
|
subject,
|
||||||
parts.history.historySourceItem(subject),
|
parts.history.historySourceItem(subject),
|
||||||
),
|
),
|
||||||
position: Cesium.Cartesian3.clone(subject.position),
|
position: geo.cartesian3.clone(subject.position),
|
||||||
});
|
});
|
||||||
layerState.navigationIndex = layerState.navigationHistory.length - 1;
|
layerState.navigationIndex = layerState.navigationHistory.length - 1;
|
||||||
}
|
}
|
||||||
@@ -389,7 +390,7 @@ export function createSubject({ state: layerState, services, parts, source }) {
|
|||||||
const labelChanged = nextLabel !== layerState.subject.label;
|
const labelChanged = nextLabel !== layerState.subject.label;
|
||||||
layerState.subject = { ...layerState.subject, position, label: nextLabel };
|
layerState.subject = { ...layerState.subject, position, label: nextLabel };
|
||||||
const movementM = layerState.lastEvaluatedPosition
|
const movementM = layerState.lastEvaluatedPosition
|
||||||
? Cesium.Cartesian3.distance(layerState.lastEvaluatedPosition, position)
|
? geo.cartesian3.distance(layerState.lastEvaluatedPosition, position)
|
||||||
: Infinity;
|
: Infinity;
|
||||||
if (
|
if (
|
||||||
!parts.model.awarenessRefreshRequired({
|
!parts.model.awarenessRefreshRequired({
|
||||||
@@ -413,7 +414,7 @@ export function createSubject({ state: layerState, services, parts, source }) {
|
|||||||
}
|
}
|
||||||
layerState.results = evaluateSubject(layerState.subject, sources);
|
layerState.results = evaluateSubject(layerState.subject, sources);
|
||||||
layerState.sourceRevision = nextSourceRevision;
|
layerState.sourceRevision = nextSourceRevision;
|
||||||
layerState.lastEvaluatedPosition = Cesium.Cartesian3.clone(
|
layerState.lastEvaluatedPosition = geo.cartesian3.clone(
|
||||||
position,
|
position,
|
||||||
layerState.lastEvaluatedPosition,
|
layerState.lastEvaluatedPosition,
|
||||||
);
|
);
|
||||||
@@ -448,7 +449,7 @@ export function createSubject({ state: layerState, services, parts, source }) {
|
|||||||
id: record.properties?.mmsi || record.id,
|
id: record.properties?.mmsi || record.id,
|
||||||
label: record.label || record.id,
|
label: record.label || record.id,
|
||||||
memberNames: record.properties?.memberNames || [],
|
memberNames: record.properties?.memberNames || [],
|
||||||
position: Cesium.Cartesian3.fromDegrees(longitude, latitude, 0),
|
position: geo.cartesian3.fromDegrees(longitude, latitude, 0),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
|
|
||||||
export function createController({
|
export function createController({
|
||||||
flightState,
|
flightState,
|
||||||
@@ -17,8 +17,8 @@ export function createController({
|
|||||||
const cartographic = viewer?.camera?.positionCartographic;
|
const cartographic = viewer?.camera?.positionCartographic;
|
||||||
return cartographic
|
return cartographic
|
||||||
? {
|
? {
|
||||||
latitude: Cesium.Math.toDegrees(cartographic.latitude),
|
latitude: geo.math.toDegrees(cartographic.latitude),
|
||||||
longitude: Cesium.Math.toDegrees(cartographic.longitude),
|
longitude: geo.math.toDegrees(cartographic.longitude),
|
||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { classifyAircraft } from '../../data/aircraftClass.js';
|
import { classifyAircraft } from '../../data/aircraftClass.js';
|
||||||
import { horizonOccluder } from '../../data/iconOrientation.js';
|
import { horizonOccluder } from '../../data/iconOrientation.js';
|
||||||
import * as Cesium from 'cesium';
|
import * as Cesium from 'cesium';
|
||||||
|
import * as geo from '../../geo/index.js';
|
||||||
import {
|
import {
|
||||||
ENRICH_MAX_INFLIGHT,
|
ENRICH_MAX_INFLIGHT,
|
||||||
ENRICH_DISPATCH_GAP_MS,
|
ENRICH_DISPATCH_GAP_MS,
|
||||||
@@ -200,10 +201,7 @@ export function createEnrichment({
|
|||||||
if (!/^[0-9a-f]{6}$/i.test(icao24)) continue; // adsbdb keys are 6-char hex only
|
if (!/^[0-9a-f]{6}$/i.test(icao24)) continue; // adsbdb keys are 6-char hex only
|
||||||
if (flightState.records.data.get(icao24)?.onGround) continue; // ground traffic never spends ambient budget (click-to-enrich still works)
|
if (flightState.records.data.get(icao24)?.onGround) continue; // ground traffic never spends ambient budget (click-to-enrich still works)
|
||||||
if (!bb.position || !occluder.isPointVisible(bb.position)) continue; // beyond the limb
|
if (!bb.position || !occluder.isPointVisible(bb.position)) continue; // beyond the limb
|
||||||
Cesium.Cartesian3.clone(
|
geo.cartesian3.clone(bb.position, flightState._scratchModelBS.center);
|
||||||
bb.position,
|
|
||||||
flightState._scratchModelBS.center,
|
|
||||||
);
|
|
||||||
if (
|
if (
|
||||||
cull.computeVisibility(flightState._scratchModelBS) ===
|
cull.computeVisibility(flightState._scratchModelBS) ===
|
||||||
Cesium.Intersect.OUTSIDE
|
Cesium.Intersect.OUTSIDE
|
||||||
@@ -211,7 +209,7 @@ export function createEnrichment({
|
|||||||
continue; // off-screen
|
continue; // off-screen
|
||||||
cand.push([
|
cand.push([
|
||||||
icao24,
|
icao24,
|
||||||
Cesium.Cartesian3.distanceSquared(camPos, bb.position),
|
geo.cartesian3.distanceSquared(camPos, bb.position),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
cand.sort((a, b) => a[1] - b[1]); // nearest first — what the user is looking at resolves first
|
cand.sort((a, b) => a[1] - b[1]); // nearest first — what the user is looking at resolves first
|
||||||
|
|||||||
Vendored
+5
-5
@@ -3,7 +3,7 @@ import {
|
|||||||
satelliteClassLabel,
|
satelliteClassLabel,
|
||||||
satelliteClassLegend,
|
satelliteClassLegend,
|
||||||
} from '../../data/satelliteClass.js';
|
} from '../../data/satelliteClass.js';
|
||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
import { ISS_NORAD, POINT_STYLES } from './policy.js';
|
import { ISS_NORAD, POINT_STYLES } from './policy.js';
|
||||||
|
|
||||||
export function createControls({ state: layerState, services, parts, source }) {
|
export function createControls({ state: layerState, services, parts, source }) {
|
||||||
@@ -195,7 +195,7 @@ export function createControls({ state: layerState, services, parts, source }) {
|
|||||||
return {
|
return {
|
||||||
noradId,
|
noradId,
|
||||||
name: sat.name.trim(),
|
name: sat.name.trim(),
|
||||||
position: Cesium.Cartesian3.fromDegrees(
|
position: geo.cartesian3.fromDegrees(
|
||||||
pos.longitude,
|
pos.longitude,
|
||||||
pos.latitude,
|
pos.latitude,
|
||||||
pos.altitude,
|
pos.altitude,
|
||||||
@@ -227,15 +227,15 @@ export function createControls({ state: layerState, services, parts, source }) {
|
|||||||
layerState._catalog.get(noradId)?.group === 'dense'
|
layerState._catalog.get(noradId)?.group === 'dense'
|
||||||
)
|
)
|
||||||
continue;
|
continue;
|
||||||
const carto = Cesium.Cartographic.fromCartesian(point.position);
|
const carto = geo.cartographic.fromCartesian(point.position);
|
||||||
if (!carto) continue;
|
if (!carto) continue;
|
||||||
const sat = layerState._catalog.get(noradId);
|
const sat = layerState._catalog.get(noradId);
|
||||||
result.push({
|
result.push({
|
||||||
id: noradId,
|
id: noradId,
|
||||||
label: sat ? sat.name.trim() : String(noradId),
|
label: sat ? sat.name.trim() : String(noradId),
|
||||||
position: point.position,
|
position: point.position,
|
||||||
latitude: Cesium.Math.toDegrees(carto.latitude),
|
latitude: geo.math.toDegrees(carto.latitude),
|
||||||
longitude: Cesium.Math.toDegrees(carto.longitude),
|
longitude: geo.math.toDegrees(carto.longitude),
|
||||||
altitudeM: carto.height,
|
altitudeM: carto.height,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
import {
|
import {
|
||||||
gstime,
|
gstime,
|
||||||
propagate,
|
propagate,
|
||||||
@@ -24,16 +24,16 @@ export function createOrbits({ state: layerState, services, parts, source }) {
|
|||||||
function orbitFrameModelMatrix(
|
function orbitFrameModelMatrix(
|
||||||
gmstAtBake,
|
gmstAtBake,
|
||||||
nowDate,
|
nowDate,
|
||||||
result = new Cesium.Matrix4(),
|
result = geo.matrix4.create(),
|
||||||
) {
|
) {
|
||||||
const deltaGmst = gstime(nowDate) - gmstAtBake;
|
const deltaGmst = gstime(nowDate) - gmstAtBake;
|
||||||
const rotation = Cesium.Matrix3.fromRotationZ(
|
const rotation = geo.matrix3.fromRotationZ(
|
||||||
-deltaGmst,
|
-deltaGmst,
|
||||||
layerState._scratchRingRotation,
|
layerState._scratchRingRotation,
|
||||||
);
|
);
|
||||||
return Cesium.Matrix4.fromRotationTranslation(
|
return geo.matrix4.fromRotationTranslation(
|
||||||
rotation,
|
rotation,
|
||||||
Cesium.Cartesian3.ZERO,
|
geo.cartesian3.ZERO,
|
||||||
result,
|
result,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ export function createOrbits({ state: layerState, services, parts, source }) {
|
|||||||
if (!posVel.position || typeof posVel.position === 'boolean') return null;
|
if (!posVel.position || typeof posVel.position === 'boolean') return null;
|
||||||
|
|
||||||
const gmst = gstime(date);
|
const gmst = gstime(date);
|
||||||
const geo = eciToGeodetic(posVel.position, gmst);
|
const geodetic = eciToGeodetic(posVel.position, gmst);
|
||||||
const velocity =
|
const velocity =
|
||||||
posVel.velocity && typeof posVel.velocity !== 'boolean'
|
posVel.velocity && typeof posVel.velocity !== 'boolean'
|
||||||
? posVel.velocity
|
? posVel.velocity
|
||||||
@@ -65,9 +65,9 @@ export function createOrbits({ state: layerState, services, parts, source }) {
|
|||||||
: null;
|
: null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
longitude: degreesLong(geo.longitude),
|
longitude: degreesLong(geodetic.longitude),
|
||||||
latitude: degreesLat(geo.latitude),
|
latitude: degreesLat(geodetic.latitude),
|
||||||
altitude: geo.height * 1000, // km → meters
|
altitude: geodetic.height * 1000, // km → meters
|
||||||
speedMps: Number.isFinite(speedMps) ? speedMps : null,
|
speedMps: Number.isFinite(speedMps) ? speedMps : null,
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
@@ -101,12 +101,12 @@ export function createOrbits({ state: layerState, services, parts, source }) {
|
|||||||
try {
|
try {
|
||||||
const posVel = propagate(satrec, t);
|
const posVel = propagate(satrec, t);
|
||||||
if (!posVel.position || typeof posVel.position === 'boolean') continue;
|
if (!posVel.position || typeof posVel.position === 'boolean') continue;
|
||||||
const geo = eciToGeodetic(posVel.position, fixedGmst);
|
const geodetic = eciToGeodetic(posVel.position, fixedGmst);
|
||||||
positions.push(
|
positions.push(
|
||||||
Cesium.Cartesian3.fromDegrees(
|
geo.cartesian3.fromDegrees(
|
||||||
degreesLong(geo.longitude),
|
degreesLong(geodetic.longitude),
|
||||||
degreesLat(geo.latitude),
|
degreesLat(geodetic.latitude),
|
||||||
geo.height * 1000,
|
geodetic.height * 1000,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
import { satelliteClassLabel } from '../../data/satelliteClass.js';
|
import { satelliteClassLabel } from '../../data/satelliteClass.js';
|
||||||
import { ISS_NORAD } from './policy.js';
|
import { ISS_NORAD } from './policy.js';
|
||||||
|
|
||||||
@@ -62,11 +62,11 @@ export function createRecords({ state, parts }) {
|
|||||||
}
|
}
|
||||||
const point = state._points.get(noradId);
|
const point = state._points.get(noradId);
|
||||||
if (!point?.position) return null;
|
if (!point?.position) return null;
|
||||||
const carto = Cesium.Cartographic.fromCartesian(point.position);
|
const carto = geo.cartographic.fromCartesian(point.position);
|
||||||
if (!carto) return null;
|
if (!carto) return null;
|
||||||
return {
|
return {
|
||||||
lat: Cesium.Math.toDegrees(carto.latitude),
|
lat: geo.math.toDegrees(carto.latitude),
|
||||||
lon: Cesium.Math.toDegrees(carto.longitude),
|
lon: geo.math.toDegrees(carto.longitude),
|
||||||
altitudeM: carto.height,
|
altitudeM: carto.height,
|
||||||
speedMps: null,
|
speedMps: null,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
|
|
||||||
export function createState({ services }) {
|
export function createState({ services }) {
|
||||||
const { setOverlayEntries, setOverlaySourceVisible, clearOverlaySource } =
|
const { setOverlayEntries, setOverlaySourceVisible, clearOverlaySource } =
|
||||||
@@ -58,7 +58,7 @@ export function createState({ services }) {
|
|||||||
|
|
||||||
state._activeFocusCount = 0;
|
state._activeFocusCount = 0;
|
||||||
|
|
||||||
state._scratchFocusScreen = new Cesium.Cartesian2();
|
state._scratchFocusScreen = geo.cartesian2.create();
|
||||||
|
|
||||||
state._enabled = false;
|
state._enabled = false;
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ export function createState({ services }) {
|
|||||||
state._trackedFrameGeo = null;
|
state._trackedFrameGeo = null;
|
||||||
// { longitude, latitude, altitude } or null
|
// { longitude, latitude, altitude } or null
|
||||||
|
|
||||||
state._trackedFrameCartesian = new Cesium.Cartesian3();
|
state._trackedFrameCartesian = geo.cartesian3.create();
|
||||||
|
|
||||||
/** Optional deterministic clock used only by the production-frame test seam. */
|
/** Optional deterministic clock used only by the production-frame test seam. */
|
||||||
|
|
||||||
@@ -149,9 +149,9 @@ export function createState({ services }) {
|
|||||||
|
|
||||||
// Scratch variables
|
// Scratch variables
|
||||||
|
|
||||||
state._scratchCartesian = new Cesium.Cartesian3();
|
state._scratchCartesian = geo.cartesian3.create();
|
||||||
|
|
||||||
state._scratchRingRotation = new Cesium.Matrix3();
|
state._scratchRingRotation = geo.matrix3.create();
|
||||||
|
|
||||||
/** Update the explicit model only when the rounded altitude line changes. */
|
/** Update the explicit model only when the rounded altitude line changes. */
|
||||||
/** Epoch of the last shared-context refresh for the tracked satellite. */
|
/** Epoch of the last shared-context refresh for the tracked satellite. */
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
import { viewAreaRadiusKm } from './viewArea.js';
|
import { viewAreaRadiusKm } from './viewArea.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,16 +18,16 @@ export function vesselViewArea(viewer) {
|
|||||||
if (canvas?.clientWidth && canvas?.clientHeight) {
|
if (canvas?.clientWidth && canvas?.clientHeight) {
|
||||||
try {
|
try {
|
||||||
const hit = camera.pickEllipsoid(
|
const hit = camera.pickEllipsoid(
|
||||||
new Cesium.Cartesian2(canvas.clientWidth / 2, canvas.clientHeight / 2),
|
geo.cartesian2.create(canvas.clientWidth / 2, canvas.clientHeight / 2),
|
||||||
scene.globe?.ellipsoid,
|
scene.globe?.ellipsoid,
|
||||||
);
|
);
|
||||||
if (hit) center = Cesium.Cartographic.fromCartesian(hit);
|
if (hit) center = geo.cartographic.fromCartesian(hit);
|
||||||
} catch {
|
} catch {
|
||||||
/* the camera position stands in */
|
/* the camera position stands in */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const lat = Cesium.Math.toDegrees(center.latitude);
|
const lat = geo.math.toDegrees(center.latitude);
|
||||||
const lon = Cesium.Math.toDegrees(center.longitude);
|
const lon = geo.math.toDegrees(center.longitude);
|
||||||
if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;
|
if (!Number.isFinite(lat) || !Number.isFinite(lon)) return null;
|
||||||
return { lat, lon, radiusKm };
|
return { lat, lon, radiusKm };
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
import {
|
import {
|
||||||
AIS_DEGRADED_STATUSES,
|
AIS_DEGRADED_STATUSES,
|
||||||
AIS_HEALTHY_STATUSES,
|
AIS_HEALTHY_STATUSES,
|
||||||
@@ -316,7 +316,7 @@ export function createQueries({
|
|||||||
continue;
|
continue;
|
||||||
const position = visual.billboard?.position || visual.position;
|
const position = visual.billboard?.position || visual.position;
|
||||||
if (!position) continue;
|
if (!position) continue;
|
||||||
const distanceM = Cesium.Cartesian3.distance(centerCartesian, position);
|
const distanceM = geo.cartesian3.distance(centerCartesian, position);
|
||||||
if (!Number.isFinite(distanceM) || distanceM > range) continue;
|
if (!Number.isFinite(distanceM) || distanceM > range) continue;
|
||||||
entries.push({
|
entries.push({
|
||||||
mmsi: record.mmsi,
|
mmsi: record.mmsi,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { createVesselFeed } from './ingestion.js';
|
import { createVesselFeed } from './ingestion.js';
|
||||||
import { VesselRecords } from './records.js';
|
import { VesselRecords } from './records.js';
|
||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
import { DEFAULT_AIS_RUNTIME } from './policy.js';
|
import { DEFAULT_AIS_RUNTIME } from './policy.js';
|
||||||
|
|
||||||
export function createVesselState({ source, services }) {
|
export function createVesselState({ source, services }) {
|
||||||
@@ -18,7 +18,7 @@ export function createVesselState({ source, services }) {
|
|||||||
|
|
||||||
vesselState._lastCamPoseSig = '';
|
vesselState._lastCamPoseSig = '';
|
||||||
|
|
||||||
vesselState._scratchFocusScreen = new Cesium.Cartesian2();
|
vesselState._scratchFocusScreen = geo.cartesian2.create();
|
||||||
|
|
||||||
vesselState.DEFAULT_VESSEL_OVERLAY_HOST = Object.freeze({
|
vesselState.DEFAULT_VESSEL_OVERLAY_HOST = Object.freeze({
|
||||||
setEntries: setOverlayEntries,
|
setEntries: setOverlayEntries,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as Cesium from 'cesium';
|
import * as geo from '../../geo/index.js';
|
||||||
import {
|
import {
|
||||||
TRAIL_HEIGHT_M,
|
TRAIL_HEIGHT_M,
|
||||||
VESSEL_LIFT_M,
|
VESSEL_LIFT_M,
|
||||||
@@ -44,7 +44,7 @@ export function createTracking({
|
|||||||
currentGeoidN(record.lat, record.lon),
|
currentGeoidN(record.lat, record.lon),
|
||||||
TRAIL_HEIGHT_M,
|
TRAIL_HEIGHT_M,
|
||||||
);
|
);
|
||||||
return Cesium.Cartesian3.fromDegrees(record.lon, record.lat, heightM);
|
return geo.cartesian3.fromDegrees(record.lon, record.lat, heightM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,7 +66,7 @@ export function createTracking({
|
|||||||
currentGeoidN(record.lat, record.lon),
|
currentGeoidN(record.lat, record.lon),
|
||||||
VESSEL_LIFT_M,
|
VESSEL_LIFT_M,
|
||||||
);
|
);
|
||||||
visual.position = Cesium.Cartesian3.fromDegrees(
|
visual.position = geo.cartesian3.fromDegrees(
|
||||||
record.lon,
|
record.lon,
|
||||||
record.lat,
|
record.lat,
|
||||||
heightM,
|
heightM,
|
||||||
@@ -146,7 +146,7 @@ export function createTracking({
|
|||||||
currentGeoidN(lat, lon),
|
currentGeoidN(lat, lon),
|
||||||
TRAIL_HEIGHT_M,
|
TRAIL_HEIGHT_M,
|
||||||
);
|
);
|
||||||
older.push(Cesium.Cartesian3.fromDegrees(lon, lat, heightM));
|
older.push(geo.cartesian3.fromDegrees(lon, lat, heightM));
|
||||||
}
|
}
|
||||||
if (!older.length) return;
|
if (!older.length) return;
|
||||||
|
|
||||||
@@ -170,8 +170,7 @@ export function createTracking({
|
|||||||
const next = vesselTrailPosition(record);
|
const next = vesselTrailPosition(record);
|
||||||
if (!next) return;
|
if (!next) return;
|
||||||
const last = state.trailPositions[state.trailPositions.length - 1];
|
const last = state.trailPositions[state.trailPositions.length - 1];
|
||||||
if (last && Cesium.Cartesian3.distance(last, next) <= TRAIL_MIN_MOVE_M)
|
if (last && geo.cartesian3.distance(last, next) <= TRAIL_MIN_MOVE_M) return;
|
||||||
return;
|
|
||||||
state.trailPositions.push(next);
|
state.trailPositions.push(next);
|
||||||
if (state.trailPositions.length > TRAIL_MAX_POINTS)
|
if (state.trailPositions.length > TRAIL_MAX_POINTS)
|
||||||
state.trailPositions.shift();
|
state.trailPositions.shift();
|
||||||
|
|||||||
Reference in new issue
Block a user