# How God’s Eye View Resolves Metadata for Tracked Entities: Context Store Architecture

> Discover how God's Eye View resolves metadata for tracked entities using its context store architecture. Learn about registering, selecting, and refreshing entity contexts efficiently.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: architecture
- Published: 2026-09-13

---

**God’s Eye View resolves metadata for tracked entities through a centralized context store that maps every subject to a metadata record via `registerEntityContext`, retrieves current state via `selectTrackedSubjectContext`, and merges telemetry updates via `refreshTrackedSubjectContext` while preserving sticky fields.**

God’s Eye View (GEV) is an open-source geospatial visualization project (`bilawalsidhu/gods-eye-view`) that tracks aircraft, satellites, and maritime vessels in real time. When telemetry arrives from various data layers, the application must resolve which metadata belongs to which visual entity and ensure that critical identifiers remain stable across updates. This resolution logic is centralized in [`src/data/contextStore.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/contextStore.js), which maintains a single source of truth for all tracked subject metadata through a pipeline of registration, selection, and refresh operations.

## The Metadata Resolution Pipeline

The context store implements a three-phase resolution pipeline that handles the complete lifecycle of entity metadata. Each phase corresponds to a specific function exported from the store module, operating on a global `Map` structure that maps entity identifiers to their associated metadata records.

### Registration via registerEntityContext

When a new subject appears in the telemetry stream—whether an aircraft entering the surveillance area or a satellite passing overhead—the owning layer invokes `registerEntityContext(entity, metadata)`. This function creates a metadata record containing at minimum the `id` (unique identifier) and `layerId` (source layer), then stores it in the global `store.entities` Map. According to the source implementation in [`src/data/contextStore.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/contextStore.js), this establishes the initial metadata baseline that subsequent operations will reference.

### Selection via selectTrackedSubjectContext

UI components such as the cockpit HUD, flight tracking overlays, or military contact displays retrieve metadata through `selectTrackedSubjectContext(metadata)`. This function queries the global store using the provided identifier and returns the existing record if found. If no record exists—indicating the entity has not yet been registered or has been purged—the function returns null, allowing the calling component to handle the absence gracefully. This selection mechanism ensures that all UI elements read from the same centralized state rather than maintaining isolated copies.

### Refresh via refreshTrackedSubjectContext

As real-time telemetry arrives—new AIS messages for vessels, ADS-B updates for aircraft, or orbital elements for satellites—the system must merge fresh data with existing records without destroying stable identifiers. The `refreshTrackedSubjectContext(metadata)` function handles this merge operation, updating fields like altitude, speed, or position while preserving "sticky" metadata that should survive across updates, such as aircraft registrations or vessel IMO numbers.

### Sticky Metadata Preservation

Certain fields in the metadata record are designated as **sticky**: once they receive a non-null value, subsequent telemetry updates cannot overwrite them. This behavior, implemented within the merge logic of `registerEntityContext` and `refreshTrackedSubjectContext`, guarantees that stable identifiers remain constant even if upstream data sources temporarily omit them or provide conflicting values. The system checks incoming values against a `STICKY_FIELDS` array; if a field is sticky and already populated, the existing value is retained regardless of the new telemetry content.

## Core Implementation Files

The metadata resolution system spans several key files within the repository, each responsible for distinct aspects of the pipeline:

- **[`src/data/contextStore.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/contextStore.js)**: Contains the central Map store and the three primary resolution functions (`registerEntityContext`, `selectTrackedSubjectContext`, `refreshTrackedSubjectContext`). This file maintains the `store.entities` Map that serves as the single source of truth.

- **[`src/cockpitTracking.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/cockpitTracking.js)**: Consumes resolved metadata to populate the primary flight tracking interface, calling `selectTrackedSubjectContext` to retrieve current aircraft states for display.

- **[`src/layers/flights/tracking.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/layers/flights/tracking.js)**: Implements the flight layer's integration with the context store, registering new aircraft and refreshing existing ones as ADS-B telemetry streams in.

- **[`src/layers/military/tracking.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/layers/military/tracking.js)**: Demonstrates the layer-agnostic nature of the resolution system by handling military contacts using the same registration and refresh patterns as civilian flights.

- **[`src/data/aircraftMeta.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/aircraftMeta.js)**: Provides helper utilities for merging aircraft-specific sticky metadata, containing the `STICKY_FIELDS` definition and merge logic referenced by the context store.

- **[`src/hud.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/hud.js)**: Renders metadata strips and labels by reading resolved records from the context store, displaying callsigns, altitudes, and other tracked properties.

## Working with the Context Store API

The following examples demonstrate how to interact with the metadata resolution system in application code.

### Registering a New Tracked Object

When a layer detects a new entity, it registers the metadata to establish the tracking baseline:

