From 2e061b2cdfa65474441d4165e60d05aa334d8387 Mon Sep 17 00:00:00 2001 From: jing Date: Mon, 13 Jul 2026 16:53:05 +1000 Subject: [PATCH] wave2 phase 5: polish pack (military, ground tracks, URL state, screenshots) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Military callsigns (aircraft.js): callsigns matching CONFIG.aircraft. militaryPrefixes tint red regardless of altitude band and bump larger. New "Military filter" HUD row (default off) shows only military aircraft when on; status "N military of M". Pick overlay shows Military/Civil class. 2. Satellite ground track (satellites.js): selecting a satellite draws its sub-satellite path (height 0, ±half orbit around now) as a dashed polyline in the sat's colour; deselect hides it; one track at a time. Recomputed on demand from the satrec (no upfront precompute of 97 tracks). 3. Shareable URL state (main.js + ui.js): camera / mode / layer toggles / clock offset serialize to location.hash (replaceState, 1 s cadence, only on change) and are restored on boot; malformed hashes ignored silently. 4. Screenshot endpoint (serve.py): dev-only POST snap?name= writes a base64 PNG body to docs/.png (name sanitized to [a-z0-9-], can't escape docs/). Captured docs/screenshot-data.png + screenshot-photo.png (render() called synchronously before toDataURL — the preserveDrawingBuffer pitfall). README rewritten for Wave 2: quakes/fires layer rows (marked REAL), replay, shared cache, shareable links, ground tracks, military, screenshots, updated architecture + roadmap. Verified in browser: 11 military of 6062 + filter; ground track 180 pts on select / hidden on deselect; URL round-trips camera+mode+layers+clock; both screenshots written as valid 1280x720 PNGs; subpath audit clean. Co-Authored-By: Claude Opus 4.8 --- README.md | 43 +++++++++++++++--- docs/screenshot-data.png | Bin 0 -> 1359014 bytes docs/screenshot-photo.png | Bin 0 -> 1970766 bytes js/layers/aircraft.js | 40 +++++++++++++--- js/layers/satellites.js | 49 +++++++++++++++++++- js/main.js | 93 +++++++++++++++++++++++++++++++++++--- js/ui.js | 23 ++++++++++ serve.py | 30 ++++++++++++ 8 files changed, 259 insertions(+), 19 deletions(-) create mode 100644 docs/screenshot-data.png create mode 100644 docs/screenshot-photo.png diff --git a/README.md b/README.md index cd7921b..be9a23c 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ A browser-based **3D/4D OSINT world view** — a CesiumJS digital-twin globe tha Everything runs client-side from free, public, **unclassified** data. No API keys are required. No Cesium ion token. No build step. +![Photo Mode — Sentinel-2 imagery over the Persian Gulf with the recon-satellite fleet, live aircraft, quakes and fires](docs/screenshot-photo.png) + --- ## Quickstart @@ -29,18 +31,24 @@ The HUD lists every layer with a live status line and an on/off toggle, plus a ` | Layer | Source | Live? | Notes | |---|---|---|---| | **Satellites** (~97) | [Celestrak](https://celestrak.org) GP/TLE | ✅ deterministic | SGP4-propagated orbits with glowing paths; EO/recon birds incl. WorldView, Pléiades, Capella, SkySat, plus Chinese **Gaofen** and Russian **Cosmos** (Persona) military satellites. Click one for orbital elements. | -| **Aircraft** | [OpenSky Network](https://opensky-network.org) ADS-B | ✅ live | Thousands of live flights, colored by altitude band; click one for callsign/country/altitude/speed/heading. | +| **Aircraft** | [OpenSky Network](https://opensky-network.org) ADS-B | ✅ live | Thousands of live flights, colored by altitude band; **military callsigns highlighted** and filterable; click one for callsign/country/altitude/speed/heading. Scrub off-live and it **replays recorded traffic** (see below). | +| **Earthquakes** | [USGS](https://earthquake.usgs.gov) GeoJSON | ✅ real | Last 24 h of quakes, time-anchored so each **appears as the slider crosses its origin time**; magnitude ramps amber→red, recent quakes pulse, M≥4.5 labeled. Click one for magnitude/depth/time and the USGS event link. | +| **Wildfires** | [NASA EONET](https://eonet.gsfc.nasa.gov) | ✅ real | Active wildfire events worldwide as flame glyphs; click one for the event details and EONET link. | | **Ships** `[DEMO]` | synthetic | — | Illustrative tanker traffic through the Strait of Hormuz, incl. a "toll-route" carrier, a **dark-vessel AIS gap**, and the Fujairah idle anchorage. Optional live AIS — see below. | | **Infrastructure** | static vectors | — | Choke points (Hormuz, Bab el-Mandeb, Suez, Malacca), the East–West Petroline & Habshan–Fujairah pipelines, and key oil/desal/base facilities. Coordinates approximate. | | **Events** `[DEMO]` | synthetic | — | Time-anchored markers that appear as the slider crosses their moment — illustrative placeholders for a future real event feed. | +Select a satellite and its **sub-satellite ground track** draws under it. In **Data Mode**, the whole picture reads as orbits + markers on a dark globe: + +![Data Mode — satellite orbit paths, the recon fleet, quakes and event markers](docs/screenshot-data.png) + ### Basemaps - **Data Mode:** © OpenStreetMap contributors © CARTO (dark_all raster tiles). - **Photo Mode:** Sentinel-2 cloudless by [EOX](https://s2maps.eu) — modified Copernicus Sentinel data 2023. ## What is real vs. DEMO -**Real, live, public data:** satellites (Celestrak TLEs) and aircraft (OpenSky ADS-B). Satellite positions are computed live via SGP4; aircraft are polled from OpenSky. +**Real, live, public data:** satellites (Celestrak TLEs), aircraft (OpenSky ADS-B), **earthquakes** (USGS), and **wildfires** (NASA EONET). Satellite positions are computed live via SGP4; aircraft are polled from OpenSky; quakes and fires are fetched directly from their public feeds. **Synthetic `[DEMO]` data:** ships and events. These are hand-authored to illustrate the *kind* of analysis the platform is built for (dark-vessel detection, choke-point pressure, strike/pass correlation) without claiming to depict a real event. Every demo entity is labeled `[DEMO]` in its name, the HUD, and its info panel. @@ -56,6 +64,28 @@ AISSTREAM_API_KEY: 'your-key-here', On the first live position report the demo fleet hides and real vessels stream in over a WebSocket (no proxy needed). +## Time-travel: aircraft replay + +Orbits, demo ships, quakes and events are all time-aware, so scrubbing the timeline "just works" for them. Live aircraft are different — you can't compute where a plane *was* an hour ago. So an optional local recorder, **`record.py`**, snapshots live traffic every 3 minutes into a small SQLite db (`data/history.db`, gitignored, 72 h retention). Scrub the clock off wall-clock-now and the aircraft layer fetches the nearest recorded snapshot and **replays the actual traffic** for that moment — the aircraft status turns amber (`replay ·