mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
feat(intro): v2 — cities, accelerating sweep, detections, thriller sound design
- City engine: Esri ground, OSM buildings that rise with the scan, road ribbons carrying modelled traffic coloured by congestion, NYC DOT cameras, real ADS-B, MBTA GTFS lines + realtime vehicles, LAX runways with approach strobes, Fort Bragg restricted volumes, Everest terrain with contours. - Indexing keeps accelerating into a 260-capture global sweep while the planet whips a full turn. - The eye opens: aperture blades, sensor array waking, optics calibration, radar sweep, orbiting coordinate ring. - Camera wall with YOLOv8n detections and a city-pulse trace. - Ends on GOD'S EYE VIEW / OMNISCIENCE. - audio/sfx.py: sound design only, built to sit under a music track. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01KqP857pippaUs6konSDfe8
This commit is contained in:
30 files changed
+8921
-1442
No files matched your search
@@ -0,0 +1,72 @@
|
||||
"""Poll live ADS-B (adsb.lol, fallback adsb.fi) around each scene 3x, 20 s apart.
|
||||
Writes city/<slug>/air.json with latest sample per aircraft + short track history."""
|
||||
import json, os, sys, time, requests
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
from common import SCENES, enu
|
||||
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
|
||||
RAD = {'nyc': 25, 'lax': 25, 'bragg': 25, 'boston': 20}
|
||||
HELI_TYPES = {'EC35','EC30','EC45','EC55','EC20','EC25','EC75','EC13','EC40','AS50','AS55','AS65','AS32','AS3B','H125','H130','H135','H145','H160','H175','B06','B06T','B407','B412','B427','B429','B430','B47G','B505','B212','B222','B230','B105','BK17','R22','R44','R66','S76','S92','S61','S64','S70','H60','UH60','MH60','HH60','H47','CH47','H53','A109','A119','A139','A169','A189','AW09','MI8','MI17','UH1','UH1Y','AH1','AH64','H64','V22','MV22','CABR','G2CA','EN28','EN48','H269','H500','MD52','MD60','NH90','LYNX','PUMA','GAZL','EH10','H1','B505'}
|
||||
H = {'User-Agent': 'gods-eye-view-intro/1.0 (film research)'}
|
||||
def fetch(slug):
|
||||
lat, lon, _ = SCENES[slug]; nm = RAD[slug]
|
||||
for url, key in ((f'https://api.adsb.lol/v2/point/{lat}/{lon}/{nm}', 'ac'),
|
||||
(f'https://opendata.adsb.fi/api/v2/lat/{lat}/lon/{lon}/dist/{nm}', 'aircraft')):
|
||||
try:
|
||||
r = requests.get(url, headers=H, timeout=20); r.raise_for_status(); j = r.json()
|
||||
ac = j.get('ac') or j.get('aircraft') or []
|
||||
now = j.get('now') or time.time() * 1000
|
||||
return url, now / 1000 if now > 1e11 else now, ac
|
||||
except Exception as e:
|
||||
print(slug, 'fail', url, e, file=sys.stderr)
|
||||
return None, time.time(), []
|
||||
def num(v):
|
||||
try: return float(v)
|
||||
except Exception: return None
|
||||
def conv(slug, a):
|
||||
lat, lon = num(a.get('lat')), num(a.get('lon'))
|
||||
if lat is None or lon is None:
|
||||
lp = a.get('lastPosition') or {}
|
||||
lat, lon = num(lp.get('lat')), num(lp.get('lon'))
|
||||
if lat is None: return None
|
||||
x, y = enu(slug, lat, lon)
|
||||
ab = a.get('alt_baro')
|
||||
if ab == 'ground': alt = 0.0
|
||||
else:
|
||||
v = num(ab)
|
||||
if v is None: v = num(a.get('alt_geom'))
|
||||
alt = round(v * 0.3048, 1) if v is not None else None
|
||||
trk = num(a.get('track')); trk = num(a.get('true_heading')) if trk is None else trk
|
||||
gs = num(a.get('gs')); gs = round(gs * 0.514444, 1) if gs is not None else None
|
||||
vr = num(a.get('baro_rate')); vr = num(a.get('geom_rate')) if vr is None else vr
|
||||
vr = round(vr * 0.00508, 2) if vr is not None else None
|
||||
return [x, y, alt, trk, gs, vr, (a.get('flight') or '').strip(), a.get('t') or '', a.get('category') or '']
|
||||
def main():
|
||||
polls = {s: [] for s in SCENES}
|
||||
for i in range(3):
|
||||
t0 = time.time()
|
||||
for s in SCENES:
|
||||
url, t, ac = fetch(s); polls[s].append((url, t, ac)); print(i, s, len(ac), url, flush=True)
|
||||
if i < 2: time.sleep(max(0, 20 - (time.time() - t0)))
|
||||
summary = {}
|
||||
for s in SCENES:
|
||||
latest, tracks, src = {}, {}, set()
|
||||
tlast = 0
|
||||
for url, t, ac in polls[s]:
|
||||
if url: src.add(url.split('/')[2])
|
||||
tlast = max(tlast, t)
|
||||
for a in ac:
|
||||
hx = a.get('hex'); row = conv(s, a)
|
||||
if not hx or row is None: continue
|
||||
if (num(a.get('seen_pos')) or 0) > 60: continue
|
||||
latest[hx] = row
|
||||
tr = tracks.setdefault(hx, [])
|
||||
p = [row[0], row[1], row[2]]
|
||||
if not tr or tr[-1][:2] != p[:2]: tr.append(p)
|
||||
heli = [h for h, r in latest.items() if r[8] == 'A7' or r[7] in HELI_TYPES]
|
||||
out = {'t': int(tlast), 'source': sorted(src), 'radius_nm': RAD[s], 'hex': list(latest.keys()),
|
||||
'a': list(latest.values()), 'tracks': {h: v for h, v in tracks.items() if len(v) > 1}}
|
||||
json.dump(out, open(os.path.join(ROOT, 'city', s, 'air.json'), 'w'), separators=(',', ':'))
|
||||
summary[s] = {'aircraft': len(latest), 'with_track': len(out['tracks']), 'heli': len(heli),
|
||||
'heli_list': [[latest[h][6], latest[h][7], latest[h][8], latest[h][2]] for h in heli]}
|
||||
print(json.dumps(summary, indent=1))
|
||||
if __name__ == '__main__': main()
|
||||
Reference in new issue
Block a user