Fix: Ortsnamen-Layer, InfoBox bei Klick, globale Flugabdeckung
Ortsnamen: Esri World Boundaries als zuschaltbarer Imagery-Layer. InfoBox: CSS-Ausblendung entfernt, Dark-Theme Styling. Flugverkehr: Batch-Groesse 3, Pause 3s, zufaellige Reihenfolge — alle Regionen bekommen Daten statt nur Europa.
Dieser Commit ist enthalten in:
@@ -27,10 +27,12 @@ _lock = asyncio.Lock()
|
|||||||
_task = None
|
_task = None
|
||||||
|
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
async def _fetch_all():
|
async def _fetch_all():
|
||||||
"""Holt Flugdaten fuer alle Stuetzpunkte."""
|
"""Holt Flugdaten fuer alle Stuetzpunkte."""
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if _cache["data"] and now - _cache["ts"] < 25:
|
if _cache["data"] and now - _cache["ts"] < 45:
|
||||||
return _cache["data"]
|
return _cache["data"]
|
||||||
|
|
||||||
async with _lock:
|
async with _lock:
|
||||||
@@ -39,9 +41,11 @@ async def _fetch_all():
|
|||||||
|
|
||||||
seen = {}
|
seen = {}
|
||||||
errors = 0
|
errors = 0
|
||||||
|
grid = list(_GRID)
|
||||||
|
random.shuffle(grid)
|
||||||
async with httpx.AsyncClient(timeout=10) as client:
|
async with httpx.AsyncClient(timeout=10) as client:
|
||||||
for i in range(0, len(_GRID), 10):
|
for i in range(0, len(grid), 3):
|
||||||
batch = _GRID[i:i+10]
|
batch = grid[i:i+3]
|
||||||
tasks = [client.get(f"https://api.airplanes.live/v2/point/{lat:.2f}/{lon:.2f}/250")
|
tasks = [client.get(f"https://api.airplanes.live/v2/point/{lat:.2f}/{lon:.2f}/250")
|
||||||
for lat, lon in batch]
|
for lat, lon in batch]
|
||||||
results = await asyncio.gather(*tasks, return_exceptions=True)
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||||
@@ -56,8 +60,8 @@ async def _fetch_all():
|
|||||||
seen[h] = ac
|
seen[h] = ac
|
||||||
except Exception:
|
except Exception:
|
||||||
errors += 1
|
errors += 1
|
||||||
if i + 10 < len(_GRID):
|
if i + 3 < len(grid):
|
||||||
await asyncio.sleep(0.2)
|
await asyncio.sleep(3.0)
|
||||||
|
|
||||||
_cache["data"] = {"ac": list(seen.values()), "total": len(seen), "errors": errors}
|
_cache["data"] = {"ac": list(seen.values()), "total": len(seen), "errors": errors}
|
||||||
_cache["ts"] = time.time()
|
_cache["ts"] = time.time()
|
||||||
@@ -73,7 +77,7 @@ async def _collector_loop():
|
|||||||
await _fetch_all()
|
await _fetch_all()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Flight collector error: {e}")
|
logger.warning(f"Flight collector error: {e}")
|
||||||
await asyncio.sleep(30)
|
await asyncio.sleep(60)
|
||||||
|
|
||||||
|
|
||||||
def start_flight_collector():
|
def start_flight_collector():
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ html, body { height: 100%; overflow: hidden; background: var(--bg-primary); colo
|
|||||||
.cesium-viewer-animationContainer,
|
.cesium-viewer-animationContainer,
|
||||||
.cesium-viewer-timelineContainer,
|
.cesium-viewer-timelineContainer,
|
||||||
.cesium-viewer-fullscreenContainer,
|
.cesium-viewer-fullscreenContainer,
|
||||||
.cesium-viewer-infoBoxContainer,
|
|
||||||
.cesium-viewer-geocoderContainer,
|
.cesium-viewer-geocoderContainer,
|
||||||
.cesium-viewer-bottom { display: none !important; }
|
.cesium-viewer-bottom { display: none !important; }
|
||||||
.cesium-credit-logoContainer { opacity: 0.3; }
|
.cesium-credit-logoContainer { opacity: 0.3; }
|
||||||
@@ -92,3 +92,23 @@ html, body { height: 100%; overflow: hidden; background: var(--bg-primary); colo
|
|||||||
/* === Cesium InfoBox Override === */
|
/* === Cesium InfoBox Override === */
|
||||||
.cesium-infoBox { background: var(--bg-panel) !important; border: 1px solid var(--border) !important; }
|
.cesium-infoBox { background: var(--bg-panel) !important; border: 1px solid var(--border) !important; }
|
||||||
.cesium-infoBox-title { color: var(--accent) !important; font-family: var(--font-mono) !important; }
|
.cesium-infoBox-title { color: var(--accent) !important; font-family: var(--font-mono) !important; }
|
||||||
|
|
||||||
|
/* === InfoBox (Entity-Details bei Klick) === */
|
||||||
|
.cesium-infoBox {
|
||||||
|
background: var(--bg-panel) !important;
|
||||||
|
border: 1px solid var(--border) !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
box-shadow: 0 8px 32px rgba(0,0,0,0.5) !important;
|
||||||
|
}
|
||||||
|
.cesium-infoBox-title {
|
||||||
|
color: var(--accent) !important;
|
||||||
|
font-family: var(--font-mono) !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
background: rgba(0,255,136,0.08) !important;
|
||||||
|
}
|
||||||
|
.cesium-infoBox-iframe {
|
||||||
|
background: var(--bg-primary) !important;
|
||||||
|
}
|
||||||
|
.cesium-selection-wrapper {
|
||||||
|
border-color: var(--accent) !important;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const Globe = {
|
|||||||
viewer: null,
|
viewer: null,
|
||||||
layers: {},
|
layers: {},
|
||||||
_statsInterval: null,
|
_statsInterval: null,
|
||||||
|
_labelsLayer: null,
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// Cesium Ion Token
|
// Cesium Ion Token
|
||||||
@@ -82,6 +83,22 @@ const Globe = {
|
|||||||
document.getElementById('bottom-stats').textContent = 'Globe initialisiert — Lade Daten...';
|
document.getElementById('bottom-stats').textContent = 'Globe initialisiert — Lade Daten...';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_toggleLabels(on) {
|
||||||
|
if (on && !this._labelsLayer) {
|
||||||
|
this._labelsLayer = this.viewer.imageryLayers.addImageryProvider(
|
||||||
|
new Cesium.UrlTemplateImageryProvider({
|
||||||
|
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
|
||||||
|
maximumLevel: 18,
|
||||||
|
credit: 'Esri',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this._labelsLayer.alpha = 0.9;
|
||||||
|
} else if (!on && this._labelsLayer) {
|
||||||
|
this.viewer.imageryLayers.remove(this._labelsLayer);
|
||||||
|
this._labelsLayer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_setupLayerToggles() {
|
_setupLayerToggles() {
|
||||||
var toggles = {
|
var toggles = {
|
||||||
'layer-flights': function(on) { on ? FlightsLayer.start(Globe.viewer) : FlightsLayer.stop(); },
|
'layer-flights': function(on) { on ? FlightsLayer.start(Globe.viewer) : FlightsLayer.stop(); },
|
||||||
@@ -89,7 +106,7 @@ const Globe = {
|
|||||||
'layer-quakes': function(on) { on ? QuakesLayer.start(Globe.viewer) : QuakesLayer.stop(); },
|
'layer-quakes': function(on) { on ? QuakesLayer.start(Globe.viewer) : QuakesLayer.stop(); },
|
||||||
'layer-gdelt': function(on) { on ? GdeltLayer.start(Globe.viewer) : GdeltLayer.stop(); },
|
'layer-gdelt': function(on) { on ? GdeltLayer.start(Globe.viewer) : GdeltLayer.stop(); },
|
||||||
'layer-daynight': function(on) { Globe.viewer.scene.globe.enableLighting = on; },
|
'layer-daynight': function(on) { Globe.viewer.scene.globe.enableLighting = on; },
|
||||||
'layer-labels': function(on) { /* Phase 2 */ },
|
'layer-labels': function(on) { Globe._toggleLabels(on); },
|
||||||
};
|
};
|
||||||
Object.keys(toggles).forEach(function(id) {
|
Object.keys(toggles).forEach(function(id) {
|
||||||
var cb = document.getElementById(id);
|
var cb = document.getElementById(id);
|
||||||
|
|||||||
In neuem Issue referenzieren
Einen Benutzer sperren