How to Manage Detection Density and Visibility Rules in CesiumJS
Separate pure policy logic from Cesium-specific rendering to enforce consistent detection density limits and dynamic bracket opacity across all interaction modalities.
The bilawalsidhu/gods-eye-view repository demonstrates a robust architecture for managing detection density and visibility rules in CesiumJS applications. By isolating policy decisions in pure JavaScript modules, the system prevents UI drift and ensures that camera altitude, density sliders, and view modes produce predictable, testable results.
Architecture Overview
The codebase splits responsibilities between policy modules (pure logic) and rendering modules (Cesium/Canvas interactions). This separation ensures that rules governing how many detections to show and how visible they should be remain consistent whether the user interacts via UI sliders, share links, or voice commands.
Key files in this architecture include:
src/data/detectionPolicy.js– Defines density stops, view-scale budgets, and opacity calculations.src/data/detectionPresentation.js– Contains view-mode specific multipliers like cockpit opacity reductions.src/data/detectionDraw.js– Handles Canvas2D rendering using values computed by the policy modules.
Configuring Detection Density Stops and Budgets
Detection density is expressed as a percentage (0–100) but constrained to five canonical stops defined by the DENSITY_STOPS constant. This prevents arbitrary values from creating inconsistent behavior between the UI state and the rendered output.
Canonical Density Stops
The system uses canonicalizeDensity to snap any input value to the nearest approved stop. This ensures that a density setting of 73% resolves to a concrete profile (e.g., BALANCED) rather than floating between discrete states.
Functions like profileForDensity and defaultDensityForProfile translate these percentages into semantic labels (SPARSE, BALANCED, DENSE) that drive both UI cues and rendering budgets.
View-Scale Label Budgets
The labelBudgetFor function determines how many detection labels can appear simultaneously based on camera altitude and current density:
import { viewScaleForAltitude, labelBudgetFor } from './data/detectionPolicy.js';
// Map camera altitude (meters) to view scale label
const scale = viewScaleForAltitude(15000); // Returns 'city', 'metro', etc.
// Get maximum labels allowed for this scale and density
const maxLabels = labelBudgetFor(15000, 75); // Returns budget from VIEW_SCALE_BUDGETS
The VIEW_SCALE_BUDGETS lookup table enforces hard limits: a street view at 100% density permits 90 labels, while a global view at identical density allows only 56.
Implementing Visibility Rules and Bracket Opacity
Visibility rules govern the opacity of detection brackets (the UI elements surrounding tracked objects) independently of the underlying detection call-outs. This ensures that brackets remain visible enough to be useful without cluttering the view.
Aircraft Bracket Alpha Calculations
The detectionBracketAlpha function in src/data/detectionPolicy.js computes final opacity using a piecewise-linear floor to prevent "dead zones" in the control range:
import {
aircraftBracketAlphaFloor,
detectionBracketAlpha
} from './data/detectionPolicy.js';
// Compute minimum opacity floor based on outside opacity setting
const floor = aircraftBracketAlphaFloor(0.8);
// Calculate final bracket alpha for AIR type, respecting keyhole and floor
const alpha = detectionBracketAlpha('AIR', keyholeAlpha, outsideOpacity);
For AIR type detections, the function applies the floor computed by aircraftBracketAlphaFloor, ensuring the bracket never becomes completely invisible. Other detection types preserve any lower opacity values set by the keyhole logic.
Cockpit View Multipliers
When the user switches to cockpit view, the system reduces bracket stroke opacity using detectionBracketOpacity from src/data/detectionPresentation.js:
import { detectionBracketOpacity } from './data/detectionPresentation.js';
const COCKPIT_BRACKET_OPACITY = 0.3; // Defined in detectionPresentation.js
const finalAlpha = baseAlpha * detectionBracketOpacity(cockpitActive);
This multiplier affects only the visual bracket rendering, preserving full opacity for underlying detection data and UI controls.
The Detection Rendering Pipeline
When density or camera state changes, the system executes a four-stage pipeline:
- Normalize incoming values using
canonicalizeDensityandprofileForDensityto prevent drift between UI modalities. - Derive the current view scale via
viewScaleForAltitudebased on camera altitude. - Lookup thelabel budget through
labelBudgetForto determine the maximum detection count. - Apply per-bracket opacity rules using
detectionBracketAlphaand view-specific multipliers likedetectionBracketOpacity.
This flow guarantees that a density change triggered by a voice command produces identical results to one triggered by a UI slider or share-link parameter.
Practical Implementation Examples
Updating Density from UI Controls
import {
canonicalizeDensity,
profileForDensity,
labelBudgetFor,
detectionBracketAlpha,
} from './data/detectionPolicy.js';
import { detectionBracketOpacity } from './data/detectionPresentation.js';
function onDensityChange(rawPct, profile, cameraAltitude, outsideOpacity, cockpitActive) {
// Snap to legal stop
const densityPct = canonicalizeDensity(rawPct);
const normalizedProfile = profileForDensity(densityPct);
// Compute render budget
const maxLabels = labelBudgetFor(cameraAltitude, densityPct);
// Calculate bracket opacity
const keyholeAlpha = 0.6;
const bracketAlpha = detectionBracketAlpha('AIR', keyholeAlpha, outsideOpacity);
const finalBracketAlpha = bracketAlpha * detectionBracketOpacity(cockpitActive);
renderDetections({
maxLabels,
bracketAlpha: finalBracketAlpha,
profile: normalizedProfile,
});
}
Rendering with Canvas2D
import { measureLabelCard } from './data/detectionDraw.js';
function renderDetections({ maxLabels, bracketAlpha, profile }) {
const ctx = canvas.getContext('2d');
ctx.lineWidth = 2;
ctx.strokeStyle = `rgba(255,255,255,${bracketAlpha})`;
detections.slice(0, maxLabels).forEach(det => {
const { primary, secondary } = composeLabel(det);
const card = measureLabelCard(primary, secondary, CHAR_WIDTH);
// Draw rounded rect, accent bar, and text...
});
}
Determining Horizontal Sectors
import { detectionHorizontalSector } from './data/detectionPolicy.js';
function sectorForDetection(screenX, viewportWidth) {
// Returns 'left', 'front', or 'right' for UI placement and diagnostics
return detectionHorizontalSector(screenX, viewportWidth);
}
Summary
src/data/detectionPolicy.jscontains the pure logic for density stops, view-scale budgets, and bracket opacity floors, making it testable without Cesium dependencies.canonicalizeDensityprevents UI drift by snapping all inputs to five canonical stops before processing.labelBudgetForenforces performance constraints by mapping altitude and density to concrete label limits.detectionBracketAlphaensures honest opacity controls for aircraft brackets using piecewise-linear floors.detectionPresentation.jsprovides view-mode specific multipliers (like cockpit opacity reduction) without affecting underlying detection data.
Frequently Asked Questions
How does the system prevent slider drift between different input methods?
The canonicalizeDensity function in src/data/detectionPolicy.js normalizes all incoming values—whether from UI sliders, share-links, or voice commands—to the nearest approved stop in DENSITY_STOPS. This ensures that a 73% input resolves to the same canonical value regardless of input modality, preventing state divergence between the URL, UI display, and renderer.
Why separate detection policy from Cesium-specific rendering code?
Separating concerns allows the policy logic to remain pure (free of Cesium, DOM, or canvas dependencies), enabling unit testing in isolation and reuse across different renderers. The Canvas2D overlay in src/data/detectionDraw.js simply consumes values computed by detectionPolicy.js, making the system immune to Cesium API changes and easier to maintain.
How is the maximum number of detection labels calculated?
The labelBudgetFor function combines the current camera altitude (mapped to a view scale via viewScaleForAltitude) with the canonicalized density percentage to lookup a hard limit in the VIEW_SCALE_BUDGETS table. For example, street-level views at maximum density permit 90 labels, while global views permit only 56, ensuring consistent performance across zoom levels.
What prevents aircraft brackets from becoming completely invisible?
The aircraftBracketAlphaFloor function computes a piecewise-linear minimum opacity based on the outsideOpacity parameter. When detectionBracketAlpha processes AIR type detections, it applies this floor to the calculated opacity, ensuring brackets remain visible even when other detection types might fade due to keyhole logic or distance culling.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →