mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VVYRAqiQj9Y1V9ZfG1RcDH
687 lines
20 KiB
JavaScript
687 lines
20 KiB
JavaScript
/**
|
||
* Offline stub situations, shaped like mobile/globe/API.md (band, archetype,
|
||
* telemetry, headline, media, series [{t,v}]). Everything here is labelled
|
||
* simulated; Eye cards point at the dev server's real public-camera frames
|
||
* (`/api/cctv/frame/:id`) and fall back to imagery when that is unreachable.
|
||
*/
|
||
|
||
import { esriThumb } from './dom.js';
|
||
|
||
export const SIM = 'Simulated · offline stub engine';
|
||
|
||
/** Public traffic cameras the dev server proxies (ids from /api/cctv/sources). */
|
||
export const STUB_CAMS = [
|
||
{
|
||
id: '354',
|
||
title: '5th St / Congress Ave',
|
||
city: 'Austin',
|
||
provider: 'Austin Transportation & Public Works',
|
||
lat: 30.267119,
|
||
lon: -97.743172,
|
||
headingDeg: 67.5,
|
||
},
|
||
{
|
||
id: 'tfl-00001.06502',
|
||
title: 'Trafalgar Square',
|
||
city: 'London',
|
||
provider: 'Transport for London',
|
||
lat: 51.5074,
|
||
lon: -0.12765,
|
||
headingDeg: 135,
|
||
},
|
||
{
|
||
id: 'wsdot-9520',
|
||
title: 'I-5 at 5th Ave / Columbia',
|
||
city: 'Seattle',
|
||
provider: 'WSDOT',
|
||
lat: 47.605166,
|
||
lon: -122.330316,
|
||
headingDeg: 202.5,
|
||
},
|
||
{
|
||
id: 'ca-d4-tv301',
|
||
title: 'US-101 at Octavia St',
|
||
city: 'San Francisco',
|
||
provider: 'Caltrans',
|
||
lat: 37.77146,
|
||
lon: -122.42323,
|
||
headingDeg: 180,
|
||
},
|
||
{
|
||
id: 'no-vegvesen-3000051_1',
|
||
title: 'F862 Sentrumstangenten',
|
||
city: 'Tromsø',
|
||
provider: 'Statens vegvesen',
|
||
lat: 69.64469,
|
||
lon: 18.947695,
|
||
headingDeg: 270,
|
||
},
|
||
{
|
||
id: 'ca-d11-x1248',
|
||
title: 'I-5 at First Avenue',
|
||
city: 'San Diego',
|
||
provider: 'Caltrans',
|
||
lat: 32.72285,
|
||
lon: -117.16356,
|
||
headingDeg: 180,
|
||
},
|
||
{
|
||
id: 'fi-c1455101',
|
||
title: 'vt4 Rovaniemi Revontuli',
|
||
city: 'Rovaniemi',
|
||
provider: 'Fintraffic',
|
||
lat: 66.503858,
|
||
lon: 25.725196,
|
||
headingDeg: 202.5,
|
||
},
|
||
];
|
||
|
||
export const camFrameUrl = (id) =>
|
||
`/api/cctv/frame/${encodeURIComponent(id)}?ts=${Math.floor(Date.now() / 10000)}`;
|
||
|
||
function series(values, stepMin, now) {
|
||
return values.map((v, i) => ({
|
||
t: now - (values.length - 1 - i) * stepMin * 60e3,
|
||
v,
|
||
}));
|
||
}
|
||
|
||
export function buildStubSituations(now) {
|
||
const min = 60e3;
|
||
const S = (o) => ({
|
||
live: true,
|
||
source: SIM,
|
||
section: 'now',
|
||
severity: 0,
|
||
updatedAt: now - (o.age ?? 2) * min,
|
||
time: o.time ?? { start: now - 6 * 3600e3, end: now + 24 * 3600e3 },
|
||
camera: o.camera ?? {
|
||
lon: o.lon,
|
||
lat: o.lat,
|
||
height: o.height ?? 400e3,
|
||
heading: 0,
|
||
pitch: -90,
|
||
},
|
||
thumbnail: esriThumb(o.lon, o.lat, o.span ?? 1, 480, o.th ?? 600),
|
||
...o,
|
||
});
|
||
const eye = (cam, o) =>
|
||
S({
|
||
kind: 'camera',
|
||
family: 'eyes',
|
||
band: 'ground',
|
||
archetype: 'eye',
|
||
lon: cam.lon,
|
||
lat: cam.lat,
|
||
span: 0.01,
|
||
height: 1500,
|
||
camera: {
|
||
lon: cam.lon,
|
||
lat: cam.lat,
|
||
height: 900,
|
||
heading: cam.headingDeg,
|
||
pitch: -30,
|
||
},
|
||
layers: ['eyes.public-cctv', 'ground.traffic-flow'],
|
||
media: {
|
||
kind: 'image',
|
||
url: camFrameUrl(cam.id),
|
||
refreshMs: 15000,
|
||
cameraId: cam.id,
|
||
headingDeg: cam.headingDeg,
|
||
provider: cam.provider,
|
||
city: cam.city,
|
||
},
|
||
telemetry: `GROUND · CAM ${cam.id.slice(-6).toUpperCase()} · ${cam.title.toUpperCase()}`,
|
||
source: `${cam.provider} public camera`,
|
||
...o,
|
||
});
|
||
const C = Object.fromEntries(STUB_CAMS.map((c) => [c.id, c]));
|
||
return [
|
||
S({
|
||
id: 'cyclone-wpac',
|
||
kind: 'cyclone',
|
||
family: 'hazards',
|
||
band: 'orbit',
|
||
archetype: 'sensor',
|
||
severity: 5,
|
||
title: 'Typhoon tracking toward Luzon',
|
||
subtitle: 'Category 4 · eyewall replacement under way',
|
||
place: 'Philippine Sea',
|
||
lon: 126.5,
|
||
lat: 15.4,
|
||
span: 9,
|
||
th: 640,
|
||
height: 2200e3,
|
||
layers: ['hazards.tropical-cyclones', 'weather.clouds', 'weather.wind'],
|
||
metrics: [
|
||
{ label: 'Wind', value: 185, unit: 'km/h' },
|
||
{ label: 'Pressure', value: 935, unit: 'hPa' },
|
||
{ label: 'Moving', value: 'WNW 18', unit: 'km/h' },
|
||
],
|
||
headline: { value: 185, unit: 'km/h', label: 'sustained wind' },
|
||
telemetry: 'ORBIT · GOES IR · 185 KM/H · 935 HPA · WNW 18',
|
||
series: series(
|
||
[120, 130, 140, 150, 165, 175, 185, 185, 180, 185],
|
||
360,
|
||
now,
|
||
),
|
||
seriesLabel: 'sustained wind, km/h',
|
||
age: 2,
|
||
time: { start: now - 72 * 3600e3, end: now + 120 * 3600e3 },
|
||
events: [{ at: now + 30 * 3600e3, label: 'Landfall (fcst)' }],
|
||
}),
|
||
eye(C['354'], {
|
||
id: 'eye-austin',
|
||
title: 'Saturday night on Congress Ave',
|
||
subtitle: 'Downtown crowds after the game',
|
||
place: 'Downtown Austin, Texas',
|
||
severity: 2,
|
||
age: 0,
|
||
}),
|
||
S({
|
||
id: 'squawk-7700',
|
||
kind: 'squawk',
|
||
family: 'sky',
|
||
band: 'sky',
|
||
archetype: 'track',
|
||
severity: 4,
|
||
title: 'Squawk 7700 · descending toward Halifax',
|
||
subtitle: 'Simulated emergency track, diverting',
|
||
place: 'Over Nova Scotia',
|
||
lon: -62.4,
|
||
lat: 45.1,
|
||
span: 2.4,
|
||
th: 520,
|
||
height: 350e3,
|
||
layers: ['sky.emergency-squawks', 'sky.commercial-flights'],
|
||
metrics: [
|
||
{ label: 'Altitude', value: 'FL100', unit: '' },
|
||
{ label: 'Speed', value: 312, unit: 'kt' },
|
||
{ label: 'Squawk', value: '7700', unit: '' },
|
||
],
|
||
headline: { value: '7700', unit: '', label: 'general emergency' },
|
||
telemetry: 'SKY · FL100 ↓ · 312 KT · SQ 7700',
|
||
track: { headingDeg: 310 },
|
||
age: 1,
|
||
}),
|
||
S({
|
||
id: 'lightning-gulf',
|
||
kind: 'lightning',
|
||
family: 'weather',
|
||
band: 'sky',
|
||
archetype: 'number',
|
||
severity: 3,
|
||
title: 'Lightning over the Gulf of Mexico',
|
||
subtitle: 'A squall line pushing toward the Louisiana coast',
|
||
place: 'Gulf of Mexico',
|
||
lon: -90.2,
|
||
lat: 27.4,
|
||
span: 5,
|
||
th: 460,
|
||
height: 900e3,
|
||
layers: ['weather.lightning', 'weather.radar'],
|
||
metrics: [
|
||
{ label: 'Strikes / h', value: 4812, unit: '' },
|
||
{ label: 'Peak density', value: 38, unit: '/km²' },
|
||
],
|
||
headline: { value: 4812, unit: '', label: 'strikes in the last hour' },
|
||
telemetry: 'SKY · GLM · 4,812 STR/H · 27.4N 90.2W',
|
||
series: series([620, 900, 1400, 2100, 2900, 3600, 4100, 4812], 15, now),
|
||
seriesLabel: 'strikes / 15 min',
|
||
age: 1,
|
||
}),
|
||
S({
|
||
id: 'quake-24h',
|
||
kind: 'earthquake',
|
||
family: 'hazards',
|
||
band: 'ground',
|
||
archetype: 'sensor',
|
||
severity: 4,
|
||
title: 'M6.4 · largest quake in 24 h',
|
||
subtitle: 'Shallow thrust event, aftershocks continuing',
|
||
place: 'Off Hokkaido, Japan',
|
||
lon: 144.2,
|
||
lat: 42.1,
|
||
span: 3.5,
|
||
th: 480,
|
||
height: 900e3,
|
||
layers: ['hazards.earthquakes'],
|
||
metrics: [
|
||
{ label: 'Magnitude', value: 6.4, unit: 'Mw' },
|
||
{ label: 'Depth', value: 38, unit: 'km' },
|
||
{ label: 'Aftershocks', value: 27, unit: '' },
|
||
],
|
||
headline: { value: 6.4, unit: 'Mw', label: 'magnitude' },
|
||
telemetry: 'GROUND · USGS · M6.4 · 38 KM DEEP',
|
||
age: 11,
|
||
events: [{ at: now - 14 * 3600e3, label: 'M6.4' }],
|
||
}),
|
||
S({
|
||
id: 'iss-pass',
|
||
kind: 'iss',
|
||
family: 'orbit',
|
||
band: 'orbit',
|
||
archetype: 'track',
|
||
severity: 2,
|
||
title: 'ISS crosses your sky at 21:42',
|
||
subtitle: 'Bright pass · max elevation 71°',
|
||
place: 'Low Earth orbit',
|
||
lon: -40,
|
||
lat: 30,
|
||
span: 30,
|
||
th: 520,
|
||
height: 9000e3,
|
||
layers: ['orbit.iss-crewed', 'orbit.ground-tracks'],
|
||
metrics: [
|
||
{ label: 'Altitude', value: 418, unit: 'km' },
|
||
{ label: 'Speed', value: 7.66, unit: 'km/s' },
|
||
{ label: 'Next pass', value: '21:42', unit: '' },
|
||
],
|
||
headline: { value: '21:42', unit: '', label: 'next pass · 71° max' },
|
||
telemetry: 'ORBIT · 418 KM · 7.66 KM/S · PASS 21:42',
|
||
track: { headingDeg: 52 },
|
||
age: 1,
|
||
}),
|
||
S({
|
||
id: 'fires-sierra',
|
||
kind: 'fires',
|
||
family: 'hazards',
|
||
band: 'ground',
|
||
archetype: 'sensor',
|
||
severity: 4,
|
||
title: 'Fire cluster in the Sierra foothills',
|
||
subtitle: 'Hotspots doubling since dawn, smoke drifting east',
|
||
place: 'Nevada County, California',
|
||
lon: -120.9,
|
||
lat: 39.05,
|
||
span: 1.6,
|
||
th: 560,
|
||
height: 260e3,
|
||
layers: [
|
||
'hazards.active-fires',
|
||
'hazards.fire-perimeters',
|
||
'weather.wind',
|
||
],
|
||
metrics: [
|
||
{ label: 'Hotspots', value: 214, unit: '' },
|
||
{ label: 'FRP', value: 1840, unit: 'MW' },
|
||
{ label: 'Wind', value: 32, unit: 'km/h' },
|
||
],
|
||
headline: { value: 214, unit: '', label: 'hotspots' },
|
||
telemetry: 'GROUND · FIRMS VIIRS · 214 HOTSPOTS · WIND W 32',
|
||
series: series([12, 18, 30, 44, 61, 88, 120, 160, 190, 214], 60, now),
|
||
seriesLabel: 'hotspots / h',
|
||
age: 4,
|
||
}),
|
||
S({
|
||
id: 'gnss-baltic',
|
||
kind: 'gnss',
|
||
family: 'infra',
|
||
band: 'sky',
|
||
archetype: 'number',
|
||
severity: 3,
|
||
title: 'GNSS jamming over the Baltic',
|
||
subtitle: 'Aircraft reporting degraded navigation integrity',
|
||
place: 'Baltic Sea',
|
||
lon: 21.0,
|
||
lat: 56.5,
|
||
span: 6,
|
||
th: 480,
|
||
height: 1500e3,
|
||
layers: ['infra.gnss-interference', 'sky.commercial-flights'],
|
||
metrics: [
|
||
{ label: 'Affected', value: 312, unit: 'aircraft' },
|
||
{ label: 'Area', value: 84, unit: 'k km²' },
|
||
],
|
||
headline: { value: 312, unit: '', label: 'aircraft affected' },
|
||
telemetry: 'SKY · ADS-B NIC<7 · 312 AC · 84K KM²',
|
||
series: series([120, 180, 240, 260, 300, 312], 60, now),
|
||
seriesLabel: 'aircraft with NIC < 7',
|
||
age: 9,
|
||
}),
|
||
eye(C['tfl-00001.06502'], {
|
||
id: 'eye-trafalgar',
|
||
title: 'Trafalgar Square, live',
|
||
subtitle: 'Looking south-east down Whitehall',
|
||
place: 'Westminster, London',
|
||
severity: 1,
|
||
age: 0,
|
||
}),
|
||
S({
|
||
id: 'circling-midtown',
|
||
kind: 'circling',
|
||
family: 'sky',
|
||
band: 'sky',
|
||
archetype: 'track',
|
||
severity: 4,
|
||
live: false,
|
||
title: '3 helicopters circled Midtown Manhattan',
|
||
subtitle: 'Detected from orbiting tracks · replay the Moment',
|
||
place: 'Empire State Building, New York',
|
||
lon: -73.98566,
|
||
lat: 40.74844,
|
||
span: 0.05,
|
||
th: 520,
|
||
height: 6000,
|
||
layers: ['sky.helicopters', 'sky.commercial-flights'],
|
||
metrics: [
|
||
{ label: 'Rotorcraft', value: 3, unit: '' },
|
||
{ label: 'Orbit radius', value: '450–650', unit: 'm' },
|
||
{ label: 'Altitude', value: '1,050–1,450', unit: 'ft' },
|
||
],
|
||
headline: { value: 3, unit: 'helis', label: 'circling one point' },
|
||
telemetry: 'SKY · 3 ROTORCRAFT · R 450–650 M · 1,050–1,450 FT',
|
||
momentId: 'empire-state',
|
||
illustrative: true,
|
||
track: { headingDeg: 0, circuit: true },
|
||
age: 76,
|
||
}),
|
||
S({
|
||
id: 'novosel',
|
||
kind: 'helicopters',
|
||
family: 'sky',
|
||
band: 'sky',
|
||
archetype: 'track',
|
||
title: 'Rotor school: 14th circuit of the day',
|
||
subtitle: 'A training helicopter flying the pattern',
|
||
place: 'Fort Novosel, Alabama',
|
||
lon: -85.72,
|
||
lat: 31.36,
|
||
span: 0.22,
|
||
th: 420,
|
||
height: 40e3,
|
||
layers: ['sky.helicopters'],
|
||
metrics: [
|
||
{ label: 'Airborne', value: 23, unit: 'rotorcraft' },
|
||
{ label: 'Pattern alt', value: 700, unit: 'ft' },
|
||
],
|
||
headline: { value: 14, unit: 'th', label: 'circuit today' },
|
||
telemetry: 'SKY · 700 FT · 88 KT · CIRCUIT 14',
|
||
track: { headingDeg: 140, circuit: true },
|
||
age: 3,
|
||
alwaysOn: true,
|
||
}),
|
||
S({
|
||
id: 'bhote-koshi-2026',
|
||
kind: 'reconstruction',
|
||
family: 'hazards',
|
||
band: 'inside',
|
||
archetype: 'sensor',
|
||
title: 'Bhote Koshi outburst flood',
|
||
subtitle: '16 sourced observations · 3 open hypotheses',
|
||
place: 'Rasuwa, Nepal ↔ Gyirong, Tibet',
|
||
section: 'reconstructions',
|
||
lon: 85.33,
|
||
lat: 28.15,
|
||
span: 0.3,
|
||
th: 640,
|
||
height: 30e3,
|
||
camera: {
|
||
lon: 85.3548,
|
||
lat: 28.207,
|
||
height: 14e3,
|
||
heading: 344,
|
||
pitch: -39,
|
||
},
|
||
layers: [
|
||
'hazards.floods',
|
||
'infra.recent-imagery',
|
||
'eyes.signed-captures',
|
||
],
|
||
metrics: [
|
||
{ label: 'Observations', value: 16, unit: '' },
|
||
{ label: 'Corridor', value: 145, unit: 'pts' },
|
||
{ label: 'Hypotheses', value: 3, unit: '' },
|
||
],
|
||
telemetry: 'INSIDE · 4D · 16 OBS · 22 KM CORRIDOR',
|
||
live: false,
|
||
age: 60 * 24 * 7,
|
||
source: 'GeoPera reconstruction · Vantor Open Data (CC BY-NC 4.0)',
|
||
time: { start: Date.UTC(2026, 7, 26, 0), end: Date.UTC(2026, 7, 27, 12) },
|
||
thread: 'bhote-koshi-2026',
|
||
thumbnail: '/events/bhote-koshi-2026/post.webp',
|
||
}),
|
||
S({
|
||
id: 'rain-houston',
|
||
kind: 'rain',
|
||
family: 'weather',
|
||
band: 'sky',
|
||
archetype: 'sensor',
|
||
severity: 3,
|
||
title: 'Heavy rain cell over Houston',
|
||
subtitle: '60 dBZ core over the Ship Channel, moving east',
|
||
place: 'Houston, Texas',
|
||
lon: -95.25,
|
||
lat: 29.74,
|
||
span: 0.9,
|
||
th: 540,
|
||
height: 120e3,
|
||
layers: ['weather.radar', 'weather.lightning'],
|
||
metrics: [
|
||
{ label: 'Peak', value: 60, unit: 'dBZ' },
|
||
{ label: 'Rate', value: 76, unit: 'mm/h' },
|
||
],
|
||
headline: { value: 76, unit: 'mm/h', label: 'rain rate' },
|
||
telemetry: 'SKY · MRMS · 60 DBZ · 76 MM/H · E 22 KM/H',
|
||
age: 2,
|
||
}),
|
||
S({
|
||
id: 'starbase',
|
||
kind: 'launch',
|
||
family: 'orbit',
|
||
band: 'orbit',
|
||
archetype: 'track',
|
||
title: 'Launch window opens at Starbase',
|
||
subtitle: 'Trajectory east over the Gulf',
|
||
place: 'Boca Chica, Texas',
|
||
lon: -97.157,
|
||
lat: 25.997,
|
||
span: 0.06,
|
||
th: 380,
|
||
height: 12e3,
|
||
layers: ['orbit.launches', 'orbit.ground-tracks'],
|
||
metrics: [
|
||
{ label: 'T−', value: '06:12:00', unit: '' },
|
||
{ label: 'Weather go', value: 80, unit: '%' },
|
||
],
|
||
headline: { value: 'T−06:12', unit: '', label: 'to window' },
|
||
telemetry: 'ORBIT · PAD B · AZ 097° · T−06:12:00',
|
||
track: { headingDeg: 97, launch: true },
|
||
age: 6,
|
||
events: [{ at: now + 6.2 * 3600e3, label: 'T-0' }],
|
||
}),
|
||
eye(C['wsdot-9520'], {
|
||
id: 'eye-seattle',
|
||
title: 'I-5 through downtown Seattle',
|
||
subtitle: 'Southbound into the convention center tunnel',
|
||
place: 'Seattle, Washington',
|
||
age: 0,
|
||
}),
|
||
S({
|
||
id: 'suez-queue',
|
||
kind: 'queue',
|
||
family: 'sea',
|
||
band: 'ground',
|
||
archetype: 'number',
|
||
title: '41 ships waiting at Suez',
|
||
subtitle: 'Southbound convoy holding in the anchorage',
|
||
place: 'Gulf of Suez, Egypt',
|
||
lon: 32.55,
|
||
lat: 29.88,
|
||
span: 0.35,
|
||
th: 560,
|
||
height: 60e3,
|
||
layers: ['sea.ais-vessels', 'sea.tankers-cargo'],
|
||
metrics: [
|
||
{ label: 'Waiting', value: 41, unit: 'vessels' },
|
||
{ label: 'Median wait', value: 19, unit: 'h' },
|
||
],
|
||
headline: { value: 41, unit: '', label: 'vessels at anchor' },
|
||
telemetry: 'GROUND · AIS · 41 AT ANCHOR · WAIT 19 H',
|
||
series: series([28, 30, 33, 35, 39, 41], 120, now),
|
||
seriesLabel: 'vessels at anchor',
|
||
age: 5,
|
||
}),
|
||
S({
|
||
id: 'north-sea-mil',
|
||
kind: 'military',
|
||
family: 'sky',
|
||
band: 'sky',
|
||
archetype: 'sensor',
|
||
title: 'Tanker orbits over the North Sea',
|
||
subtitle: 'Two refuelling tracks and a fighter CAP',
|
||
place: 'North Sea',
|
||
lon: 3.5,
|
||
lat: 55.5,
|
||
span: 5,
|
||
th: 520,
|
||
height: 900e3,
|
||
layers: ['sky.military-aircraft'],
|
||
metrics: [
|
||
{ label: 'Aircraft', value: 14, unit: '' },
|
||
{ label: 'Tankers', value: 3, unit: '' },
|
||
],
|
||
telemetry: 'SKY · FL260 · 3 TANKERS · 14 MIL',
|
||
age: 7,
|
||
}),
|
||
eye(C['no-vegvesen-3000051_1'], {
|
||
id: 'eye-tromso',
|
||
kind: 'camera',
|
||
title: 'Tromsø under a Kp 6 sky',
|
||
subtitle: 'Road camera on Sentrumstangenten, aurora nowcast high',
|
||
place: 'Tromsø, Norway',
|
||
age: 0,
|
||
}),
|
||
S({
|
||
id: 'jet-stream',
|
||
kind: 'jet',
|
||
family: 'weather',
|
||
band: 'sky',
|
||
archetype: 'sensor',
|
||
title: 'Jet stream at 210 kt over the Atlantic',
|
||
subtitle: 'Eastbound flights riding it, westbound avoiding it',
|
||
place: 'North Atlantic',
|
||
lon: -38,
|
||
lat: 49,
|
||
span: 22,
|
||
th: 460,
|
||
height: 4500e3,
|
||
layers: ['weather.wind', 'sky.commercial-flights'],
|
||
metrics: [{ label: 'Core', value: 210, unit: 'kt' }],
|
||
headline: { value: 210, unit: 'kt', label: 'jet core at FL340' },
|
||
telemetry: 'SKY · GFS 250 HPA · 210 KT · FL340',
|
||
age: 20,
|
||
}),
|
||
S({
|
||
id: 'atl-rush',
|
||
kind: 'airport',
|
||
family: 'sky',
|
||
band: 'sky',
|
||
archetype: 'number',
|
||
title: 'Busiest airport right now',
|
||
subtitle: 'Hartsfield–Jackson arrival bank',
|
||
place: 'Atlanta, Georgia',
|
||
lon: -84.428,
|
||
lat: 33.6407,
|
||
span: 0.09,
|
||
th: 600,
|
||
height: 18e3,
|
||
layers: [
|
||
'sky.commercial-flights',
|
||
'sky.holding-patterns',
|
||
'sky.airport-boards',
|
||
],
|
||
metrics: [
|
||
{ label: 'Movements', value: 182, unit: '/h' },
|
||
{ label: 'Holding', value: 6, unit: '' },
|
||
],
|
||
headline: { value: 182, unit: '/h', label: 'movements' },
|
||
telemetry: 'SKY · KATL · 182 MVT/H · 6 HOLDING',
|
||
series: series([120, 140, 166, 170, 182, 176, 181, 182], 30, now),
|
||
seriesLabel: 'movements / h',
|
||
age: 1,
|
||
alwaysOn: true,
|
||
}),
|
||
eye(C['ca-d4-tv301'], {
|
||
id: 'eye-sf',
|
||
title: 'US-101 at Octavia, San Francisco',
|
||
subtitle: 'Central Freeway merging into Mission',
|
||
place: 'San Francisco, California',
|
||
age: 0,
|
||
alwaysOn: true,
|
||
}),
|
||
S({
|
||
id: 'tokyo-rush',
|
||
kind: 'transit',
|
||
family: 'ground',
|
||
band: 'ground',
|
||
archetype: 'sensor',
|
||
title: 'Rush hour on the Yamanote line',
|
||
subtitle: 'Headways at 2 min 30 s through Shinjuku',
|
||
place: 'Shinjuku, Tokyo',
|
||
lon: 139.7,
|
||
lat: 35.69,
|
||
span: 0.05,
|
||
th: 600,
|
||
height: 9e3,
|
||
layers: ['ground.transit-vehicles', 'ground.rail'],
|
||
metrics: [
|
||
{ label: 'Trains moving', value: 1840, unit: '' },
|
||
{ label: 'On time', value: 98.6, unit: '%' },
|
||
],
|
||
telemetry: 'GROUND · GTFS-RT · 1,840 TRAINS · 98.6% OT',
|
||
age: 2,
|
||
alwaysOn: true,
|
||
}),
|
||
S({
|
||
id: 'aurora',
|
||
kind: 'aurora',
|
||
family: 'weather',
|
||
band: 'orbit',
|
||
archetype: 'sensor',
|
||
title: 'Aurora oval reaching 60°N tonight',
|
||
subtitle: 'Kp 6 storm, clear skies after 22:00',
|
||
place: 'Northern Scandinavia',
|
||
lon: 18.95,
|
||
lat: 69.65,
|
||
span: 8,
|
||
th: 600,
|
||
height: 1200e3,
|
||
layers: ['weather.clouds'],
|
||
metrics: [
|
||
{ label: 'Kp', value: 6, unit: '' },
|
||
{ label: 'Cloud', value: 20, unit: '%' },
|
||
],
|
||
headline: { value: 'Kp 6', unit: '', label: 'geomagnetic storm' },
|
||
telemetry: 'ORBIT · OVATION · KP 6 · OVAL 60N',
|
||
series: series([2, 3, 3, 4, 5, 6, 6], 180, now),
|
||
seriesLabel: 'Kp index',
|
||
age: 15,
|
||
}),
|
||
S({
|
||
id: 'singapore',
|
||
kind: 'strait',
|
||
family: 'sea',
|
||
band: 'ground',
|
||
archetype: 'sensor',
|
||
title: 'Singapore Strait at capacity',
|
||
subtitle: 'Eastbound lane full, 318 ships at anchor',
|
||
place: 'Singapore Strait',
|
||
lon: 103.85,
|
||
lat: 1.22,
|
||
span: 0.4,
|
||
th: 420,
|
||
height: 70e3,
|
||
layers: ['sea.ais-vessels'],
|
||
metrics: [
|
||
{ label: 'Transits', value: 22, unit: '/h' },
|
||
{ label: 'At anchor', value: 318, unit: '' },
|
||
],
|
||
telemetry: 'GROUND · AIS · 22 TRANSITS/H · 318 ANCHORED',
|
||
age: 3,
|
||
alwaysOn: true,
|
||
}),
|
||
];
|
||
}
|