# How to Perform Analytical Queries on Live CesiumJS Data Layers

> Learn to perform analytical queries on live CesiumJS data layers using Gods Eye View. Explore methods like resolveLayerTrackingTarget for powerful data insights.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: how-to-guide
- Published: 2026-09-04

---

**To perform analytical queries on live CesiumJS data layers in God’s Eye View, use the DataLayerManager’s `resolveLayerTrackingTarget()` method after enabling and refreshing the target layer via `setEnabled()` and `refreshLayer()`.**

God’s Eye View is an open-source CesiumJS application that renders real-time data overlays for aircraft, satellites, and vessels. To perform analytical queries on live CesiumJS data layers, the codebase implements a centralized **DataLayerManager** ([`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js)) that coordinates layer lifecycle management and exposes a uniform API for interrogating specific entity states and cartographic positions.

## Core Architecture of the Query System

The analytical capabilities rely on a modular architecture that separates data sources from visualization logic.

### DataLayerManager Registry

The **DataLayerManager** class (`src/data/manager.js#L18-L27`) maintains a central registry (`this.layers`) storing layer entries with metadata including `module`, `enabled`, and `initialized` states. This registry serializes visibility changes and manages the deterministic lifecycle of each overlay.

### Layer Module Interface

Individual data sources such as [`src/data/traffic.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/traffic.js) and [`src/data/satellites.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/satellites.js) implement a standard interface exposing `init()`, `enable()`, `update()`, `disable()`, and optionally `resolveTrackingRestoreTarget()`. When the manager needs to resolve a specific entity, it delegates to the layer module’s implementation.

### Visibility Intent System

To guarantee deterministic enable/disable behavior, the manager uses a queued intent system implemented in `_setEnabledWithIntent()` (`src/data/manager.js#L74-L89`). This ensures that rapid state changes do not corrupt layer state before queries execute.

## The Analytical Query API

The primary method for entity resolution is `resolveLayerTrackingTarget()` (`src/data/manager.js#L438-L452`). This function accepts a `layerId`, `targetId` (such as an ICAO callsign), and optional abort signals, returning a structured result object containing:

- **status**: `'found'`, `'missing'`, `'source-unavailable'`, or `'cancelled'`
- **Cartographic coordinates**: `latitude`, `longitude`, `altitude`
- **Metadata**: Layer-specific entity properties

Before invoking this API, layers must be activated and refreshed to ensure data freshness.

## Step-by-Step Query Workflow

Follow this sequence to query live CesiumJS data layers reliably:

1. **Obtain the manager instance**: Import or access the `DataLayerManager` singleton from [`src/main.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/main.js).

2. **Enable the target layer**: Activate the layer using `setEnabled()` (`src/data/manager.js#L58-L66`):

```javascript
await dataManager.setEnabled('flights', true);

```

3. **Refresh the layer data**: Force a fresh update cycle using `refreshLayer()` (`src/data/manager.js#L91-L99`) to guarantee the query sees the latest positions:

```javascript
await dataManager.refreshLayer('flights');

```

4. **Resolve the tracking target**: Call `resolveLayerTrackingTarget()` with the entity identifier:

```javascript
const result = await dataManager.resolveLayerTrackingTarget(
  'flights',
  'ABC123',
  { signal: AbortSignal.timeout(5000) }
);

```

5. **Interpret results**: Check `result.status`. If `'found'`, the payload contains Cesium-compatible cartographic coordinates suitable for camera positioning or UI annotations.

## Cesium Integration and Coordinate Systems

The query API returns geographic coordinates that integrate directly with CesiumJS geometric utilities.

### Cartographic Conversion

Layer modules and utilities like [`src/worldFocus.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/worldFocus.js) convert query results into Cesium cartesian positions using `Cesium.Cartographic.fromDegrees()`:

```javascript
const carto = Cesium.Cartographic.fromDegrees(longitude, latitude, altitude);

```

Alternatively, for direct camera positioning:

```javascript
const position = Cesium.Cartesian3.fromDegrees(lon, lat, height);
viewer.camera.setView({ destination: position });

```

### Entity Picking

For ad-hoc spatial queries, Cesium’s native picking API complements the analytical query system:

```javascript
const picked = viewer.scene.pick(new Cesium.Cartesian2(x, y));

```

## Practical Code Examples

### Example 1: Simple Aircraft Lookup

This implementation demonstrates enabling the flights layer, refreshing data, and positioning the camera on the resolved entity:

```javascript
async function lookupAircraft(callsign) {
  // Enable the flights layer
  await dataManager.setEnabled('flights', true);
  
  // Force refresh for latest positions (src/data/manager.js#L91-L99)
  await dataManager.refreshLayer('flights');
  
  // Resolve the target entity (src/data/manager.js#L438)
  const res = await dataManager.resolveLayerTrackingTarget('flights', callsign);
  
  if (res.status === 'found') {
    const { latitude, longitude, altitude } = res;
    console.log(`Aircraft ${callsign} at ${latitude.toFixed(3)}°, ${longitude.toFixed(3)}°, ${altitude}m`);
    
    // Camera transition to entity using Cesium utilities
    viewer.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, altitude + 500)
    });
  } else {
    console.warn(`Lookup failed: ${res.status}`);
  }
}

```

### Example 2: Generic Layer Query Wrapper

Create a reusable abstraction for querying any live layer:

```javascript
async function queryLayer(dm, layerId, entityId) {
  // Ensure layer is active (src/data/manager.js#L58-L66)
  const enabled = await dm.setEnabled(layerId, true);
  if (!enabled) return null;
  
  // Refresh to get freshest data
  await dm.refreshLayer(layerId);
  
  // Resolve and normalize result
  const result = await dm.resolveLayerTrackingTarget(layerId, entityId);
  return result.status === 'found' ? result : null;
}

```

### Example 3: Computing Distance Between Live Entities

Combine multiple queries with Cesium’s geometric utilities:

```javascript
async function distanceBetween(layerId, idA, idB) {
  const a = await queryLayer(dataManager, layerId, idA);
  const b = await queryLayer(dataManager, layerId, idB);
  
  if (!a || !b) throw new Error('One or both entities not found');
  
  const posA = Cesium.Cartesian3.fromDegrees(a.longitude, a.latitude, a.altitude);
  const posB = Cesium.Cartesian3.fromDegrees(b.longitude, b.latitude, b.altitude);
  
  return Cesium.Cartesian3.distance(posA, posB); // Returns meters
}

```

## Summary

- **DataLayerManager** ([`src/data/manager.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/manager.js)) serves as the central registry and query coordinator for all live CesiumJS data layers.
- **Analytical queries** require three sequential operations: `setEnabled()` to activate the layer, `refreshLayer()` to fetch current data, and `resolveLayerTrackingTarget()` to retrieve specific entity states.
- **Query results** provide standardized status flags and cartographic coordinates compatible with CesiumJS camera and visualization APIs.
- **Layer modules** such as [`src/data/traffic.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/traffic.js) implement the entity-specific resolution logic that the manager delegates to during queries.
- **Coordinate conversion** leverages `Cesium.Cartesian3.fromDegrees()` to transform query results into 3-D world positions for camera manipulation or spatial analysis.

## Frequently Asked Questions

### How does DataLayerManager handle layer lifecycle during queries?

The manager implements a deterministic intent system in `_setEnabledWithIntent()` (`src/data/manager.js#L74-L89`) that queues visibility changes. This prevents race conditions when rapidly toggling layers or executing queries during initialization, ensuring that `resolveLayerTrackingTarget()` only runs against fully initialized data sources.

### Why must I call refreshLayer before querying?

Live data layers in God’s Eye View operate on periodic update cycles. Calling `refreshLayer()` (`src/data/manager.js#L91-L99`) forces an immediate data fetch from the upstream source (such as aviation or satellite APIs), guaranteeing that `resolveLayerTrackingTarget()` returns the most recent entity position rather than cached or stale coordinates.

### What properties does the query result object contain?

According to the implementation at `src/data/manager.js#L438-L452`, the result object includes a `status` string (`'found'`, `'missing'`, `'source-unavailable'`, or `'cancelled'`), geographic coordinates (`latitude`, `longitude`, `altitude`), and layer-specific metadata. When status equals `'found'`, the coordinates are ready for direct use with Cesium’s `Cartesian3.fromDegrees()` or `Cartographic` utilities.

### Can I query layers that are not currently visible?

Yes, but you must first enable them. The `setEnabled()` method (`src/data/manager.js#L58-L66`) handles the full initialization lifecycle including module loading and first data fetch. Attempting to query a disabled layer will return a `'source-unavailable'` status, as implemented in the resolution logic used by the voice assistant module ([`src/voice/gevRealtime.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/voice/gevRealtime.js)).