Neue Features: Satelliten-Orbits, Naturkatastrophen, Visual Modes
SATELLITEN (CelesTrak TLE): - Raumstationen (ISS), GPS, Galileo, Wetter, Erdbeobachtung, Starlink - Echtzeit-Positionsberechnung aus Kepler-Elementen (2s Update) - Orbitbahnen als leuchtende Linien (Stationen, GPS, Galileo) - Farbkodiert nach Gruppe (rot=Station, orange=GPS, blau=Galileo) NATURKATASTROPHEN (NASA EONET): - Waldbraende, Vulkane, Stuerme, Fluten, Erdrutsche, Eis - Farbige Punkte mit Emoji-Labels - Klick zeigt Details und Quellen VISUAL MODES: - STD: Standard-Ansicht - NVG: Nachtsicht (gruener Monochrom-Filter) - FLIR: Thermal-Ansicht (invertiert, Infrarot-Look) - CRT: Retro-Monitor (Scanlines, Vignette) 4 neue Dateien: satellites.js, disasters.js, visualmodes.js, data_satellites.py, data_disasters.py
Dieser Commit ist enthalten in:
69
src/data_satellites.py
Normale Datei
69
src/data_satellites.py
Normale Datei
@@ -0,0 +1,69 @@
|
||||
"""Satelliten-Daten: CelesTrak TLE Orbital Elements."""
|
||||
import logging
|
||||
import time
|
||||
|
||||
import httpx
|
||||
from fastapi import APIRouter
|
||||
|
||||
logger = logging.getLogger("globe.satellites")
|
||||
router = APIRouter()
|
||||
|
||||
_cache: dict = {"data": None, "ts": 0}
|
||||
|
||||
# Wichtigste Satellitengruppen (nicht alle 14.000)
|
||||
_GROUPS = [
|
||||
("stations", "Raumstationen (ISS etc.)"),
|
||||
("gps-ops", "GPS Navigationssatelliten"),
|
||||
("galileo", "Galileo Navigation"),
|
||||
("weather", "Wettersatelliten"),
|
||||
("resource", "Erdbeobachtung"),
|
||||
("starlink", "Starlink (Auswahl)"),
|
||||
("active", None), # Fallback: alle aktiven, wird gefiltert
|
||||
]
|
||||
|
||||
|
||||
@router.get("/satellites")
|
||||
async def get_satellites():
|
||||
now = time.time()
|
||||
if _cache["data"] and now - _cache["ts"] < 3600: # 1h Cache
|
||||
return _cache["data"]
|
||||
|
||||
all_sats = []
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=15) as client:
|
||||
for group, label in _GROUPS:
|
||||
if group == "active":
|
||||
continue # Zu gross, skip
|
||||
url = f"https://celestrak.org/NORAD/elements/gp.php?GROUP={group}&FORMAT=json"
|
||||
try:
|
||||
r = await client.get(url)
|
||||
if r.status_code == 200:
|
||||
sats = r.json()
|
||||
# Starlink: nur 200 nehmen (sind tausende)
|
||||
if group == "starlink":
|
||||
sats = sats[:200]
|
||||
for s in sats:
|
||||
all_sats.append({
|
||||
"name": s.get("OBJECT_NAME", "?"),
|
||||
"id": s.get("NORAD_CAT_ID"),
|
||||
"group": group,
|
||||
"epoch": s.get("EPOCH"),
|
||||
"meanMotion": s.get("MEAN_MOTION"),
|
||||
"eccentricity": s.get("ECCENTRICITY"),
|
||||
"inclination": s.get("INCLINATION"),
|
||||
"raOfAscNode": s.get("RA_OF_ASC_NODE"),
|
||||
"argOfPericenter": s.get("ARG_OF_PERICENTER"),
|
||||
"meanAnomaly": s.get("MEAN_ANOMALY"),
|
||||
"bstar": s.get("BSTAR"),
|
||||
"meanMotionDot": s.get("MEAN_MOTION_DOT"),
|
||||
})
|
||||
except Exception as e:
|
||||
logger.warning(f"CelesTrak {group}: {e}")
|
||||
except Exception as e:
|
||||
logger.warning(f"CelesTrak Fehler: {e}")
|
||||
return _cache["data"] or {"satellites": [], "total": 0}
|
||||
|
||||
_cache["data"] = {"satellites": all_sats, "total": len(all_sats)}
|
||||
_cache["ts"] = time.time()
|
||||
logger.info(f"Satellites: {len(all_sats)} geladen")
|
||||
return _cache["data"]
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren