diff --git a/DATA_SOURCES.md b/DATA_SOURCES.md index d6796a70e..1c89cd2e0 100644 --- a/DATA_SOURCES.md +++ b/DATA_SOURCES.md @@ -15,7 +15,11 @@ How to read this: | Source | Used for | License / terms | Attribution | | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| **NOAA GFS (wind)** | Global 10 m wind, optional 2 m temperature and mean sea-level pressure for Wind | U.S. public domain (NOAA); keyless via NOAA Open Data on AWS | "NOAA Global Forecast System (GFS)" (courtesy; not an endorsement) | +| **NOAA GFS (wind)** (`noaa-gfs-bdp-pds.s3.amazonaws.com`) | Global 10 m wind, optional 2 m temperature and mean sea-level pressure for Wind. Keyless; latest 6-hourly 0.25° cycle, byte-range GRIB2 reads, cached for an hour | U.S. public domain (NOAA); keyless via NOAA Open Data on AWS | "NOAA Global Forecast System (GFS)" (courtesy; not an endorsement) | +| **ECMWF IFS (wind)** (`data.ecmwf.int/forecasts`, ECMWF Open Data) | The alternative Wind model: 10 m wind, optional 2 m temperature and mean sea-level pressure. Keyless; latest 6-hourly 0.25° run, byte-range GRIB2 reads, cached for an hour | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) plus the [ECMWF Terms of Use](https://apps.ecmwf.int/datasets/licences/general/) | "This service is based on data and products of the European Centre for Medium-Range Weather Forecasts (ECMWF)", with the CC BY 4.0 link, the modification notice and ECMWF's liability disclaimer — shown in-app | +| **NOAA nowCOAST observed weather** (`nowcoast.noaa.gov/geoserver/observations/{weather_radar,satellite}/ows`, WMS 1.1.1) | Rain radar (MRMS base reflectivity, contiguous US, about 4-minute updates) and Satellite clouds (GOES-19/18 Band 14 regional infrared, about 5-minute updates; global infrared mosaic, hourly). Keyless; layer metadata refreshed every 2 minutes, exact-time images cached for up to 24 hours | [NOAA disclaimer](https://oceanservice.noaa.gov/disclaimer.html) | "NOAA nowCOAST · NWS/OAR MRMS radar; NESDIS GOES and global satellite partners" | +| **NOAA nowCOAST lightning density** (`nowcoast.noaa.gov/geoserver/observations/lightning_detection/ows`) | Lightning density: 15-minute accumulated strike density on an approximately 8 km grid, Americas and Pacific. Keyless; layer metadata refreshed every 10 minutes, exact-time images cached for up to 24 hours | NOAA Level-5 derived product from Vaisala NLDN/GLD360; the [product description](https://ocean.weather.gov/lightning/lightning_pdd.php) permits public distribution of this density product, not of raw Vaisala detections | "NOAA/NWS nowCOAST; derived from Vaisala NLDN/GLD360" | +| **NOAA NHC / CPHC advisories** (`www.nhc.noaa.gov/CurrentStorms.json` + the `mapservices.weather.noaa.gov` tropical weather summary MapServer) | Cyclone advisories: storm positions, forecast tracks, points and cones for the Atlantic and eastern/central North Pacific. Keyless through `/api/cyclones`; cached for 5 minutes | [NWS public-data terms](https://www.weather.gov/disclaimer); no endorsement implied | "NOAA/NWS NHC / CPHC" | | **OpenStreetMap ALPR camera locations** (including DeFlock community mapping) | Optional mapped automatic license-plate-reader camera layer | [ODbL 1.0](https://opendatacommons.org/licenses/odbl/1-0/); commercial use permitted with applicable attribution and database share-alike obligations | [© OpenStreetMap contributors](https://www.openstreetmap.org/copyright); [DeFlock](https://deflock.org) community mapping | | **Google Map Tiles API** (Photorealistic 3D Tiles) + Places/Geocoding | The 3D globe, voice scene context, and on-demand nearby installation search | Google Maps Platform ToS (proprietary, your own key + billing) | "Google" / "Google Maps" logo — **shown in-app**, required | | **OpenSky Network** | Primary worldwide live-flight snapshot | Non-commercial research/education license | Schäfer et al., _"Bringing Up OpenSky"_, IPSN 2014 + opensky-network.org | @@ -42,7 +46,7 @@ How to read this: | **Stadt Warendorf webcam** | Webcam frames, Marktplatz / Historisches Rathaus (`config/cctv_sources.warendorf.json`) | Public municipal webcam data | "Stadt Warendorf — webcam.warendorf.de" (courtesy); mount and heading derived from OSM geometry, "© OpenStreetMap contributors" (ODbL) | | **Live Traffic NSW (Transport for NSW)** | CCTV camera catalog + frames, New South Wales | [CC BY 4.0](https://opendata.transport.nsw.gov.au/) — attribution REQUIRED | "Live Traffic NSW — Transport for NSW" | | **Caltrans (cwwp2.dot.ca.gov)** | CCTV camera catalogs + frames, California districts | Public Caltrans traffic camera data | "Caltrans — cwwp2.dot.ca.gov" (courtesy) | -| **DelDOT (video.deldot.gov)** | CCTV camera catalog + live HTTPS HLS video, Delaware | Public DelDOT traffic camera streams via the [DelDOT traffic map](https://deldot.gov/map/) |"DelDOT — Delaware Department of Transportation" (courtesy) | +| **DelDOT (video.deldot.gov)** | CCTV camera catalog (`tmc.deldot.gov/json/videocamera.json`, cached for 15 minutes) + live HTTPS HLS video, Delaware. Keyless | Public DelDOT traffic camera streams via the [DelDOT traffic map](https://deldot.gov/map/) | "DelDOT — Delaware Department of Transportation" (courtesy) | | **TfL Open Data (JamCams)** | CCTV camera catalog + frames, London | [TfL Open Data terms](https://tfl.gov.uk/info-for/open-data-users/) — attribution REQUIRED | "Powered by TfL Open Data. Contains OS data © Crown copyright and database rights" | | **Ontario 511** | CCTV camera catalog + frames, Ontario highways including Kitchener-area routes | [Open Government Licence – Ontario](https://www.ontario.ca/page/open-government-licence-ontario) | "Ontario 511" plus Open Government Licence - Ontario | | **Fintraffic / Digitraffic (weathercams)** | CCTV camera catalog + frames, Finland | [CC BY 4.0](https://www.digitraffic.fi/en/terms-of-service/) — attribution REQUIRED | "Fintraffic / digitraffic.fi, license CC BY 4.0" | @@ -156,42 +160,6 @@ transaction quota. Requires a free `FIRMS_MAP_KEY` (https://firms.modaps.eosdis.nasa.gov/api/map_key/); the layer is empty without it. The former bundled 2026-05-25 snapshot was removed 2026-07-16. -### ECMWF IFS wind - -Wind also offers ECMWF IFS 10 m forecasts from the keyless [ECMWF Open Data](https://www.ecmwf.int/en/forecasts/datasets/open-data) service. The proxy reads its JSON Lines inventory and byte-range fetches 10u/10v GRIB messages, optionally adding 2t (2 m temperature) or msl (mean sea-level pressure) from the same run and forecast time. It resamples these fields to the approximately 1° display grid. Data is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). The [ECMWF Terms of Use](https://apps.ecmwf.int/datasets/licences/general/) also apply. In-app attribution identifies this service as based on ECMWF data and products, links the CC BY 4.0 licence, identifies resampling and animation as modifications, and retains the required ECMWF liability disclaimer. Both model issue time and the selected forecast valid time appear in the layer row. These are model forecasts, not observations. - -### NOAA GFS wind - -The optional **Wind** layer animates the global 10 m wind field from NOAA's -Global Forecast System (GFS). The `/api/wind` server-side proxy selects the -latest available 0.25° cycle, reads its `.idx` inventory, byte-range fetches only -the `UGRD`/`VGRD` 10 m GRIB2 messages, optionally adding `TMP` at 2 m or -`PRMSL` at mean sea level from the same run and forecast time. It decodes the -selected messages with ecCodes (WASM), resamples to a compact grid (1° by -default), and serves a manifest plus Float32 U/V and optional scalar values. It is keyless, cached -per cycle for an hour, and is a **forecast, not an observation**: the particles -show model flow, not measured wind. The renderer bakes bounded curves through -the sampled field and animates their phase on the GPU, with a canvas fallback. -Any display lift is a visual aid and does not change the forecast's 10 m level. -NOAA GFS data is U.S. public domain; the credit above is a courtesy and does not -imply endorsement. - -For both models, optional temperature is normalized from K to °C and pressure -from Pa to hPa before delivery. A missing, malformed or timed-out companion field -does not discard valid wind: the manifest marks that field unavailable, and the -UI retains wind without inventing scalar values. The proxy caches by model and -requested field, with bounded current/previous grids and shared in-flight loads. -Wind speed shading is computed locally from U/V and needs no companion download. -The legend and map-center reading explain units and forecast validity; the -animation is a visual flow through one forecast, not advancing forecast time. -Optional globe relief uses existing terrain vertex normals for view lighting; -without those normals it shades global globe curvature only, not local terrain -relief. Neither mode represents measured sunlight or a new elevation source. -This Wind prototype adds no cloud-volume or radar data. Mapped.earth's public -bundles were studied for rendering ideas, but -no code or assets were reused and no application licence granting reuse was -found. Its presentation is not a weather-data source for this implementation. - ### Natural Earth physical regions (`natural_earth/`) Curated from the **Natural Earth 10m physical vectors** (https://www.naturalearthdata.com/ — @@ -230,9 +198,43 @@ Douglas-Peucker simplification, 6-decimal rounding). --- -## In-app attribution +## Weather sources -The required Google Maps / Cesium credit renders on the on-globe credit line (`#cesium-credits`, bottom-left) and must stay visible — including in clean-view and recording modes (the whole line, logo + "Google Maps" + the "Data attribution" link, stays on screen; only the GEV panels/HUD fade). The layer-specific credits (adsb.lol, TeleGeography, OSM datacenters/dams/roads, NASA FIRMS, CelesTrak, USGS, City of Austin, Fintraffic, GBFS, Radio Browser, OpenSky, AISStream) are registered into the expandable **"Data attribution"** popover on that credit line via `viewer.creditDisplay.addStaticCredit(new Cesium.Credit(html, /* showOnScreen */ false))` — see `src/data/dataCredits.js`. When you add a new data source, add its license and attribution to this file **and** append an entry to `DATA_CREDITS` in `src/data/dataCredits.js` so it surfaces in the app. +### ECMWF IFS wind + +Wind also offers ECMWF IFS 10 m forecasts from the keyless [ECMWF Open Data](https://www.ecmwf.int/en/forecasts/datasets/open-data) service. The proxy reads its JSON Lines inventory and byte-range fetches 10u/10v GRIB messages, optionally adding 2t (2 m temperature) or msl (mean sea-level pressure) from the same run and forecast time. It resamples these fields to the approximately 1° display grid. Data is licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). The [ECMWF Terms of Use](https://apps.ecmwf.int/datasets/licences/general/) also apply. In-app attribution identifies this service as based on ECMWF data and products, links the CC BY 4.0 licence, identifies resampling and animation as modifications, and retains the required ECMWF liability disclaimer. Both model issue time and the selected forecast valid time appear in the WEATHER panel. These are model forecasts, not observations. + +### NOAA GFS wind + +The optional **Wind** layer animates the global 10 m wind field from NOAA's +Global Forecast System (GFS). The `/api/wind` server-side proxy selects the +latest available 0.25° cycle, reads its `.idx` inventory, byte-range fetches only +the `UGRD`/`VGRD` 10 m GRIB2 messages, optionally adding `TMP` at 2 m or +`PRMSL` at mean sea level from the same run and forecast time. It decodes the +selected messages with ecCodes (WASM), resamples to a compact grid (1° by +default), and serves a manifest plus Float32 U/V and optional scalar values. It is keyless, cached +per cycle for an hour, and is a **forecast, not an observation**: the particles +show model flow, not measured wind. The renderer bakes bounded curves through +the sampled field and animates their phase on the GPU, with a canvas fallback. +Any display lift is a visual aid and does not change the forecast's 10 m level. +NOAA GFS data is U.S. public domain; the credit above is a courtesy and does not +imply endorsement. + +For both models, optional temperature is normalized from K to °C and pressure +from Pa to hPa before delivery. A missing, malformed or timed-out companion field +does not discard valid wind: the manifest marks that field unavailable, and the +UI retains wind without inventing scalar values. The proxy caches by model and +requested field, with bounded current/previous grids and shared in-flight loads. +Wind speed shading is computed locally from U/V and needs no companion download. +The legend and map-center reading explain units and forecast validity; the +animation is a visual flow through one forecast, not advancing forecast time. +Optional globe relief uses existing terrain vertex normals for view lighting; +without those normals it shades global globe curvature only, not local terrain +relief. Neither mode represents measured sunlight or a new elevation source. +This Wind prototype adds no cloud-volume or radar data. Mapped.earth's public +bundles were studied for rendering ideas, but +no code or assets were reused and no application licence granting reuse was +found. Its presentation is not a weather-data source for this implementation. ### Observed weather: NOAA nowCOAST @@ -246,8 +248,8 @@ services: `https://nowcoast.noaa.gov/geoserver/observations/weather_radar/ows` a Coverage gaps do not mean no precipitation. The numeric legend follows NOAA's `weather_radar_base_reflectivity` style. - `goes_longwave_imagery`: GOES-19/18 Band 14, approximately 2 km, 5-minute updates, - regional North America. Filtered infrared softly dims pixels with a linear - brightness ramp from 0.40 to 0.70; Full infrared retains source alpha. This + regional North America. **Clouds only** softly dims pixels with a linear + brightness ramp from 0.40 to 0.70; **Full image** retains source alpha. This is a display filter, not a cloud mask or measured cloud volume. - `global_longwave_imagery_mosaic`: approximately 3 km, hourly, nominal 60°S–60°N coverage and typically 2–3-hour latency. It is slower global context. @@ -263,8 +265,17 @@ and filters it once, then crops 256 px tiles bounded to the manifest extent at maximum level 3. This broad context view has a coarser display resolution than its 3 km source. No browser reprojection is used. Browser imagery owns a displayed frame and a staging frame, retaining the outgoing layer for one render after -admission; the proxy has an 8-request -concurrency budget, 12-second deadline, 1 MiB tile / 4 MiB global PNG caps and a shared 16 MiB/128-image cache. +admission. + +On Google 3D Tiles each observed product is instead a raised shell showing one +whole-extent image per frame (up to 4096×2048; global infrared 2048×1024). Every +product except global infrared also draws a 4096×2048 detail window around the +view, requested with a 2:1 `bbox` inside the product bounds, rounded to 0.25°. +The proxy has an 8-request concurrency budget and a 12-second deadline; tiles +(256, 512 or 1024 px) are capped at 1 MiB or 4 bytes per pixel plus 64 KiB, +whichever is larger, and whole-extent and detail images at 16 MiB. Its shared +cache holds up to 128 images and 16 MiB, each exact-time image for at most 24 +hours. Metadata refreshes every two minutes with explicitly stale last-good fallback. No key, new dependency, image reprojection job, or full-disk image download is needed. @@ -320,4 +331,8 @@ The fixed nowCOAST imagery and NHC advisory implementations are original maintai work; this acknowledgement does not represent merging those four PRs or equate NOAA density imagery with the raw GLM product. +--- + +## In-app attribution + The required Google Maps / Cesium credit renders on the on-globe credit line (`#cesium-credits`, bottom-left) and must stay visible — including in clean-view and recording modes (the whole line, logo + "Google Maps" + the "Data attribution" link, stays on screen; only the GEV panels/HUD fade). The layer-specific credits (adsb.lol, adsbdb, TeleGeography, OSM datacenters/dams/roads, NASA FIRMS, CelesTrak, USGS, City of Austin, Fintraffic, GBFS, Radio Browser, OpenSky, AISStream) are registered into the expandable **"Data attribution"** popover on that credit line via `viewer.creditDisplay.addStaticCredit(new Cesium.Credit(html, /* showOnScreen */ false))` — see `src/data/dataCredits.js`. When you add a new data source, add its license and attribution to this file **and** append an entry to `DATA_CREDITS` in `src/data/dataCredits.js` so it surfaces in the app. diff --git a/README.md b/README.md index 0c5cdfbec..88690d52f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # 🌐 God's Eye View -[![CI](https://github.com/bilawalsidhu/gods-eye-view/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/bilawalsidhu/gods-eye-view/actions/workflows/ci.yml) +[![CI](https://github.com/bilawalsidhu/gods-eye-view/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/bilawalsidhu/gods-eye-view/actions/workflows/ci.yml) [![Reached #1 on GitHub Trending](https://img.shields.io/badge/%231_GitHub_Trending-thank_you!-F0A63C?style=flat-square&logo=github)](https://x.com/bilawalsidhu/status/2093798887815348521) ### A spy-satellite simulator in your browser — then you realize the sources are public and the data is real. @@ -18,8 +18,6 @@ _No place left behind._ ▶️ **From the project behind the viral God's Eye View series** _(formerly WorldView)_ — [5M+ on YouTube](https://youtube.com/playlist?list=PL6qSg2I-7_koPbDnSMo0QeeHX_RknA2uv&si=nBGYMoHWQw41v93Q) · [25M+ across socials](https://www.google.com/search?q=god%27s+eye+view) -[![Reached #1 on GitHub Trending](https://img.shields.io/badge/%231_GitHub_Trending-thank_you!-F0A63C?style=flat-square&logo=github)](https://x.com/bilawalsidhu/status/2093798887815348521) - 🏆 **Reached #1 on GitHub Trending, daily and weekly · August 2026** **[#8 Product of the Day](https://www.producthunt.com/products/god-s-eye-view?launch=god-s-eye-view)** · Hunted by Chris Messina, creator of the hashtag @@ -70,6 +68,14 @@ Start with the included data sources, then add your own. Each layer is a separat - **🎥 Scene director:** Capture cinematic camera tours for clips and demos. - **🔗 Share Links:** Camera, style, layers, and even one tracked target serialize into a URL — a live target is a handoff, not a bookmark. - **🏠 Reset Globe:** One control — or one sentence — back to the full Earth. +- **🌦️ Weather:** Animate GFS or ECMWF forecast wind, replay observed radar, satellite clouds and lightning on one timeline, and follow NHC/CPHC cyclone tracks. No key needed. +- **📷 Mapped ALPR cameras:** License-plate-reader camera locations tagged in OpenStreetMap, one city at a time. Locations and tags only; no key needed. +- **🔭 Satellite passes:** Ask by voice when any loaded satellite next rises over you: rise, peak and set times, and whether you can see it. +- **🔎 Analyst answers:** Count, filter and rank satellites, datacenters and dams by voice, alongside flights, ships, fires and quakes; answers say when a feed is stale or on a fallback. +- **🧭 Tilt and North Up:** Switch between straight-down and a 35° oblique, or put north at the top, while a tracked target stays centered. +- **🔍 Keyless search:** Type coordinates or a bundled city or landmark to fly there with no network request; other names use Google when configured, then Photon and Nominatim. +- **📦 Shareable scenes:** Import, preview and share Director scenes as files or bundles, with camera anchors, authored moves and data packs. +- **🌊 Nepal flood scene:** Replay the Bhote Koshi flood: flood path, witness sources and before-and-after imagery (bundled data is non-commercial; see [DATA_SOURCES.md](DATA_SOURCES.md)). --- @@ -90,7 +96,7 @@ cameras, radio, and launches are available without keys. For photorealistic 3D, add a **Cesium ion token** for eligible personal, non-commercial use, or a **Google Maps key** for the direct, metered route and -in-app place search. Provider terms and quotas apply. Add keys through the +Google place search. Provider terms and quotas apply. Add keys through the app's **POWER UP** panel; [Keys & Costs](#-api-keys) explains the options. ### Path 1 — One click, no terminal @@ -153,8 +159,8 @@ reopens the same panel. - **What to get first:** the free [Cesium ion](https://cesium.com/ion) token (eligible personal, non-commercial use; current terms and quotas apply) for photorealistic 3D and world terrain; a Google Maps key only for the - billing-enabled, metered route + place search; OpenAI when you want to talk - to the world. Full map, costs included, in [Keys & Costs](#-api-keys). + billing-enabled, metered route + Google place search; OpenAI when you want to + talk to the world. Full map, costs included, in [Keys & Costs](#-api-keys).
Older Pinokio versions and credential storage @@ -188,7 +194,7 @@ Choose a first-run mission, or try these in order. The GIFs show Google Photorea ![Moving from a full airport overhead down to close taxiway inspection with 3D flight models](docs/media/start-here/airport-ground-traffic-google-3d.gif) -4. **Look through a public camera.** Turn on **CCTV** over Austin, London, California, Finland, or Delaware (live video). The feeds aren't webcam embeds — they project _into_ the 3D city. Cycle coverage to **VIEWSHED** and every camera draws its estimated coverage volume — where it reaches, and where it goes blind. +4. **Look through a public camera.** Turn on **Cameras** over Austin, London, California, Finland, or Delaware (live video). The feeds aren't webcam embeds — they project _into_ the 3D city. Cycle coverage to **VIEWSHED** and every camera draws its estimated coverage volume — where it reaches, and where it goes blind. ![Diving into an Austin intersection with a live public camera projected into the 3D scene](docs/media/03-austin-cctv.gif) @@ -203,7 +209,7 @@ Choose a first-run mission, or try these in order. The GIFs show Google Photorea 7. **Talk to it** _(needs an OpenAI key)_: _"Take me to LAX and select the nearest airborne aircraft."_ 8. **Come home.** Hit **Reset Globe** — or just say _"zoom out to a globe view."_ -**Keyboard:** `1`–`7` visual styles · `H` HUD · `D` detection · `C` cockpit · `Esc` out. +**Keyboard:** `1`–`7` visual styles · `H` HUD · `D` detection · `C` cockpit · `` ` `` frame rate · `Esc` out. Trackpad pinch zooms the globe. --- @@ -235,7 +241,7 @@ Click **GEV MIC**, grant the microphone, and just talk. This is more than a voic - **🎬 Cinematic framing.** _"Show me the planes overhead"_ pulls the camera back, angles it, and frames the live traffic like a director. - **🔒 Honest and secure.** The agent only confirms actions that succeeded. Your `OPENAI_API_KEY` never touches the browser; the client only gets a short-lived session token. -Twenty-eight tools, four jobs — the commands below come straight from the product's voice test suite and tool playbook: +Twenty-nine tools, four jobs — the commands below come straight from the product's voice test suite and tool playbook: **🎥 Direct it** — drone-operator camera verbs: @@ -253,7 +259,7 @@ Twenty-eight tools, four jobs — the commands below come straight from the prod **🔎 Interrogate it** — analyst queries against the live layers: -> 🗣️ _"How many flights are over Texas right now?"_ · _"Which ships are headed to Oakland?"_ · _"What is the biggest fire near Los Angeles?"_ · _"Is anything flying above forty thousand feet?"_ · _"When does the ISS pass over next?"_ +> 🗣️ _"How many flights are over Texas right now?"_ · _"Which ships are headed to Oakland?"_ · _"What is the biggest fire near Los Angeles?"_ · _"Is anything flying above forty thousand feet?"_ · _"When does the ISS pass over next?"_ · _"How many datacenters are in view?"_ **🎛️ Operate it** — the whole console, hands-free: @@ -271,7 +277,7 @@ _Ask for radio near anywhere and the globe starts broadcasting — every station ## 🛰️ What's on the Globe -Fifteen layers and map sources. **Thirteen have a keyless path.** Some offer additional capabilities with a provider key. (🟢 no key · 🟡 free key · 🔴 metered.) +Nineteen layers and map sources. **Seventeen have a keyless path.** Some offer additional capabilities with a provider key. (🟢 no key · 🟡 free key · 🔴 metered.) | Layer | What you get | Source | Auth | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------- | @@ -283,6 +289,7 @@ Fifteen layers and map sources. **Thirteen have a keyless path.** Some offer add | 🌍 **Earthquakes** | Global seismic activity, last 24h | USGS | 🟢 | | 🚗 **Traffic** | Simulated vehicles on OSM roads. With TomTom, live flow speeds drive the simulation and congestion colors below ~8 km; individual vehicle positions are not live observations | TomTom + OSM | 🟢 simulation · 🟡 live flow speeds | | 📹 **CCTV Mesh** | ~3,600 public cameras projected _into_ the 3D space — Austin · Texas (TxDOT) · California (Caltrans) · London (TfL) · Ontario (511) · Finland (Fintraffic) · British Columbia (DriveBC) · Estonia (Tallinn, Tarktee) · Delaware (DelDOT live video) · New South Wales (Live Traffic NSW) · Calgary. Positions are published; poses are estimated priors **you calibrate by dragging a gizmo on the camera itself** | City APIs | 🟢 | +| 📷 **Mapped ALPR Cameras** | License-plate-reader camera locations tagged by OpenStreetMap contributors, loaded one city-sized view at a time, with **SHOW NEAREST**. Locations and tags only: no plate data, no video | OpenStreetMap (incl. DeFlock mapping) | 🟢 | | 📻 **Radio** | Geolocated world radio with an **analog tuner** — drag the needle across up to 750 stations and the globe flies to each broadcaster | Radio Browser / broadcasters | 🟢 | | 🚌 **Transit** | Live buses, trams, metros, trains and ferries with delayed playback between reports, selected-vehicle trails, and mode-coloured DETECT labels — Boston, Austin, Minneapolis, Helsinki, the Netherlands, Norway, South East Queensland | Operator GTFS-Realtime feeds | 🟢 | | 🚲 **Bikeshare** | Live station availability | GBFS | 🟢 | @@ -290,6 +297,13 @@ Fifteen layers and map sources. **Thirteen have a keyless path.** Some offer add | 🔥 **Active Fires** | Live NASA FIRMS detections, trailing 24h | NASA FIRMS | 🟡 | | 🚀 **Space Missions** | Rolling 30-day launches with payload, stage, and recovery detail | Launch Library 2 | 🟢 (🟡 optional token raises the allowance) | | 🎖️ **Mapped Installations** | Viewport-bounded military-site context from community mapping — incomplete by nature, and labeled that way | OpenStreetMap | 🟢 | +| 🌬️ **Wind** | Animated 10 m forecast wind with an optional speed, temperature or pressure color field and a reading at map center | NOAA GFS / ECMWF IFS | 🟢 | +| 🌦️ **Observed Weather** | Rain radar (contiguous US), Satellite clouds (GOES regional or global infrared, Clouds only or Full image) and Lightning density (Americas and Pacific) on one history timeline | NOAA nowCOAST | 🟢 | +| 🌀 **Cyclones** | Advisory positions, forecast tracks and uncertainty cones for the Atlantic and eastern/central North Pacific | NOAA NHC / CPHC | 🟢 | + +**Weather, keyless.** **Wind** animates 10 m forecast flow from NOAA GFS or ECMWF IFS, with an optional color field and a reading at map center. **Rain radar**, **Satellite clouds** and **Lightning density** are observations on one history timeline in the **WEATHER** panel (step back, **Play**, **Latest**); **Cyclone advisories** draw NHC and CPHC positions, forecast tracks and cones. On Google 3D Tiles the observed layers float above the city as translucent shells, sharpened around your view. + +In the app, **Data Layers** groups them as Movement, Cameras, Infrastructure, Events, Weather and Utilities. **The basemap ladder — what each tier buys you:** @@ -297,7 +311,7 @@ Fifteen layers and map sources. **Thirteen have a keyless path.** Some offer add | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 🟢 Nothing | Esri World Imagery satellite basemap + keyless terrain, in 2D. OSM takes over automatically if Esri is unreachable; if terrain is unavailable the globe continues without it | | 🟡 A free Cesium ion token | **Google Photorealistic 3D cities** and world terrain — eligible personal, non-commercial use; current ion terms and quotas apply | -| 🔴 A Google Maps key | The same 3D direct from Google, plus in-app place search — the billing-enabled, metered route | +| 🔴 A Google Maps key | The same 3D direct from Google, plus Google place search — the billing-enabled, metered route | ![A reconstructed Falcon 9 ascent climbing and curving into its projected orbit](docs/media/08-falcon9-replay.gif) @@ -364,7 +378,8 @@ src/ ├── hud.js # Intelligence HUD + AI scene summary ├── keySetup.js # POWER UP panel — in-app provider keys (dev server only) ├── mapStackController.js # Basemap switching — Google 3D / Esri / OSM / ion stacks -├── voice/ # OpenAI Realtime session + 28 voice tools +├── voice/ # OpenAI Realtime session + 29 voice tools +├── layers/ # Layer components — weather, wind, cyclones, transit, ALPR, … ├── data/ # One module per layer + orchestration + context store │ ├── iconOrientation.js # Screen-projected headings + horizon cull │ └── local_data/ # Bundled datasets (per-folder provenance) @@ -384,6 +399,11 @@ each provider enables; none is required to start. See the [setup instructions](#then-power-it-up--in-the-app-not-in-a-file) for storage and configuration details. +No key needed for Wind, Rain radar, Satellite clouds, Lightning density, +Cyclone advisories, Mapped ALPR Cameras, Transit, Directions, Delaware live +video, and coordinate or bundled-place search. A layer row waiting on a key +names it. + ### Choose the capabilities you want Six keys. Four have a free tier, and the two 🔴 ones are metered: @@ -467,9 +487,9 @@ Honest numbers, roughly, as of mid-2026 — always check the provider pricing pa | | Cost reality | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **🟢 Most layers** | **$0, no signup.** OpenSky anon, USGS, CelesTrak, adsb.lol, city CCTV, Radio Browser, GBFS, Launch Library 2, bundled datasets. | +| **🟢 Most layers** | **$0, no signup.** OpenSky anon, USGS, CelesTrak, adsb.lol, city CCTV, Radio Browser, GBFS, Launch Library 2, transit feeds, OSRM routing, NOAA and ECMWF weather, OpenStreetMap ALPR mapping, bundled datasets. | | **🟡 The free-key tier** | **$0 with a signup.** AISStream, FIRMS, TomTom, OpenSky, plus Cesium ion for eligible personal/non-commercial use. Provider quotas and eligibility still apply. | -| **🗺️ Google 3D tiles** | **Free through an eligible Cesium ion Community account within its quota; metered through a direct Google key.** Use the direct route for GEV place search or commercial deployment, verify current provider terms, and set budget alerts where billing is enabled. | +| **🗺️ Google 3D tiles** | **Free through an eligible Cesium ion Community account within its quota; metered through a direct Google key.** Use the direct route for Google place search or commercial deployment, verify current provider terms, and set budget alerts where billing is enabled. | | **🔴 OpenAI voice** | **The one that costs real money — so the app meters it for you.** Realtime audio runs a few cents per active minute; an evening of heavy use is single-digit dollars. A live session-spend readout sits next to the mic, with an STD/MINI model toggle, a $2 warning, and a **$5 hard cap that ends the session**. The voice context window is kept deliberately short too. | Google's direct 3D route is surprisingly generous: the first 1,000 Photorealistic diff --git a/docs/APPLICATION.md b/docs/APPLICATION.md index cf901c8a6..deafe9168 100644 --- a/docs/APPLICATION.md +++ b/docs/APPLICATION.md @@ -105,14 +105,17 @@ checks when changing this wiring. `src/search` owns forward/reverse geocoding, place search and route provider interfaces. `createStandaloneApplication({ geospatial })` accepts `endpoints` -and `providers`; the defaults preserve Google/Photon search, Google place context -and the local OSRM route proxy. Location, annotations, HUD labels and voice use -the composed service. Provider-specific credentials belong in the selected -transport; server secrets never belong in browser configuration. +and `providers`. Default forward search tries decimal coordinates and bundled +place names (`presets`) first, without a network request, then Google when a key +is configured, Photon, and the local `/api/geocode` Nominatim route. The +defaults also keep Google place context and the local OSRM route proxy. +Location, annotations, HUD labels and voice use the composed service. +Provider-specific credentials belong in the selected transport; server secrets +never belong in browser configuration. -For a compatible protocol, configure `geocode`, `photon`, `reverse`, `textSearch`, -`nearby` or `route` endpoints. These are developer-selected configuration, not -URLs accepted from page queries or model arguments. A different protocol supplies +For a compatible protocol, configure `geocode`, `photon`, `nominatim`, `reverse`, +`textSearch`, `nearby` or `route` endpoints. These are developer-selected +configuration, not URLs accepted from page queries or model arguments. A different protocol supplies an adapter function instead. The exported `createDefaultPlaceSearch` constructor supports the same options for direct composition: @@ -181,10 +184,14 @@ separate constructors. Pass these to `createApplication`; use its `signal` and `defer` for ownership. The compatibility catalog is still page-scoped: construct one application per page. Controls, actions and renderers use the same layer instances. Configure sources with `application/sources` before registration or -state restoration, and release them after the consumers stop. +state restoration, and release them after the consumers stop. The catalog +constructor (`application/layers`) also requires `wind`, `weather` and +`cyclones` sources with `getSnapshot` for the Weather layers, and owns the +observed-history clock those layers share for the catalog's lifetime. `application/services` accepts boundary, terrain, regional-context, weather and -summary services. `application/requests` supplies the existing HTTP protocols +summary services; its weather service supplies cockpit local conditions, not the +Weather layers. `application/requests` supplies the existing HTTP protocols with configurable endpoints and a scoped transport. Changing an endpoint works only for a compatible protocol; another protocol supplies a service adapter. Cancellation discards late response bodies, and replacing a source invalidates diff --git a/docs/CURRENT-STATE.md b/docs/CURRENT-STATE.md index 6453981aa..1ad6f8080 100644 --- a/docs/CURRENT-STATE.md +++ b/docs/CURRENT-STATE.md @@ -146,12 +146,11 @@ messages use each product's eligibility gap (30 minutes, or three hours for the global mosaic). Wind shows forecast valid and issue times and does not follow history. Satellite clouds uses Clouds only / Full image configuration labels. -Left weather rows retain the toggle, one status line with a source tooltip, -configuration chips and the cyclone selection/focus list. Cyclone advisory, -position time, wind, pressure, geometry status and the official advisory link -live in the card. Controls opens the corresponding left row. The panel hides -when empty, auto-expands once per page session and then preserves the user's -collapsed state. Status lines reserve their space and refreshes are coalesced +Left weather rows retain only the toggle and one status line with a source +tooltip. Configuration and the cyclone Storms list live in the cards, as do the +cyclone advisory, position time, wind, pressure, geometry status and the +official advisory link. The panel hides when empty, auto-expands once per page +session and then preserves the user's collapsed state. Status lines reserve their space and refreshes are coalesced per frame. Generic keyed rail cards and the native rail timeline preserve DOM nodes and avoid identical writes; the weather panel owns descriptor mapping. Inspection emphasizes the chosen scalar and marks the exact sampled location; @@ -2637,7 +2636,7 @@ test:track` 43 tracking invariants · headless QA harnesses under > ISS pass prediction, and per-layer data attribution. Gate at close: unit 98/98, build clean, > track 19/19, + five QA harnesses (heading 16/16, sprites 9/9, cctv 5/5, failstate 5/5, > attribution 18/18). New modules: `src/data/{motionModel,aircraftMeta,aircraftClass,aircraftIcons,issPass,routePlausible,dataCredits}.js`. -> The live runtime now declares 28 voice tools; the 17→20 count above is retained only as milestone history. +> The live runtime now declares 29 voice tools; the 17→20 count above is retained only as milestone history. ## Canonical Docs Order @@ -3526,7 +3525,7 @@ silently demoting every later lookup for the session. - **Token flow**: browser fetches a short-lived client secret from `/api/realtime/token`; the Vite middleware holds `OPENAI_API_KEY` and posts the full session config (instructions, tool schemas, VAD, truncation) to `api.openai.com/v1/realtime/client_secrets`. SDP exchange goes directly to `api.openai.com/v1/realtime/calls` with the ephemeral token. - **Session defaults** (env-tunable): model `gpt-realtime-2` (or `gpt-realtime-2.1-mini` when the MINI tier is selected — see the model-tier entry below), voice `marin`, reasoning effort `low`, semantic VAD with low eagerness, no response interruption, context window truncated to ~3,000 post-instruction tokens with 0.5 retention ratio — the conversational window stays short because map state is fetched live per turn. -- **Twenty-eight tools** (schemas defined server-side in `vite.config.js`, executed client-side in `src/voice/gevActions.js`): `fly_to_location`, `select_nearest_aircraft`, `adjust_camera_zoom`, `zoom_to_globe`, `set_layer_visibility`, `show_data_layers_menu`, `set_panel_open`, `set_visual_style`, `get_entity_context`, `get_current_view_state`, `set_hud`, `set_detection`, `set_map_stack`, `set_post_processing`, `control_scene`, `control_cctv`, `set_context_mode`, `control_cockpit`, `control_radio`, `track_entity`, `stop_tracking`, `frame_overhead`, `annotate_map`, `clear_annotations`, `move_camera`, `fly_route`, `analyst_query`, and `next_iss_pass`. +- **Twenty-nine tools** (argument schemas in `src/voice/actionSchemas.js`, served with their descriptions by `server/providers/openai/tools.js`, executed client-side in `src/voice/gevActions.js`): `fly_to_location`, `select_nearest_aircraft`, `adjust_camera_zoom`, `zoom_to_globe`, `set_layer_visibility`, `show_data_layers_menu`, `set_panel_open`, `set_visual_style`, `get_entity_context`, `get_current_view_state`, `set_hud`, `set_detection`, `set_map_stack`, `set_post_processing`, `control_scene`, `control_cctv`, `set_context_mode`, `control_cockpit`, `control_radio`, `track_entity`, `stop_tracking`, `frame_overhead`, `annotate_map`, `clear_annotations`, `move_camera`, `fly_route`, `analyst_query`, `next_iss_pass`, and `next_satellite_pass`. > **Reading `npm test` totals:** the count depends on the Node major. The two > GC-bracketed allocation microbenchmarks (`src/data/focusAllocations.test.mjs` @@ -4166,9 +4165,9 @@ restoring a host joins the retained history target. The wind row explicitly says “Forecast · does not follow history” while the observed clock is in history mode. The catalog exposes `weatherClock` and destroys it with its lifetime signal. -Existing row controls retain source, opacity, coverage navigation and transport; -no controls move in this pass. The viewer clock is untouched. Observation layers -are off by default; share/persist includes appearance and product, while history +Source, opacity, coverage navigation and transport controls live in the WEATHER +panel's cards and timeline, not in the rows. The viewer clock is untouched. +Observation layers are off by default; share/persist includes appearance and product, while history is transient and shared links open latest. Rendering retains the previous frame when an incoming frame fails; no eligible historical frame instead hides imagery. diff --git a/docs/KNOWN-ISSUES.md b/docs/KNOWN-ISSUES.md index 92c92c1f9..e41623cc6 100644 --- a/docs/KNOWN-ISSUES.md +++ b/docs/KNOWN-ISSUES.md @@ -1,6 +1,6 @@ # KNOWN ISSUES -Updated: July 8, 2026 +Updated: September 22, 2026 This file tracks active runtime issues only. @@ -78,6 +78,56 @@ Status: Open (owner-accepted 2026-07-08, documented) --- +### Weather layers: coverage and meaning +Status: Open (source limits, by design) + +- **Rain radar covers the contiguous United States only.** It shows MRMS + reflectivity in dBZ, not rainfall rate or a forecast; a gap in coverage does not + mean no precipitation. +- **Lightning density is a ground-network grid, not GLM flashes.** It is NOAA's + 15-minute density product derived from Vaisala NLDN/GLD360 on an approximately + 8 km grid, for the Americas and Pacific only (110°E across the dateline to 0°, + 25°S–80°N). It is not a live strike counter or an all-clear. +- **Cyclone advisories cover NOAA's basins only:** the Atlantic and the + eastern/central North Pacific (NHC and CPHC). Storms elsewhere do not appear. + The cone is forecast-center uncertainty, not storm size. +- **Satellite clouds:** global infrared is hourly with typically 2–3 hours of + source latency. Clouds only is a brightness filter, not a cloud mask. +- **Wind is a forecast.** The animation flows through one forecast on an + approximately 1° grid and does not advance forecast time or follow the + observed-history timeline. +- **History is not shared.** Share links carry the weather layers and their + settings but open at Latest. +- **3D Tiles detail window during history playback:** when a frame's detail image + is slow to arrive, the window may fall back to the coarser full-extent image + until it does. +- Native hardware GPU behavior of the wind and weather renderers is not yet + verified. + +--- + +### Satellite passes and analyst answers +Status: Open (by design) + +- Pass predictions search the next 24 hours for satellites in the loaded catalog. + Visibility is a geometric estimate (satellite sunlit, observer's Sun at or + below −6°); it ignores weather, satellite brightness and orbital-element age. +- Analyst counts and ranks cover a bounded set of loaded records (by default + 2,000 per layer for satellites, datacenters and dams), so omitted records can + change a nearest or count answer. Satellite distance is ground distance. + +--- + +### Live camera video (HLS) +Status: Open (limits) + +- At most two live-video sessions run at once. RTMP-only sources and encrypted, + fMP4 or byte-range playlists are not supported. +- When live video fails, the camera falls back to its labeled still, Street View + or placeholder frame, which is not live video. + +--- + ## Closed / Intentional (for clarity) ### Proxy SSRF and error-surface hardening gaps @@ -118,5 +168,14 @@ Context: converted to **live NASA FIRMS data** on 2026-07-16: the `/api/firms` proxy merges three VIIRS NRT sources (trailing 24 h, 30 min cache, serve-stale-on-failure) and the bundled snapshot was deleted. Requires a free server-side `FIRMS_MAP_KEY`; without it - the layer shows a KEY REQUIRED state. -- Weather radar is still held out of OSS v1 after QA found the previous overlay did not provide reliable visible value. + the layer row reads "Needs FIRMS_MAP_KEY — add it in Provider Settings". + +--- + +### Weather radar held out of the open-source release +Status: Closed — observed rain radar shipped (September 2026) + +Context: +- Rain radar, Satellite clouds, Lightning density, Wind and Cyclone advisories + are in the Weather group of Data Layers. Their current limits are listed under + "Weather layers: coverage and meaning" above. diff --git a/src/tooling/transitQa.test.mjs b/src/tooling/transitQa.test.mjs index 85afbe0c8..44da48386 100644 --- a/src/tooling/transitQa.test.mjs +++ b/src/tooling/transitQa.test.mjs @@ -675,7 +675,7 @@ test('public transit documentation uses courtesy attribution and the approved gr ); assert.ok( readme.includes( - 'Fifteen layers and map sources. **Thirteen have a keyless path.**', + 'Nineteen layers and map sources. **Seventeen have a keyless path.**', ), ); assert.ok(