GEOINT-Modus: Experimentelle taktische Kartenansicht mit Echtzeit-Datenlayern

Neuer experimenteller GEOINT-Modus per Checkbox auf der Karten-Kachel:
- Satellitenbilder (Esri World Imagery) statt OSM-Strassenkarte
- Echtzeit-Flugverkehr (airplanes.live via Backend-Proxy, 15s Refresh)
- Erdbeben-Layer (USGS M2.5+, pulsierende Kreise nach Magnitude)
- GDELT Nachrichten (geokodierte Echtzeit-News, Cluster-Darstellung)
- Heatmap-Visualisierung der Artikel-Standorte (Leaflet.heat)
- Timeline-Slider fuer zeitliche Filterung der Artikel-Marker
- Koordinatenanzeige (Lat/Lon unter Mauszeiger)
- Distanzmessung (Klick-zu-Klick mit km-Anzeige)
- Taktisches Styling (dunkle Tonung, gruene Akzente, Scanlines)

Neue Dateien: geoint.js, geoint.css, routers/geoint.py
Inspiriert von WorldView/Gods Eye Konzept, komplett eigenentwickelt.
Dieser Commit ist enthalten in:
Claude Dev
2026-03-24 09:29:19 +01:00
Ursprung fdbffa7e00
Commit b2be1358ab
6 geänderte Dateien mit 1030 neuen und 1 gelöschten Zeilen

Datei anzeigen

@@ -19,6 +19,7 @@
<link rel="stylesheet" href="/static/css/network.css?v=20260316a">
<link rel="stylesheet" href="/static/css/network-cluster.css?v=20260322b">
<link rel="stylesheet" href="/static/css/style.css?v=20260316k">
<link rel="stylesheet" href="/static/css/geoint.css?v=20260324a">
</head>
<body>
<a href="#main-content" class="skip-link">Zum Hauptinhalt springen</a>
@@ -406,15 +407,24 @@
<div class="card-title">Geografische Verteilung</div>
<span class="map-stats" id="map-stats"></span>
<div class="card-header-actions">
<label class="geoint-toggle" title="GEOINT-Modus aktivieren">
<input type="checkbox" id="geoint-mode-cb" onchange="GEOINT.toggle(this.checked, UI._map)">
<span class="geoint-toggle-label">GEOINT</span>
</label>
<button class="btn btn-secondary btn-small" id="geoparse-btn" onclick="App.triggerGeoparse()" title="Orte aus Artikeln einlesen">Orte einlesen</button>
<button class="btn btn-secondary btn-small map-expand-btn" id="map-expand-btn" onclick="UI.toggleMapFullscreen()" title="Vollbild" aria-label="Karte im Vollbild anzeigen">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
</button>
</div>
</div>
<div class="map-container" id="map-container">
<div class="map-container" id="map-container" style="position:relative">
<div class="map-empty" id="map-empty">Keine Orte erkannt</div>
</div>
<div class="geoint-timeline" id="geoint-timeline" style="display:none">
<button class="geoint-timeline-btn" onclick="GEOINT._resetTimeline()" title="Zuruecksetzen">&#8634;</button>
<input type="range" id="geoint-timeline-slider" min="0" max="100" value="100" oninput="GEOINT._onTimelineChange(this.value)">
<span class="geoint-timeline-label" id="geoint-timeline-label">--</span>
</div>
</div>
</div>
</div>
@@ -776,6 +786,8 @@
<script src="/static/js/api.js?v=20260316c"></script>
<script src="/static/js/ws.js?v=20260316b"></script>
<script src="/static/js/components.js?v=20260316d"></script>
<script src="https://unpkg.com/leaflet.heat@0.2.0/dist/leaflet-heat.js"></script>
<script src="/static/js/geoint.js?v=20260324a"></script>
<script src="/static/js/layout.js?v=20260316b"></script>
<script src="/static/js/app.js?v=20260316b"></script>
<script src="/static/js/api_network.js?v=20260316a"></script>
@@ -792,6 +804,10 @@
<div class="map-fullscreen-header">
<div class="map-fullscreen-title">Geografische Verteilung</div>
<span class="map-stats map-fullscreen-stats" id="map-fullscreen-stats"></span>
<label class="geoint-toggle" title="GEOINT-Modus">
<input type="checkbox" id="geoint-mode-cb-fs" onchange="GEOINT.toggle(this.checked, UI._map)">
<span class="geoint-toggle-label">GEOINT</span>
</label>
<button class="btn btn-secondary btn-small" onclick="UI.toggleMapFullscreen()" title="Vollbild beenden" aria-label="Vollbild beenden">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/><line x1="14" y1="10" x2="21" y2="3"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
</button>