Skip to content

data-poems/live-earth

Repository files navigation

Live Earth

MIT License Live Site

A real-time planetary monitoring dashboard on an interactive 3D globe. No backend required — every data layer fetches directly from live public APIs in the browser, refreshing on its own schedule.

Live: https://dr.eamer.dev/datavis/dashboards/live-earth/


What it shows

The globe renders 16 stacked data layers in real time:

Hazards

  • Seismic events — USGS M2.5+ earthquakes from the past 24 hours, refreshed every 5 minutes. Circle size scales with magnitude.
  • Volcanoes — USGS elevated-alert volcanoes, updated hourly.
  • Wildfires — NASA FIRMS VIIRS satellite fire detections worldwide, refreshed every 30 minutes.
  • Hurricanes — Active tropical cyclones from NOAA NHC, with storm intensity.
  • Weather alerts — Active NWS alerts for the US with polygon overlays, refreshed every 5 minutes.

Atmosphere

  • Aurora — NOAA OVATION aurora probability across ~65,000 lat/lon grid points, refreshed every 10 minutes. Points below 15% probability are culled.
  • Air quality — Open-Meteo AQI for major cities globally, refreshed every 30 minutes.
  • Space weather — Kp index (geomagnetic activity) and solar wind speed/density from NOAA SWPC, refreshed every 10 minutes.
  • Tides — Water levels at 10 US coastal NOAA CO-OPS stations (San Francisco, NYC Battery, Seattle, Honolulu, and more), updated every 6 minutes.

Traffic

  • Flights — Live aircraft positions from OpenSky Network via a server-side CORS proxy, refreshed every 60 seconds. Color-coded by altitude phase: cruising (blue), climb/descent (yellow), approach (orange). Filter by commercial, private, or helicopter.
  • ISS — International Space Station position updated every 10 seconds via wheretheiss.at, with an orbital trail of the last 50 positions.
  • Satellites — Starlink (50), GPS (30), and weather (20) satellites tracked using TLE data from tle.ivanstanojevic.me, propagated in real time with satellite.js. TLE data refreshes every 6 hours; positions update every frame.

Earth View

  • Day/night terminator — Calculated astronomically from current UTC time.
  • City lights — Natural Earth populated places rendered on the night side.
  • Major cities — 20 reference cities with labels.

A scrolling ticker at the bottom surfaces earthquake alerts, weather warnings, active fire counts, and space weather readings as they come in.


Running locally

Static HTML — no build step:

cd /path/to/live-earth
python3 -m http.server 8000
# Open http://localhost:8000/

Architecture

Everything lives in index.html (~2,600 lines): CSS custom properties for the dark terminal theme, D3.js orthographic projection on a Canvas 2D context, and async fetch loops for each data layer.

The globe uses D3's orthographic projection with drag rotation. All drawing goes through a single Canvas 2D context. d3.geoDistance() handles backface visibility culling so points behind the globe don't render. Layer order matters — ISS renders on top of everything; ocean fill renders first.

Data sources

All browser-direct (no proxy needed except where noted):

Layer Source Refresh
Earthquakes USGS GeoJSON feed 5 min
Volcanoes USGS HANS public API 1 hour
Wildfires NASA FIRMS VIIRS NRT 30 min
Hurricanes NOAA NHC (via CORS proxy) 30 min
Weather alerts NWS api.weather.gov 5 min
Aurora NOAA OVATION JSON 10 min
Air quality Open-Meteo AQI API 30 min
Kp index + solar wind NOAA SWPC 10 min
Tides NOAA CO-OPS tides API 6 min
Flights OpenSky Network (via proxy) 60 sec
ISS wheretheiss.at 10 sec
Satellites tle.ivanstanojevic.me + satellite.js TLE: 6h / pos: per-frame

Dependencies (CDN)

  • D3.js v7
  • TopoJSON v3
  • satellite.js v5
  • world-atlas 110m
  • Google Fonts: Share Tech Mono, Inter

Satellite propagation

TLE data comes from the ivanstanojevic.me API. satellite.js converts it to real-time lat/lon:

const satrec = satellite.twoline2satrec(sat.line1, sat.line2);
const now = new Date();
const gmst = satellite.gstime(now);
const posVel = satellite.propagate(satrec, now);
const geo = satellite.eciToGeodetic(posVel.position, gmst);
const lon = satellite.degreesLong(geo.longitude);
const lat = satellite.degreesLat(geo.latitude);

Adding a new live layer

  1. Confirm the API sends Access-Control-Allow-Origin: * (or route through the proxy)
  2. Add the endpoint to the API object
  3. Write an async fetchNewLayer() function and call it in init()
  4. Set a setInterval using the appropriate REFRESH constant
  5. Write a drawNewLayer() function and call it inside render()
  6. Add a toggle row to the Data Layers panel in the HTML

UI

  • Left panel: Data Layers — toggle switches for each layer, zoom controls, flight type filters
  • Right panel: Global Status — live counters (seismic events, active fires, aircraft tracked, ISS altitude, Kp index, solar wind speed, satellites, and more)
  • Bottom ticker: scrolling feed of current alerts and readings
  • Hover tooltips on earthquake, fire, flight, volcano, and weather alert markers
  • Mobile: panels collapse behind a hamburger toggle; ticker font scales down; stats grid reflows

Author

Luke Steuber — dr.eamer.dev@lukesteuber.com

License

MIT

About

Real-time earth dashboard: earthquakes, ISS, aurora, satellites, tides

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors