/** * 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, }, }); }, };