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

@@ -716,6 +716,9 @@ const UI = {
if (emptyEl) emptyEl.style.display = 'none';
// Locations fuer GEOINT merken
this._lastLocations = locations;
// Statistik
const totalArticles = locations.reduce((s, l) => s + l.article_count, 0);
if (statsEl) statsEl.textContent = `${locations.length} Orte / ${totalArticles} Artikel`;
@@ -742,6 +745,10 @@ const UI = {
}).setView([51.1657, 10.4515], 5); // Deutschland-Zentrum
this._applyMapTiles();
// GEOINT-Modus wiederherstellen
if (typeof GEOINT !== 'undefined') GEOINT.restoreState(this._map);
this._mapCluster = L.markerClusterGroup({
maxClusterRadius: 40,
iconCreateFunction: function(cluster) {
@@ -853,6 +860,11 @@ const UI = {
this._mapLegendControl = legend;
}
// GEOINT: Timeline mit Artikel-Daten initialisieren
if (typeof GEOINT !== 'undefined' && typeof App !== 'undefined') {
GEOINT.initTimeline(App._currentArticles || []);
}
// Resize-Fix fuer gridstack (mehrere Versuche, da Container-Hoehe erst spaeter steht)
const self = this;
[100, 300, 800].forEach(delay => {
@@ -870,6 +882,8 @@ const UI = {
_applyMapTiles() {
if (!this._map) return;
// Im GEOINT-Modus Tiles nicht ueberschreiben
if (typeof GEOINT !== 'undefined' && GEOINT._active) return;
// Alte Tile-Layer entfernen
this._map.eachLayer(layer => {
if (layer instanceof L.TileLayer) this._map.removeLayer(layer);