```javascript
import { registerEntityContext } from '../data/contextStore.js';

// Create or obtain the Cesium entity for visualization
const aircraftEntity = viewer.entities.add({
  position: Cesium.Cartesian3.fromDegrees(lon, lat, alt),
  point: { pixelSize: 10, color: Cesium.Color.YELLOW }
});

// Define initial metadata with required id and layerId fields
const aircraftMeta = {
  id: 'A0B1C2',           // ICAO 24-bit address
  layerId: 'flights',     // Origin layer identifier
  callsign: 'UAL123',
  altitudeFt: 32000,
  speedMps: 245,
  registration: 'N12345'  // Sticky field
};

// Register in the global context store
registerEntityContext(aircraftEntity, aircraftMeta);

```

### Selecting Metadata for UI Components

Components retrieve current metadata to render information panels or update visual attributes:

```javascript
import { selectTrackedSubjectContext } from '../data/contextStore.js';

function updateCockpitDisplay(selectedEntity) {
  // Retrieve the resolved metadata record
  const record = selectTrackedSubjectContext(selectedEntity);
  
  if (!record) {
    console.warn('No metadata found for selected entity');
    return;
  }
  
  // Update HUD elements with resolved values
  hud.updateCallsign(record.callsign);
  hud.updateAltitude(record.altitudeFt);
  hud.updateSpeed(record.speedMps);
}

```

### Refreshing Metadata on Telemetry Updates

When new data arrives from external feeds, the layer refreshes the context store while allowing sticky fields to persist:

```javascript
import { refreshTrackedSubjectContext } from '../data/contextStore.js';

function handleFlightUpdate(adsbMessage) {
  const incomingMeta = {
    id: adsbMessage.icao,
    layerId: 'flights',
    altitudeFt: adsbMessage.altitude,
    speedMps: adsbMessage.velocity,
    // callsign might be null in this message
    callsign: adsbMessage.callsign 
  };
  
  // Merge into existing record; sticky fields like registration persist
  refreshTrackedSubjectContext(incomingMeta);
}

```

### Internal Sticky Field Merge Logic

The context store implements the following merge strategy to handle sticky metadata preservation:

```javascript
// Simplified excerpt from src/data/contextStore.js
const STICKY_FIELDS = ['registration', 'imoNumber', 'serialNumber'];

function mergeMetadata(existingMeta, newMeta) {
  const merged = { ...existingMeta };
  
  for (const [key, value] of Object.entries(newMeta)) {
    if (value === null || value === undefined) continue;
    
    // Preserve existing sticky values
    if (STICKY_FIELDS.includes(key) && merged[key] != null) {
      continue;
    }
    
    merged[key] = value;
  }
  
  return merged;
}

```

## Summary

- **Centralized Resolution**: All entity metadata resolves through [`src/data/contextStore.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/contextStore.js), which maintains a global `Map` of identifiers to metadata records.
- **Three-Phase Pipeline**: The system uses `registerEntityContext` for initialization, `selectTrackedSubjectContext` for reads, and `refreshTrackedSubjectContext` for updates.
- **Sticky Field Protection**: Critical identifiers survive telemetry updates through sticky field logic that preserves existing non-null values.
- **Layer Agnostic**: Any layer (flights, military, maritime) can register entities using the same API, with `layerId` distinguishing ownership.
- **UI Integration**: Cockpit displays and HUD components consume resolved metadata directly from the store, ensuring consistent state across the application.

## Frequently Asked Questions

### What happens if telemetry arrives for an unregistered entity?

If `refreshTrackedSubjectContext` receives metadata for an identifier not present in `store.entities`, the function typically ignores the update or returns early without creating a record. The entity must first be registered via `registerEntityContext` before the store will maintain its metadata state, ensuring that only explicitly tracked subjects consume memory and processing resources.

### How does God's Eye View prevent stale metadata from overwriting critical identifiers?

The context store implements **sticky metadata** logic within its merge functions. Fields listed in the `STICKY_FIELDS` array—such as aircraft registrations or vessel IMO numbers—are protected after their initial population. When `refreshTrackedSubjectContext` processes incoming telemetry, it checks whether a sticky field already contains a non-null value; if so, it discards the incoming value for that field while still updating non-sticky properties like altitude or speed.

### Can multiple layers track the same entity simultaneously?

While the context store supports entities from any layer, each metadata record contains a `layerId` property indicating ownership. If two layers attempt to register entities with the same `id`, the latter registration will overwrite the former in the global `Map`. The current implementation assumes unique identifiers across layers; for shared tracking scenarios, layers should coordinate through a single registration point or use composite keys that include the layer identifier.

### Why use a centralized Map instead of attaching metadata directly to Cesium entities?

Attaching metadata directly to Cesium entity objects would couple data management to the visualization layer, complicating testing and preventing non-visual systems (such as analytics or alerting modules) from accessing tracking state. The centralized `store.entities` Map decouples metadata resolution from rendering, allows background workers to update tracking state, and enables sticky-field logic that would be fragile if scattered across multiple entity references.