mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 02:44:02 +00:00
fix(cctv): surface heading confidence — estimated bearings are now visible
Every pack sets headingConfidence on each camera, but nothing consumed it: a bearing synthesized by fallbackHeadingFromId (a hash of the id string, no geographic input) rendered exactly like a surveyed one — 2,827 of 3,997 cameras in a default catalog. Fixes #639. Two consumers, plus a passthrough: - HUD: the heading token is tagged when the bearing is synthetic — `HDG 194° (ESTIMATED)` — so a hash never reads as a measured facing. - Wireframe: a low-confidence camera draws its coverage frustum with dashed polylines instead of solid ones. Colors, widths, and the active/idle emphasis are unchanged; the dash is the only signal. - Public camera state gains `headingConfidence` (the raw pack flag) and `headingEstimated` (the derived bit) so UI consumers never re-derive it. A human-vouched pose always wins over the pack flag: a manually saved calibration (calSource:'manual') or a curated catalog entry (poseSource:'curated') is never presented as estimated, mirroring the CAL badge states in calibration.js. - src/layers/cctv/headingConfidence.js: pure helpers (isHeadingEstimated, headingHudToken) - src/layers/cctv/headingConfidence.test.mjs: confidence normalization, calibration/curation overrides, HUD token formatting - src/layers/cctv/presentation.js: HUD token + public-state passthrough - src/layers/cctv/rendering.js: dashed materials for estimated bearings
This commit is contained in:
1 parent
0d41b6be54
commit
5f27f6edf4
4 files changed
+144
-15
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { CCTV_AMBIENT_CARD_MAX } from '../../data/cctvLod.js';
|
||||
import { ACTIVE_FRAME_REFRESH_MS, IDLE_FRAME_REFRESH_MS } from './policy.js';
|
||||
import { headingHudToken, isHeadingEstimated } from './headingConfidence.js';
|
||||
|
||||
export function createPresentation({
|
||||
state: layerState,
|
||||
@@ -35,7 +36,9 @@ export function createPresentation({
|
||||
return [
|
||||
`${active.camera.city.toUpperCase()} CCTV`,
|
||||
`${active.camera.name.toUpperCase()}`,
|
||||
`HDG ${Math.round(active.camera.headingDeg)}°`,
|
||||
// A synthetic bearing (headingConfidence 'low', no human calibration)
|
||||
// is tagged so a hashed guess never reads as a surveyed facing (#639).
|
||||
headingHudToken(active.camera),
|
||||
`FOV ${Math.round(active.camera.fovDeg)}°`,
|
||||
`COVERAGE ${area.toFixed(2)}km²`,
|
||||
overlapCount > 0 ? `OVERLAP ${overlapCount} cams` : 'ISOLATED VIEW',
|
||||
@@ -76,6 +79,11 @@ export function createPresentation({
|
||||
lat: camera.lat,
|
||||
lon: camera.lon,
|
||||
headingDeg: camera.headingDeg,
|
||||
// Bearing provenance (#639): the pack's confidence flag plus the derived
|
||||
// "is this a synthetic guess" bit (calibration-aware), so UI consumers
|
||||
// never have to re-derive it.
|
||||
headingConfidence: camera.headingConfidence || null,
|
||||
headingEstimated: isHeadingEstimated(camera),
|
||||
pitchDeg: camera.pitchDeg,
|
||||
fovDeg: camera.fovDeg,
|
||||
rangeM: camera.rangeM,
|
||||
|
||||
Reference in new issue
Block a user