mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
feat(flights): publish verticalRateMps on the tracked-aircraft descriptor
`mapAnalystRecord` has always published `verticalRateMps`, but the tracked seam — `getTrackedInfo()` / `getTrackedSubject()`, built by `_describeFlight` — did not, so anything needing climb/descent had to reach past the public descriptor into the raw poll record. Both layers now map it, which matters because they store it under different keys: the civil records write `verticalRate` (records.js), the military ones write `verticalRateMps`. Mapping only one would leave `resolveTrackedAircraftInfo()` handing back two different shapes, and a consumer reading the field off a civil contact would silently read every military contact as level flight. Reported, never derived. `stickyNumber` seeds the field with null, so an aircraft that has not transmitted a rate publishes null rather than a level-flight 0 — absent is not level, and a flight-phase classifier that cannot tell them apart calls a climbing aircraft cruise. Tests: both layers, both halves (a reported rate arrives with its sign; an absent one stays null). Mutation-verified — removing either field or defaulting it to 0 turns them red. `docs/CURRENT-STATE.md` records the descriptor field, the two record keys it reconciles, and the reported-never-derived rule.
This commit is contained in:
1 parent
b210ab0fe4
commit
936d75b69e
6 files changed
+125
-5
No files matched your search
@@ -113,7 +113,7 @@ export function createQueries({
|
||||
* Build a public descriptor for one aircraft using its best current position
|
||||
* (dead-reckoned when history exists, billboard position otherwise).
|
||||
* @param {string} icao24 - ICAO 24-bit transponder address.
|
||||
* @returns {{icao24: string, callsign: string|null, position: Cesium.Cartesian3, latitude: number, longitude: number, altitudeM: number, velocityMps: number|null, track: number|null}|null}
|
||||
* @returns {{icao24: string, callsign: string|null, position: Cesium.Cartesian3, latitude: number, longitude: number, altitudeM: number, velocityMps: number|null, track: number|null, verticalRateMps: number|null}|null}
|
||||
* Descriptor with a cloned position, or null if the aircraft is unknown.
|
||||
*/
|
||||
|
||||
@@ -163,6 +163,15 @@ export function createQueries({
|
||||
onGround: info?.onGround === true,
|
||||
velocityMps: displayed.speedMps,
|
||||
track: displayed.trackDeg,
|
||||
// Climb/descent rate, the one kinematic field `mapAnalystRecord` already
|
||||
// published (as `verticalRateMps`) but this descriptor did not, so a
|
||||
// consumer reading the tracked seam had to reach back into `_flightData`
|
||||
// for it. Reported, never derived: `stickyNumber` in records.js keeps the
|
||||
// last value across a blank poll, and an absent rate stays null rather
|
||||
// than becoming a level-flight 0 the aircraft never transmitted.
|
||||
verticalRateMps: Number.isFinite(info?.verticalRate)
|
||||
? info.verticalRate
|
||||
: null,
|
||||
stale: Boolean(
|
||||
flightState.records.missingPolls.get(icao24) ||
|
||||
flightState.feed._backoff,
|
||||
@@ -834,7 +843,7 @@ export function createQueries({
|
||||
|
||||
/**
|
||||
* Describe the currently tracked aircraft at its dead-reckoned position.
|
||||
* @returns {{icao24: string, callsign: string|null, latitude: number, longitude: number, altitudeM: number, velocityMps: number|null, track: number|null}|null}
|
||||
* @returns {{icao24: string, callsign: string|null, latitude: number, longitude: number, altitudeM: number, velocityMps: number|null, track: number|null, verticalRateMps: number|null}|null}
|
||||
* Tracked aircraft info, or null when nothing is tracked.
|
||||
*/
|
||||
getTrackedInfo() {
|
||||
|
||||
@@ -86,7 +86,7 @@ export function createQueries({
|
||||
* Build a public descriptor for one aircraft using its best current position
|
||||
* (dead-reckoned when history exists, billboard position otherwise).
|
||||
* @param {string} icao24 - ICAO hex identifier of the aircraft.
|
||||
* @returns {{icao24: string, callsign: string|null, position: Cesium.Cartesian3, latitude: number, longitude: number, altitudeM: number, velocityMps: number|null, track: number|null}|null}
|
||||
* @returns {{icao24: string, callsign: string|null, position: Cesium.Cartesian3, latitude: number, longitude: number, altitudeM: number, velocityMps: number|null, track: number|null, verticalRateMps: number|null}|null}
|
||||
* Descriptor with a cloned position, or null if the aircraft is unknown.
|
||||
*/
|
||||
|
||||
@@ -129,6 +129,13 @@ export function createQueries({
|
||||
onGround: info?.onGround === true,
|
||||
velocityMps: displayed.speedMps,
|
||||
track: displayed.trackDeg,
|
||||
// Same field, same name, same null-when-absent rule as the civil
|
||||
// descriptor — the two layers store the record under different keys
|
||||
// (`verticalRateMps` here, `verticalRate` there), so only the mapping
|
||||
// makes `resolveTrackedAircraftInfo` hand back one shape for both.
|
||||
verticalRateMps: Number.isFinite(info?.verticalRateMps)
|
||||
? info.verticalRateMps
|
||||
: null,
|
||||
stale: Boolean(
|
||||
flightState.records.missingPolls.get(icao24) ||
|
||||
flightState.feed._backoff,
|
||||
@@ -755,7 +762,7 @@ export function createQueries({
|
||||
|
||||
/**
|
||||
* Describe the currently tracked aircraft at its dead-reckoned position.
|
||||
* @returns {{icao24: string, callsign: string|null, latitude: number, longitude: number, altitudeM: number, velocityMps: number|null, track: number|null}|null}
|
||||
* @returns {{icao24: string, callsign: string|null, latitude: number, longitude: number, altitudeM: number, velocityMps: number|null, track: number|null, verticalRateMps: number|null}|null}
|
||||
* Tracked aircraft info, or null when nothing is tracked.
|
||||
*/
|
||||
getTrackedInfo() {
|
||||
|
||||
Reference in new issue
Block a user