diff --git a/src/static/js/geoint.js b/src/static/js/geoint.js
index 1979acc..a071950 100644
--- a/src/static/js/geoint.js
+++ b/src/static/js/geoint.js
@@ -14,6 +14,8 @@ const GEOINT = {
_quakeInterval: null,
_gdeltInterval: null,
_shipsLayer: null,
+ _flightsData: null,
+ _shipsData: null,
_shipsInterval: null,
_flightFetching: false,
_moveHandler: null,
@@ -166,8 +168,7 @@ const GEOINT = {
this._sublayers[id] = enabled;
this._saveState();
switch (id) {
- case 'flights': enabled ? this._startFlights(map) : this._stopFlights();
- this._stopShips(); break;
+ case 'flights': enabled ? this._startFlights(map) : this._stopFlights(); break;
case 'ships': enabled ? this._startShips(map) : this._stopShips(); break;
case 'quakes': enabled ? this._startQuakes(map) : this._stopQuakes(); break;
case 'gdelt': enabled ? this._startGdelt(map) : this._stopGdelt(); break;
@@ -195,7 +196,15 @@ const GEOINT = {
var self = this;
this._fetchFlights(map);
this._flightInterval = setInterval(function() { self._fetchFlights(map); }, 30000); // 30s global refresh
- // Globale Daten - kein moveend-Handler noetig
+ // Bei Kartenbewegung neu rendern (client-seitig aus Cache)
+ this._moveHandler = function() {
+ clearTimeout(self._moveDebounce);
+ self._moveDebounce = setTimeout(function() {
+ self._renderFlights(map);
+ self._renderShips(map);
+ }, 300);
+ };
+ map.on('moveend', this._moveHandler);
},
_stopFlights() {
@@ -215,11 +224,9 @@ const GEOINT = {
.then(function(r) { return r.ok ? r.json() : { ac: [] }; })
.then(function(data) {
if (!self._flightLayer) return;
- // Neue Marker in temporaerem Layer bauen, dann atomar swappen
- var newLayer = L.layerGroup();
- var ac = data.ac || data.aircraft || [];
- ac.slice(0, 500).forEach(function(a) {
- if (!a.lat || !a.lon) return;
+ self._flightsData = data.ac || data.aircraft || [];
+ self._renderFlights(map);
+ })
var heading = a.track || a.true_heading || 0;
var icon = L.divIcon({
className: '',
@@ -241,18 +248,45 @@ const GEOINT = {
'
SPD ' + (typeof spd === 'number' ? Math.round(spd) + ' kts' : spd) +
'
HDG ' + Math.round(heading) + '°' +
'';
- L.marker([a.lat, a.lon], { icon: icon }).bindPopup(popup, { className: 'geoint-leaflet-popup' }).addTo(newLayer);
- });
- // Atomar swappen: alte Marker entfernen, neue hinzufuegen
- if (self._map && self._flightLayer) {
- self._map.removeLayer(self._flightLayer);
- self._flightLayer = newLayer.addTo(self._map);
- }
- })
.catch(function(e) { if (typeof DEV_MODE !== 'undefined' && DEV_MODE) console.warn('GEOINT flights:', e); })
.finally(function() { self._flightFetching = false; });
},
+ _renderFlights(map) {
+ if (!map || !this._flightLayer || !this._flightsData) return;
+ var newLayer = L.layerGroup();
+ var bounds = map.getBounds();
+ this._flightsData.forEach(function(a) {
+ if (!a.lat || !a.lon || !bounds.contains([a.lat, a.lon])) return;
+ var heading = a.track || a.true_heading || 0;
+ var icon = L.divIcon({
+ className: '',
+ html: '