Sonnenterminatur + Zeitzonen-Overlay
SONNENTERMINATUR: - Echtzeit Tag/Nacht-Grenze als orange Linie auf dem Globus - Nachtseite als halbtransparenter schwarzer Schatten - Basiert auf Sonnendeklination + UTC-Zeit - Aktualisiert jede Minute ZEITZONEN: - 24 vertikale Linien (alle 15 Grad Laengengrad) - Jede Zone zeigt aktuelle Uhrzeit (z.B. UTC+2 14:30) - Labels bei Zoom (<8000km) sichtbar - Aktualisiert jede Minute Alle Features der ersten Tabelle nun implementiert.
Dieser Commit ist enthalten in:
91
static/js/layers/terminator.js
Normale Datei
91
static/js/layers/terminator.js
Normale Datei
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Sonnenterminatur: Echtzeit Tag/Nacht-Grenze als Linie + Nachtflaeche.
|
||||
*/
|
||||
const TerminatorLayer = {
|
||||
_viewer: null,
|
||||
_entity: null,
|
||||
_line: null,
|
||||
_interval: null,
|
||||
_count: 0,
|
||||
|
||||
start(viewer) {
|
||||
if (this._entity) return;
|
||||
this._viewer = viewer;
|
||||
this._render();
|
||||
this._count = 1;
|
||||
var self = this;
|
||||
this._interval = setInterval(function() { self._render(); }, 60000);
|
||||
},
|
||||
|
||||
stop() {
|
||||
if (this._interval) { clearInterval(this._interval); this._interval = null; }
|
||||
if (this._entity && this._viewer) { this._viewer.entities.remove(this._entity); this._entity = null; }
|
||||
if (this._line && this._viewer) { this._viewer.entities.remove(this._line); this._line = null; }
|
||||
this._count = 0;
|
||||
},
|
||||
|
||||
_calcTerminator() {
|
||||
// Sonnenposition berechnen
|
||||
var now = new Date();
|
||||
var dayOfYear = Math.floor((now - new Date(now.getFullYear(), 0, 0)) / 86400000);
|
||||
var declination = -23.45 * Math.cos((360 / 365) * (dayOfYear + 10) * Math.PI / 180);
|
||||
var decRad = declination * Math.PI / 180;
|
||||
|
||||
// Stunden seit Mitternacht UTC
|
||||
var utcHours = now.getUTCHours() + now.getUTCMinutes() / 60 + now.getUTCSeconds() / 3600;
|
||||
var sunLon = -(utcHours - 12) * 15; // Sonnen-Laengengrad
|
||||
|
||||
// Terminatur-Punkte berechnen (Polygon um die Nachtseite)
|
||||
var points = [];
|
||||
var linePoints = [];
|
||||
for (var i = 0; i <= 360; i += 2) {
|
||||
var lon = i - 180;
|
||||
var lonRad = (lon - sunLon) * Math.PI / 180;
|
||||
var lat = Math.atan(-Math.cos(lonRad) / Math.tan(decRad)) * 180 / Math.PI;
|
||||
linePoints.push(lon, lat);
|
||||
}
|
||||
|
||||
// Nacht-Polygon: Terminatur-Linie + Pole
|
||||
var nightPolygon = [];
|
||||
// Oberer Rand (Nordpol oder Suedpol je nach Jahreszeit)
|
||||
var topLat = declination > 0 ? -90 : 90;
|
||||
nightPolygon.push(-180, topLat);
|
||||
for (var j = 0; j < linePoints.length; j += 2) {
|
||||
nightPolygon.push(linePoints[j], linePoints[j + 1]);
|
||||
}
|
||||
nightPolygon.push(180, topLat);
|
||||
|
||||
return { line: linePoints, night: nightPolygon };
|
||||
},
|
||||
|
||||
_render() {
|
||||
if (!this._viewer) return;
|
||||
var data = this._calcTerminator();
|
||||
|
||||
// Alte Entities entfernen
|
||||
if (this._entity) this._viewer.entities.remove(this._entity);
|
||||
if (this._line) this._viewer.entities.remove(this._line);
|
||||
|
||||
// Nachtflaeche (dunkel, halbtransparent)
|
||||
var nightPositions = Cesium.Cartesian3.fromDegreesArray(data.night);
|
||||
this._entity = this._viewer.entities.add({
|
||||
polygon: {
|
||||
hierarchy: new Cesium.PolygonHierarchy(nightPositions),
|
||||
material: Cesium.Color.BLACK.withAlpha(0.35),
|
||||
height: 0,
|
||||
outline: false,
|
||||
},
|
||||
});
|
||||
|
||||
// Terminatur-Linie (leuchtend)
|
||||
var linePositions = Cesium.Cartesian3.fromDegreesArray(data.line);
|
||||
this._line = this._viewer.entities.add({
|
||||
polyline: {
|
||||
positions: linePositions,
|
||||
width: 2,
|
||||
material: Cesium.Color.fromCssColorString('#ff8800').withAlpha(0.6),
|
||||
clampToGround: true,
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren