MILITAERFLUGVERKEHR (adsb.lol /v2/mil): - ~254 Militaerflugzeuge weltweit in Echtzeit (rot) - Callsign-Labels bei Zoom (RCH=USAF, GAF=Luftwaffe etc.) - Klick zeigt: Callsign, Registration, Typ, Hoehe, Squawk - 20s Refresh SEEKABEL (TeleGeography): - Untersee-Glasfaserkabel als cyan-Linien auf dem Globus - ~500+ internationale Kabelverbindungen - Geopolitisch relevant (Sabotage, Abhoerung) INFRASTRUKTUR (OpenStreetMap Overpass): - 348 Kernkraftwerke weltweit (gelb mit Orange-Rand) - Militaerflughaefen (rot) - Labels bei Zoom (<500km) - 24h Cache (statische Daten) ISS TRACKER (Open-Notify API): - Echtzeit-Position der ISS (roter Punkt, 420km Hoehe) - 5s Refresh, prominentes Label - Klick zeigt Details Backend: data_military.py, data_infra.py (2 neue Dateien) Frontend: military.js, cables.js, infra.js, iss.js (4 neue Dateien)
35 Zeilen
1.4 KiB
JavaScript
35 Zeilen
1.4 KiB
JavaScript
const CablesLayer = {
|
|
_viewer: null, _dataSource: null, _count: 0,
|
|
|
|
start(viewer) {
|
|
if (this._dataSource) return;
|
|
this._viewer = viewer;
|
|
this._dataSource = new Cesium.GeoJsonDataSource('cables');
|
|
this._fetch();
|
|
},
|
|
|
|
stop() {
|
|
if (this._dataSource && this._viewer) { this._viewer.dataSources.remove(this._dataSource); this._dataSource = null; }
|
|
this._count = 0;
|
|
},
|
|
|
|
_fetch() {
|
|
var self = this;
|
|
var statusEl = document.getElementById('status-cables');
|
|
if (statusEl) { statusEl.textContent = 'Lade Seekabel...'; statusEl.classList.add('active'); }
|
|
fetch('/api/submarine-cables')
|
|
.then(function(r) { return r.json(); })
|
|
.then(function(data) {
|
|
self._count = (data.features || []).length;
|
|
return self._dataSource.load(data, {
|
|
stroke: Cesium.Color.fromCssColorString('#00ccff').withAlpha(0.4),
|
|
strokeWidth: 1.5,
|
|
clampToGround: true,
|
|
});
|
|
})
|
|
.then(function() { self._viewer.dataSources.add(self._dataSource); if (statusEl) statusEl.textContent = self._count + ' Kabel'; })
|
|
.catch(function(e) { console.warn('Cables:', e); if (statusEl) statusEl.textContent = 'Fehler'; })
|
|
.finally(function() { setTimeout(function() { if (statusEl) statusEl.classList.remove('active'); }, 5000); });
|
|
},
|
|
};
|