OVERVIEW
E.Y.E. pulls live data from multiple public APIs and WebSocket streams, proxies them through a lightweight Express backend with in-memory caching, then renders everything as billboard collections and entities on a CesiumJS 3D globe.
The HUD overlay is pure DOM — positioned above the Cesium canvas via z-index — and reacts to camera movement, entity hover, layer toggles, shader changes, and backend health warnings wired in main.js.
SCREENSHOTS
DATA LAYERS
Each layer is an ES module class in layers/ with enable() / disable() lifecycle methods. All toggled via the HUD side panel.
Live global ADS-B from adsb.lol. Progressive rendering via BillboardCollection. Dead-reckoning interpolates positions each frame. Refreshes every 10 s.
TLE catalog from CelesTrak. SGP4 propagation via satellite.js, updated every 3 frames. Progressive loading and click-to-path visualization.
Traffic cameras from TfL, Austin, NSW, and Seattle. Renders markers with initial scale-up animations. Hover previews stream proxied JPEGs.
USGS all-day GeoJSON. Pulsing crosshair billboards sized by magnitude with progressive animation. Refreshes every 60 s.
Persistent AISStream feed with viewport-based pruning and LOD clustering for high-altitude viewing. Supports important-ship metadata overrides.
Pure DOM overlay above the Cesium canvas. Includes tactical entity tracking, Reset Camera controls, layer state toggles, and shader post-processing.
POST-PROCESS SHADERS
CesiumJS PostProcessStage GLSL fragments in shaders/, managed by postprocessor.js. One stage active at a time; Normal removes the active stage.
PostProcessor API
// postprocessor.js import PostProcessor from './postprocessor.js'; const pp = new PostProcessor(viewer); pp.setMode('CRT'); // activate shader pp.setMode('Normal'); // remove active stage pp.getActiveMode(); // → 'Normal' | 'NightVision' | 'FLIR' | 'CRT'
BACKEND API
Express on port 3001. Vite proxies /api/* to it. All routes use node-cache to throttle upstream calls.
| Method | Endpoint | Description | Cache | Upstream |
|---|---|---|---|---|
| GET | /api/aircraft | All aircraft globally filtered for lat/lon. | 15 s | api.adsb.lol |
| GET | /api/ships | Current in-memory ship state from a persistent AISStream websocket, merged with static identity messages. | Live state | stream.aisstream.io |
| GET | /api/cctv | Merged cameras. Accepts ?country & ?source. | 5 min | TfL/Austin/NSW/Seattle |
| GET | /api/cctv/image | CORS proxy for camera JPEGs. ?url= | 60 s | Camera image hosts |
| GET | /api/satellites | TLE 3-line catalog. ?group=active default, with JSON fallback if the primary upstream fails. | 2 hr | CelesTrak / tle.ivanstanojevic.me |
| GET | /api/proxy | Generic CORS proxy. ?url= — 5 s timeout. | — | Arbitrary |
Camera Schema
// GET /api/cctv { id: "tfl-00001.03777", name: "Trafalgar Square", source: "tfl", country: "GB", region: "London", latitude: 51.5080, longitude: -0.1281, imageUrl: "https://...", available: true }
Ship Schema
// GET /api/ships { mmsi: "227000000", name: "FRENCH WARSHIP", lat: 47.393, lon: -2.686, sog: 7.8, cog: 66.1, heading: 65, status: 0, shipType: 35 }
ARCHITECTURE
BillboardCollection vs Entity API: Aircraft, ships, satellites, and earthquakes use raw BillboardCollection for GPU-batched rendering. CCTV uses Cesium entities for point + label markers and attaches preview metadata for hover interaction.
Dead Reckoning: Aircraft and ships interpolate position each frame using last-known heading × speed × elapsed time, keeping motion smooth despite infrequent API calls.
AIS stream model: The backend maintains one long-lived AIS websocket, merges multiple position/static message types into an in-memory registry, and serves the current ship state to the frontend on demand.
ROADMAP
Planned phases cover expanded data sources, offline capability, collaborative overlays, and a full mobile HUD. Each phase is tracked as a visual node graph.