Release God's Eye View as open source
No files matched your search
@@ -0,0 +1,108 @@
|
||||
# KNOWN ISSUES
|
||||
|
||||
Updated: July 8, 2026
|
||||
|
||||
This file tracks active runtime issues only.
|
||||
|
||||
This file records current known issues; historical planning material is not part
|
||||
of the public release.
|
||||
|
||||
---
|
||||
|
||||
## Open
|
||||
|
||||
### Street traffic can be slow/uneven when panning across dense city blocks
|
||||
Status: Open (partially mitigated)
|
||||
|
||||
Context:
|
||||
- Current traffic loader fetches one clamped viewport tile at a time (major pass, then full pass).
|
||||
- In dense cores, some visible roads can appear late after city jumps or fast pans.
|
||||
- Zooming into adjacent streets does not always immediately trigger higher-detail coverage for all visible roads.
|
||||
|
||||
Current mitigation in runtime:
|
||||
- Fair per-road dot budget allocation (reduces hard starvation under global `MAX_DOTS` cap).
|
||||
- Center-shift threshold (reduces stale overlap lock while panning).
|
||||
|
||||
Next iteration candidates:
|
||||
- Prioritize currently visible road segments inside the active viewport before off-center segments.
|
||||
- Add neighbor prefetch ring for nearby tiles after jump-to-city actions.
|
||||
- Add adaptive dot cap by frame time (coverage first, density second).
|
||||
- Promote sync chip from loading indicator to true multi-phase progress.
|
||||
|
||||
---
|
||||
|
||||
### CCTV panel can appear "missing" after layout refactors
|
||||
Status: Open (workaround available)
|
||||
|
||||
Context:
|
||||
- Panel positions are persisted in local storage and can restore off-screen after UI changes.
|
||||
|
||||
Workaround:
|
||||
- In browser console:
|
||||
- `localStorage.removeItem('godsEyeView.v6.panelPos.cctv-panel');`
|
||||
- `localStorage.removeItem('godsEyeView.v6.panelCollapsed.cctv-panel');`
|
||||
- `location.reload();`
|
||||
|
||||
Related keys (current versions):
|
||||
- Panel positions: `godsEyeView.v7.panelPos.<panel-id>` (re-versioned 2026-06-10)
|
||||
- Panel collapsed state: `godsEyeView.v6.panelCollapsed.<panel-id>`
|
||||
- CCTV calibration: `godsEyeView.cctv.calibration.v2`
|
||||
|
||||
---
|
||||
|
||||
### Height-datum residuals
|
||||
Status: Open (accepted 2026-07-08, documented)
|
||||
|
||||
- **Cold-start floor latency:** at a freshly-visited airport, grounded/low aircraft
|
||||
float low for ~1–2 poll cycles (30–60 s) and rise as terrain floors resolve;
|
||||
a few stragglers take one more poll.
|
||||
- **Born-grounded first poll:** a contact first seen on the ground with no altitude
|
||||
data renders at the geoid for ≤1 poll until its floor cell warms.
|
||||
- Full context, improvement ideas, and the verification oracle
|
||||
(`scripts/qa-floor-verify.mjs`):
|
||||
the height-datum section in `docs/CURRENT-STATE.md`.
|
||||
|
||||
---
|
||||
|
||||
## Closed / Intentional (for clarity)
|
||||
|
||||
### Proxy SSRF and error-surface hardening gaps
|
||||
Status: Closed as fixed on `main`
|
||||
|
||||
Context:
|
||||
- Proxy middleware previously allowed broader error/internal surface area and looser upstream handling.
|
||||
- Current `main` includes hardened proxy behavior in `vite.config.js`:
|
||||
- CCTV upstream URL no longer accepted from client query params.
|
||||
- Error payloads are sanitized.
|
||||
- OpenSky cache stores successful responses only.
|
||||
- OpenSky token refresh is coalesced.
|
||||
- GBFS/CCTV memory growth is bounded.
|
||||
|
||||
Validation target:
|
||||
- `vite.config.js`
|
||||
|
||||
---
|
||||
|
||||
### NVG vignette edge color bleed
|
||||
Status: Closed as fixed in current shader composite
|
||||
|
||||
Context:
|
||||
- Earlier builds leaked original scene colors near the NVG tube edge.
|
||||
- Current composite now masks NVG output with tube falloff before final blend, removing the color edge bleed.
|
||||
|
||||
Validation target:
|
||||
- `src/styles/surveillance.js`
|
||||
|
||||
---
|
||||
|
||||
### Wildfires layer unavailable / static bundled snapshot
|
||||
Status: Closed — live FIRMS integration shipped (2026-07-16)
|
||||
|
||||
Context:
|
||||
- Wildfires (NASA FIRMS) were removed from runtime in v0.5.3, returned June 2026 as a
|
||||
bundled-snapshot layer (`local-firms`, 2026-05-25 data, ~58 MB in-repo), and were
|
||||
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.
|
||||
@@ -0,0 +1,144 @@
|
||||
# Performance baseline
|
||||
|
||||
This page records one hardware-rendered Apple M5 comparison captured on 22
|
||||
August 2026 in Chrome 150 at 1440 x 900. It is not a minimum hardware
|
||||
specification and should not be used to predict performance on untested systems.
|
||||
The original capture artifacts are not included here, so this page records
|
||||
results rather than defining a runnable benchmark.
|
||||
|
||||
## Test context
|
||||
|
||||
The baseline was captured on 22 August 2026 with these conditions:
|
||||
|
||||
| Setting | Value |
|
||||
| --- | --- |
|
||||
| Renderer | Apple M5 Metal through the hardware ANGLE path |
|
||||
| Browser | Chrome 150 in a fresh isolated profile |
|
||||
| Viewport | 1440 x 900 at device pixel ratio 1 |
|
||||
| Focus | Page foregrounded for controlled scenes |
|
||||
| Scene sample | 5 seconds of scripted motion, then 5 seconds at rest |
|
||||
| Startup | Browser cache disabled; three samples |
|
||||
|
||||
The capture covered three startup samples, 16 cold layer scenarios with 14
|
||||
measurements, 23 controlled option and stress scenes, and five
|
||||
hardware-rendered overlay scenes.
|
||||
|
||||
## Startup
|
||||
|
||||
| Sample | App ready | Initial settle | Load event | Motion / rest | Used JS heap |
|
||||
| ---: | ---: | ---: | ---: | ---: | ---: |
|
||||
| 1 | 784.980 ms | 2,035.082 ms | 439.5 ms | 60 / 60 FPS | 102.9 MiB |
|
||||
| 2 | 604.849 ms | 1,855.836 ms | 442.4 ms | 60 / 60 FPS | 111.6 MiB |
|
||||
| 3 | 558.527 ms | 1,809.592 ms | 438.8 ms | 60 / 60 FPS | 105.1 MiB |
|
||||
| Median | 604.849 ms | 1,855.836 ms | 439.5 ms | 60 / 60 FPS | 105.1 MiB |
|
||||
|
||||
The initial-settle measurement is the more useful launch reference because it
|
||||
includes the first visual and data settling window. All three samples reached
|
||||
the display ceiling during both motion and rest.
|
||||
|
||||
## Cold layer activation
|
||||
|
||||
Cold activation was measured separately from warm option switching. Live object
|
||||
counts are included so that future runs can compare source populations before
|
||||
attributing a difference to the client.
|
||||
|
||||
| Layer | Activation | Source count | Motion / rest | Used JS heap |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| CCTV city | 19,608.240 ms | 48 | 60 / 60 FPS | 192.7 MiB |
|
||||
| Space Missions (report label: Rocket missions) | 3,581.066 ms | 26 | 60 / 60 FPS | 131.3 MiB |
|
||||
| Radio | 3,458.709 ms | 750 | 60 / 60 FPS | 124.8 MiB |
|
||||
| Bikeshare | 2,069.498 ms | 633 | 60 / 60 FPS | 157.4 MiB |
|
||||
| Datacenters | 817.693 ms | 4,362 | 59.6 / 60 FPS | 328.2 MiB |
|
||||
| Flights | 667.671 ms | 247 | 60 / 60 FPS | 118.4 MiB |
|
||||
| Submarine cables | 614.727 ms | 2,629 | 60 / 60 FPS | 412.0 MiB |
|
||||
| Military Flights | 557.113 ms | 68 | 60 / 60 FPS | 118.4 MiB |
|
||||
|
||||
CCTV had the largest cold activation cost in this capture. Submarine cables
|
||||
used the most heap, followed by datacenters. Completed single-layer samples
|
||||
generally reached 60 FPS, so activation time and heap separate these cases more
|
||||
clearly than steady-state frame rate.
|
||||
|
||||
## Aircraft, detection, and Cockpit
|
||||
|
||||
| Scene | Motion / rest |
|
||||
| --- | ---: |
|
||||
| Idle globe | 60 / 60 FPS |
|
||||
| Flights, 2D | 60 / 60 FPS |
|
||||
| Flights, 3D proximity | 60 / 60 FPS |
|
||||
| Flights, all 3D models | 60 / 60 FPS |
|
||||
| Military Flights, all 3D models | 60 / 60 FPS |
|
||||
| Detection at 25% | 39.3 / 41.1 FPS |
|
||||
| Detection at 50% | 37.4 / 39.8 FPS |
|
||||
| Detection at 100% | 34.4 / 35.5 FPS |
|
||||
| Cockpit | 49.6 / 49.2 FPS |
|
||||
|
||||
The clean detection scenes processed 8,169 to 8,170 observations. Selected
|
||||
labels rose from 14 at 25% density to 28 at 50% and 56 at 100%. The aircraft
|
||||
rows came from an earlier loaded, foreground-controlled pass because the clean
|
||||
rerun received no live aircraft rows.
|
||||
|
||||
## Visual styles and combined stress
|
||||
|
||||
| Scene | Motion / rest |
|
||||
| --- | ---: |
|
||||
| Normal | 60 / 60 FPS |
|
||||
| CRT (report label: Retro) | 60 / 60 FPS |
|
||||
| NVG (report label: Surveillance) | 60 / 60 FPS |
|
||||
| FLIR (report label: Thermal) | 49 / 60 FPS |
|
||||
| Anime | 60 / 59.8 FPS |
|
||||
| Noir | 47 / 56.6 FPS |
|
||||
| Snow | 42.3 / 45.8 FPS |
|
||||
| Combined static | 57.6 / 60 FPS |
|
||||
| Combined operational | 39.9 / 43.1 FPS |
|
||||
|
||||
The combined static scene rendered 11,575 objects, used 872.2 MiB of JavaScript
|
||||
heap, and issued 48,665 text draws during motion and 54,106 at rest. The combined
|
||||
operational sample contained 3,909 observations and two selected labels, but its
|
||||
live aircraft and traffic rows were empty, so it remains a limited stress case.
|
||||
|
||||
Snow, Noir, dense detection, and text-heavy combined layers are the clearest
|
||||
controlled comparison points for later optimization work.
|
||||
|
||||
## Keyed live sources
|
||||
|
||||
NASA FIRMS, AISStream, and TomTom were captured in a separate hardware-rendered
|
||||
pass. The page was visible but was not the focused window, so these frame rates
|
||||
must not be compared directly with the foreground-controlled scenes above.
|
||||
|
||||
| Source | Point-in-time population | Activation or coverage | Motion / rest |
|
||||
| --- | ---: | --- | ---: |
|
||||
| NASA FIRMS | 100,430 detections in 3,557 cells | 30.0 s activation | 32.1 / 55.2 FPS |
|
||||
| AISStream | 12,000 vessels | 6.4 s activation | 22.1 / 29.8 FPS |
|
||||
| TomTom Traffic | 4,222 road dots | 70% coverage, 2 decoded tiles | 45.0 / 51.7 FPS |
|
||||
|
||||
These populations change continuously. A future comparison must record the
|
||||
live counts again and match the focus conditions.
|
||||
|
||||
## Controls for a future capture
|
||||
|
||||
Use the same controls before attributing a difference to the application:
|
||||
|
||||
1. Record the exact GPU renderer and reject software-rendered or unavailable GPU
|
||||
strings.
|
||||
2. Use a 1440 x 900 viewport at device pixel ratio 1 and keep the page focused.
|
||||
3. Measure cache-disabled startup separately from cold layer activation and warm
|
||||
option switching.
|
||||
4. Repeat startup three times and compare medians.
|
||||
5. Sample each option for 5 seconds in scripted motion and 5 seconds at rest.
|
||||
6. Record live object counts before attributing a difference to the client.
|
||||
7. Treat a live-source outage as missing coverage, not as evidence of low client
|
||||
rendering cost.
|
||||
|
||||
## What is not established yet
|
||||
|
||||
- This report does not establish Windows performance.
|
||||
- The report does not record machine memory capacity, so it cannot support a
|
||||
minimum-memory recommendation.
|
||||
- The report does not cover other GPU renderers or viewport configurations.
|
||||
- Military Installations is outside this comparison because it requires close
|
||||
camera context.
|
||||
- The keyed pass has no controlled rerun suitable for comparison with the
|
||||
option scenes.
|
||||
|
||||
Use this page as a regression baseline for one known hardware and browser
|
||||
configuration, not as a compatibility guarantee.
|
||||
|
After Width: | Height: | Size: 981 KiB |
|
After Width: | Height: | Size: 5.6 MiB |
|
After Width: | Height: | Size: 5.8 MiB |
|
After Width: | Height: | Size: 3.0 MiB |
|
After Width: | Height: | Size: 4.8 MiB |
|
After Width: | Height: | Size: 5.3 MiB |
|
After Width: | Height: | Size: 6.0 MiB |
|
After Width: | Height: | Size: 4.8 MiB |
|
After Width: | Height: | Size: 889 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 3.7 MiB |
|
After Width: | Height: | Size: 2.2 MiB |
|
After Width: | Height: | Size: 3.0 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
@@ -0,0 +1,40 @@
|
||||
# README media provenance
|
||||
|
||||
## Capture GIFs
|
||||
|
||||
Bilawal Sidhu created and owns the following 17 GIFs and has authorized their inclusion and redistribution as part of this public repository and its project documentation. Any appearance by Bilawal Sidhu in these captures is included with his permission.
|
||||
|
||||
- `hero-open-source-reveal.gif`
|
||||
- `06-cockpit-ar.gif`
|
||||
- `start-here/airport-ground-traffic-google-3d.gif`
|
||||
- `03-austin-cctv.gif`
|
||||
- `14-iss-over-ukraine.gif`
|
||||
- `01-style-sweep.gif`
|
||||
- `12-switch-aircraft-cockpit.gif`
|
||||
- `start-here/military-cockpit-dense-google-3d.gif`
|
||||
- `01-voice-annotate-zilker.gif`
|
||||
- `04-airport-distance.gif`
|
||||
- `15-global-radio-layer.gif`
|
||||
- `08-falcon9-replay.gif`
|
||||
- `09-undersea-cables.gif`
|
||||
- `07-helicopter-loops.gif`
|
||||
- `10-walking-route-flythrough.gif`
|
||||
- `08-boneyard.gif`
|
||||
- `05-traffic-to-cctv.gif`
|
||||
|
||||
Copyright © Bilawal Sidhu. These files are not covered by the project's MIT License. Permission is limited to their inclusion and redistribution with this repository and its project documentation. No permission is granted for standalone reuse or modification. Commercial reuse outside this repository requires separate permission. No share-alike license applies.
|
||||
|
||||
The GIFs are promotional captures of God's Eye View. They include Google Photorealistic 3D Tiles and public or third-party data layers with in-frame attribution. Bilawal Sidhu's ownership and permission cover the captures and his likeness; they do not replace the terms of Google Maps Platform or any displayed data provider. Keep the visible attribution intact.
|
||||
|
||||
## Public README PNGs
|
||||
|
||||
Bilawal Sidhu published the following PNGs in the existing public `bilawalsidhu/gods-eye-view` repository and authorized their continued inclusion and redistribution with this repository and its project documentation:
|
||||
|
||||
- `youtube-popular-videos.png`
|
||||
- `open-source-survey.png`
|
||||
|
||||
Source: [`assets/youtube-popular-videos.png`](https://github.com/bilawalsidhu/gods-eye-view/blob/7afb3beefb2dd39110ed117c8f06825e9ca2ada4/assets/youtube-popular-videos.png) and [`assets/open-source-survey.png`](https://github.com/bilawalsidhu/gods-eye-view/blob/7afb3beefb2dd39110ed117c8f06825e9ca2ada4/assets/open-source-survey.png) in public repository commit [`7afb3beefb2dd39110ed117c8f06825e9ca2ada4`](https://github.com/bilawalsidhu/gods-eye-view/commit/7afb3beefb2dd39110ed117c8f06825e9ca2ada4). The localized files preserve the source bytes unchanged.
|
||||
|
||||
These files are not covered by the project's MIT License. No permission is granted for standalone reuse or modification. Commercial reuse outside this repository requires separate permission. No share-alike license applies.
|
||||
|
||||
The authorization covers the PNGs as project promotional material. It does not claim ownership of platform interfaces, trademarks, avatars, data, or third-party imagery visible within the screenshots. Those elements remain subject to their respective owners' terms.
|
||||
|
After Width: | Height: | Size: 6.2 MiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 8.2 MiB |
|
After Width: | Height: | Size: 958 KiB |
@@ -0,0 +1,66 @@
|
||||
# OpenSky Auth Setup
|
||||
|
||||
God's Eye View uses explicit auth modes for `/api/opensky`:
|
||||
|
||||
- `OPENSKY_AUTH_MODE=oauth` (default, recommended)
|
||||
- `OPENSKY_AUTH_MODE=auto` (OAuth first, then Basic fallback)
|
||||
- `OPENSKY_AUTH_MODE=basic`
|
||||
- `OPENSKY_AUTH_MODE=anon`
|
||||
|
||||
Reference: OpenSky REST API docs recommend OAuth2 Client Credentials flow.
|
||||
|
||||
## Quick Start (OAuth Client JSON)
|
||||
|
||||
Import credentials from JSON (`clientId`/`clientSecret` or `client_id`/`client_secret`) into Keychain:
|
||||
|
||||
```bash
|
||||
./scripts/opensky-import-client.sh /path/to/credentials.json
|
||||
# or: npm run opensky:import -- /path/to/credentials.json
|
||||
```
|
||||
|
||||
Then launch:
|
||||
|
||||
```bash
|
||||
./scripts/dev-fresh.sh
|
||||
```
|
||||
|
||||
Expected startup lines:
|
||||
|
||||
- `OpenSky auth mode: oauth`
|
||||
- `OpenSky OAuth: configured`
|
||||
|
||||
## Optional: Launch With File (No Keychain Import)
|
||||
|
||||
```bash
|
||||
OPENSKY_CREDENTIALS_FILE=/path/to/credentials.json ./scripts/dev-fresh.sh
|
||||
```
|
||||
|
||||
Launchers resolve OAuth creds in this order:
|
||||
|
||||
1. `OPENSKY_CLIENT_ID` + `OPENSKY_CLIENT_SECRET`
|
||||
2. `OPENSKY_CREDENTIALS_FILE`
|
||||
3. Keychain (`opensky-network` / `client_id`, `client_secret`)
|
||||
|
||||
## Basic Auth (Legacy)
|
||||
|
||||
Basic auth is still supported for now, but OpenSky is moving away from it.
|
||||
|
||||
```bash
|
||||
OPENSKY_AUTH_MODE=basic ./scripts/dev-fresh.sh
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Inspect proxy headers:
|
||||
|
||||
```bash
|
||||
curl -si http://localhost:4173/api/opensky | grep -iE 'HTTP/|X-OpenSky-Auth'
|
||||
```
|
||||
|
||||
Useful reasons:
|
||||
|
||||
- `oauth_invalid_or_missing`: OAuth client not found/usable
|
||||
- `oauth_invalid_credentials`: OAuth client rejected by OpenSky
|
||||
- `basic_invalid_credentials`: username/password rejected
|
||||
- `missing_basic_creds`: basic mode missing user/pass
|
||||
- `rate_limited`: OpenSky throttling
|
||||