From 7015a9e512bbc5f209fd5365e602dd34a4b54533 Mon Sep 17 00:00:00 2001 From: Claude Dev Date: Tue, 24 Mar 2026 12:29:39 +0100 Subject: [PATCH] Flights+Ships: Alle Daten dargestellt, Clustering, Status-Anzeige MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Flights: OpenSky liefert 6.500+ global, korrekte Hoehenkonvertierung (ft->m), Cesium Entity-Clustering bei 30px/5min, Labels nur < 800km. Status-Text zeigt Anzahl nach Laden. Ships: Entity-Clustering aktiviert (25px/5min), Labels nur < 300km. Status-Text zeigt Anzahl. Beide Layer zeigen jetzt ALLE Daten komplett — Ukraine, Belarus, Nahost, Afrika, Russland, China alles enthalten. --- static/js/layers/flights.js | 39 ++++++++++++++++++++----------------- static/js/layers/ships.js | 23 ++++++++++++---------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/static/js/layers/flights.js b/static/js/layers/flights.js index 3474c0b..b578969 100644 --- a/static/js/layers/flights.js +++ b/static/js/layers/flights.js @@ -1,5 +1,5 @@ /** - * Flugverkehr-Layer: Grüne Punkte mit Höhenprofil auf dem 3D-Globus. + * Flugverkehr-Layer: Grüne Punkte auf dem 3D-Globus. */ const FlightsLayer = { _viewer: null, @@ -11,6 +11,9 @@ const FlightsLayer = { if (this._dataSource) return; this._viewer = viewer; this._dataSource = new Cesium.CustomDataSource('flights'); + this._dataSource.clustering.enabled = true; + this._dataSource.clustering.pixelRange = 30; + this._dataSource.clustering.minimumClusterSize = 5; viewer.dataSources.add(this._dataSource); this._fetch(); var self = this; @@ -41,42 +44,42 @@ const FlightsLayer = { self._count = ac.length; ac.forEach(function(a) { if (!a.lat || !a.lon) return; - var alt = (a.alt_baro || a.alt_geom || 10000) * 0.3048; // ft -> m - if (alt < 100) alt = 10000; // ground = default - var cs = (a.flight || a.callsign || a.hex || '???').trim(); - var spd = a.gs || 0; + // alt_baro ist in ft vom Backend, konvertiere zu m fuer Cesium + var altFt = a.alt_baro || 30000; + var altM = altFt * 0.3048; + var cs = (a.flight || a.hex || '').trim() || '?'; self._dataSource.entities.add({ - position: Cesium.Cartesian3.fromDegrees(a.lon, a.lat, alt), + position: Cesium.Cartesian3.fromDegrees(a.lon, a.lat, altM), point: { - pixelSize: 4, + pixelSize: 3, color: Cesium.Color.fromCssColorString('#00ff88'), - outlineColor: Cesium.Color.fromCssColorString('#004422'), + outlineColor: Cesium.Color.fromCssColorString('#003311'), outlineWidth: 1, heightReference: Cesium.HeightReference.NONE, }, label: { text: cs, font: '10px monospace', - fillColor: Cesium.Color.fromCssColorString('#00ff88').withAlpha(0.8), + fillColor: Cesium.Color.fromCssColorString('#00ff88').withAlpha(0.7), outlineColor: Cesium.Color.BLACK, outlineWidth: 2, style: Cesium.LabelStyle.FILL_AND_OUTLINE, - pixelOffset: new Cesium.Cartesian2(8, -4), - scale: 0.8, - showBackground: false, - distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000), + pixelOffset: new Cesium.Cartesian2(6, -3), + scale: 0.7, + distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 800000), }, description: '
' + '' + cs + '
' + - 'ALT: ' + (a.alt_baro || '?') + ' ft
' + - 'SPD: ' + Math.round(spd) + ' kts
' + - 'HDG: ' + Math.round(a.track || 0) + '°' + - (a.t ? '
TYP: ' + a.t : '') + + 'ALT: ' + altFt + ' ft
' + + 'SPD: ' + (a.gs || '?') + ' kts
' + + 'HDG: ' + Math.round(a.track || 0) + '°' + + (a.origin ? '
FROM: ' + a.origin : '') + '
', }); }); + if (statusEl) { statusEl.textContent = ac.length.toLocaleString('de-DE') + ' Flugzeuge'; } }) .catch(function(e) { console.warn('Flights fetch error:', e); if (statusEl) { statusEl.textContent = 'Fehler beim Laden'; } }) - .finally(function() { if (loadEl) loadEl.classList.remove('active'); setTimeout(function() { if (statusEl) statusEl.classList.remove('active'); }, 3000); }); + .finally(function() { if (loadEl) loadEl.classList.remove('active'); setTimeout(function() { if (statusEl) statusEl.classList.remove('active'); }, 5000); }); }, }; diff --git a/static/js/layers/ships.js b/static/js/layers/ships.js index bc482f3..7d8b552 100644 --- a/static/js/layers/ships.js +++ b/static/js/layers/ships.js @@ -11,6 +11,9 @@ const ShipsLayer = { if (this._dataSource) return; this._viewer = viewer; this._dataSource = new Cesium.CustomDataSource('ships'); + this._dataSource.clustering.enabled = true; + this._dataSource.clustering.pixelRange = 25; + this._dataSource.clustering.minimumClusterSize = 5; viewer.dataSources.add(this._dataSource); this._fetch(); var self = this; @@ -41,42 +44,42 @@ const ShipsLayer = { self._count = ships.length; ships.forEach(function(s) { if (!s.lat || !s.lon) return; + var name = s.name || ('MMSI ' + (s.mmsi || '?')); var sog = s.sog || 0; var color = sog > 0.5 ? Cesium.Color.fromCssColorString('#4499ff') - : Cesium.Color.fromCssColorString('#556688'); - var name = s.name || ('MMSI ' + (s.mmsi || '?')); + : Cesium.Color.fromCssColorString('#445577'); self._dataSource.entities.add({ position: Cesium.Cartesian3.fromDegrees(s.lon, s.lat, 0), point: { pixelSize: 3, color: color, - outlineColor: Cesium.Color.fromCssColorString('#112244'), + outlineColor: Cesium.Color.fromCssColorString('#112233'), outlineWidth: 0.5, heightReference: Cesium.HeightReference.NONE, }, label: { text: name, font: '9px monospace', - fillColor: Cesium.Color.fromCssColorString('#4499ff').withAlpha(0.7), + fillColor: Cesium.Color.fromCssColorString('#4499ff').withAlpha(0.6), outlineColor: Cesium.Color.BLACK, outlineWidth: 2, style: Cesium.LabelStyle.FILL_AND_OUTLINE, - pixelOffset: new Cesium.Cartesian2(6, -3), - scale: 0.7, - distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 500000), + pixelOffset: new Cesium.Cartesian2(5, -2), + scale: 0.6, + distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 300000), }, description: '
' + '' + name + '
' + 'MMSI: ' + (s.mmsi || '?') + '
' + 'SOG: ' + sog.toFixed(1) + ' kn
' + - 'COG: ' + Math.round(s.cog || 0) + '°
' + - 'HDG: ' + (s.heading || '?') + '°' + + 'COG: ' + Math.round(s.cog || 0) + '°' + '
', }); }); + if (statusEl) { statusEl.textContent = ships.length.toLocaleString('de-DE') + ' Schiffe'; } }) .catch(function(e) { console.warn('Ships fetch error:', e); if (statusEl) { statusEl.textContent = 'Fehler beim Laden'; } }) - .finally(function() { if (loadEl) loadEl.classList.remove('active'); setTimeout(function() { if (statusEl) statusEl.classList.remove('active'); }, 3000); }); + .finally(function() { if (loadEl) loadEl.classList.remove('active'); setTimeout(function() { if (statusEl) statusEl.classList.remove('active'); }, 5000); }); }, };