UNPKG

7.86 kBJavaScriptView Raw
1function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2
3/**
4 * @copyright 2016 commenthol
5 * @license MIT
6 * @module sunrise
7 */
8/**
9 * Sunrise: Compute rise, noon, set of the Sun for an earth observer
10 */
11
12/* eslint key-spacing: 0 */
13
14import base from './base';
15import eqtime from './eqtime';
16import sexa from './sexagesimal';
17import solar from './solar';
18import julian from './julian';
19import rise from './rise';
20
21var stdh0 = {
22 sunrise: new sexa.Angle(true, 0, 50, 0).rad(),
23 sunriseEnd: new sexa.Angle(true, 0, 18, 0).rad(),
24 twilight: new sexa.Angle(true, 6, 0, 0).rad(),
25 nauticalTwilight: new sexa.Angle(true, 12, 0, 0).rad(),
26 night: new sexa.Angle(true, 18, 0, 0).rad(),
27 goldenHour: new sexa.Angle(false, 6, 0, 0).rad()
28};
29
30var stdh0Sunrise = function stdh0Sunrise(refraction) {
31 return rise.refraction(stdh0.sunrise, refraction);
32};
33var stdh0SunriseEnd = function stdh0SunriseEnd(refraction) {
34 return rise.refraction(stdh0.sunriseEnd, refraction);
35};
36var stdh0Twilight = function stdh0Twilight(refraction) {
37 return rise.refraction(stdh0.twilight, refraction);
38};
39var stdh0NauticalTwilight = function stdh0NauticalTwilight(refraction) {
40 return rise.refraction(stdh0.nauticalTwilight, refraction);
41};
42var stdh0Night = function stdh0Night(refraction) {
43 return rise.refraction(stdh0.night, refraction);
44};
45var stdh0GoldenHour = function stdh0GoldenHour(refraction) {
46 return rise.refraction(stdh0.goldenHour, refraction);
47};
48
49export var Sunrise = function () {
50 /**
51 * Computes time of sunrise, sunset for a given day `date` of an observer on earth given by latitude and longitude.
52 * Methods may return `undefined` instead of `julian.Calendar` for latitudes very near the poles.
53 * @param {julian.Calendar} date - calendar date
54 * @param {number} lat - latitude of observer in the range of (-89.6, 89.6)
55 * @param {number} lon - longitude of observer (measured positively westwards, New York = 40.7° lat, 74° lon)
56 * @param {number} [refraction] - optional refraction
57 */
58 function Sunrise(date, lat, lon, refraction) {
59 _classCallCheck(this, Sunrise);
60
61 this.date = date;
62 this.jde = date.midnight().toJDE();
63 this.lat = sexa.angleFromDeg(lat);
64 this.lon = sexa.angleFromDeg(lon);
65 this.refraction = refraction;
66 }
67
68 Sunrise.prototype._calcNoon = function _calcNoon(jde) {
69 var etime = sexa.secFromHourAngle(eqtime.eSmart(jde));
70 var delta = sexa.secFromHourAngle(this.lon);
71 var time = 43200 /* noon */ + delta - etime; // in seconds
72 return base.pmod(time / 86400, 86400);
73 };
74
75 Sunrise.prototype._calcRiseOrSet = function _calcRiseOrSet(jde, h0, isSet) {
76 var etime = sexa.secFromHourAngle(eqtime.eSmart(jde));
77 var solarDec = solar.apparentEquatorial(jde).dec;
78 var ha = rise.hourAngle(this.lat, h0, solarDec);
79 if (isSet) ha = -ha;
80 var delta = sexa.secFromHourAngle(ha - this.lon);
81 var time = 43200 /* noon */ - delta - etime; // in seconds
82 return time / 86400;
83 };
84
85 Sunrise.prototype._calcPolarDayNight = function _calcPolarDayNight(h0, isSet, step) {
86 var jde = this.jde;
87 var t = void 0;
88 var failCnt = 0;
89 while (failCnt < 190) {
90 // a bit more than days of half a year
91 jde += step;
92 try {
93 t = this._calcRiseOrSet(jde, h0, isSet);
94 t = this._calcRiseOrSet(jde + t, h0, isSet);
95 break;
96 } catch (e) {
97 t = undefined;
98 failCnt++;
99 }
100 }
101 if (t === undefined) {
102 return;
103 }
104 return new julian.Calendar().fromJDE(jde + t);
105 };
106
107 Sunrise.prototype._calc = function _calc(h0, isSet) {
108 var t = void 0;
109 var jde = this.jde;
110 // calc 2times for higher accuracy
111 try {
112 t = this._calcRiseOrSet(jde, h0, isSet);
113 t = this._calcRiseOrSet(jde + t, h0, isSet);
114 return new julian.Calendar().fromJDE(jde + t);
115 } catch (e) {
116 var step = isSet ? -1 : 1;
117 var doy = this.date.dayOfYear();
118 if ( // overlap with march, september equinoxes
119 this.lat > 0 && doy > 76 && doy < 267 || // northern hemisphere
120 this.lat < 0 && (doy < 83 || doy > 262) // southern hemisphere
121 ) {
122 step = -step;
123 }
124 return this._calcPolarDayNight(h0, isSet, step);
125 }
126 };
127
128 /**
129 * time of solar transit
130 * @return {julian.Calendar} time of noon
131 */
132
133
134 Sunrise.prototype.noon = function noon() {
135 var jde = this.jde;
136 // calc 2times for higher accuracy
137 var t = this._calcNoon(jde + this.lon / (2 * Math.PI));
138 t = this._calcNoon(jde + t);
139 return new julian.Calendar().fromJDE(jde + t);
140 };
141
142 /**
143 * Solar limb appears over the easter horizon in the morning
144 * @return {julian.Calendar} time of sunrise
145 */
146
147
148 Sunrise.prototype.rise = function rise() {
149 return this._calc(stdh0Sunrise(this.refraction), false);
150 };
151
152 /**
153 * @return {julian.Calendar} time of sunset
154 * Solar limb disappears on the western horizon in the evening
155 */
156
157
158 Sunrise.prototype.set = function set() {
159 return this._calc(stdh0Sunrise(this.refraction), true);
160 };
161
162 /**
163 * Solar limb is fully visible at the easter horizon
164 * @return {julian.Calendar} time of sunrise end
165 */
166
167
168 Sunrise.prototype.riseEnd = function riseEnd() {
169 return this._calc(stdh0SunriseEnd(this.refraction), false);
170 };
171
172 /**
173 * Solar limb starts disappearing on the western horizon in the evening
174 * @return {julian.Calendar} time of sunset start
175 */
176
177
178 Sunrise.prototype.setStart = function setStart() {
179 return this._calc(stdh0SunriseEnd(this.refraction), true);
180 };
181
182 /**
183 * Dawn, there is still enough light for objects to be distinguishable,
184 * @return {julian.Calendar} time of dawn
185 */
186
187
188 Sunrise.prototype.dawn = function dawn() {
189 return this._calc(stdh0Twilight(this.refraction), false);
190 };
191
192 /**
193 * Dusk, there is still enough light for objects to be distinguishable
194 * Bright stars and planets are visible by naked eye
195 * @return {julian.Calendar} time of dusk
196 */
197
198
199 Sunrise.prototype.dusk = function dusk() {
200 return this._calc(stdh0Twilight(this.refraction), true);
201 };
202
203 /**
204 * nautical dawn - Horizon gets visible by naked eye
205 * @return {julian.Calendar} time of nautical dawn
206 */
207
208
209 Sunrise.prototype.nauticalDawn = function nauticalDawn() {
210 return this._calc(stdh0NauticalTwilight(this.refraction), false);
211 };
212
213 /**
214 * nautical dusk - Horizon is no longer visible by naked eye
215 * @return {julian.Calendar} time of nautical dusk
216 */
217
218
219 Sunrise.prototype.nauticalDusk = function nauticalDusk() {
220 return this._calc(stdh0NauticalTwilight(this.refraction), true);
221 };
222
223 /**
224 * night starts - No sunlight illumination of the sky, such no intereferance
225 * with astronomical observations.
226 * @return {julian.Calendar} time of start of night
227 */
228
229
230 Sunrise.prototype.nightStart = function nightStart() {
231 return this._calc(stdh0Night(this.refraction), true);
232 };
233
234 /**
235 * night end - Sunlight starts illumination of the sky and interferes
236 * with astronomical observations.
237 * @return {julian.Calendar} time of end of night
238 */
239
240
241 Sunrise.prototype.nightEnd = function nightEnd() {
242 return this._calc(stdh0Night(this.refraction), false);
243 };
244
245 /**
246 * Start of "golden hour" before sunset
247 * @return {julian.Calendar} time of start of golden hour
248 */
249
250
251 Sunrise.prototype.goldenHourStart = function goldenHourStart() {
252 return this._calc(stdh0GoldenHour(this.refraction), true);
253 };
254
255 /**
256 * End of "golden hour" after sunrise
257 * @return {julian.Calendar} time of end of golden hour
258 */
259
260
261 Sunrise.prototype.goldenHourEnd = function goldenHourEnd() {
262 return this._calc(stdh0GoldenHour(this.refraction), false);
263 };
264
265 return Sunrise;
266}();
267
268export default {
269 Sunrise: Sunrise
270};
\No newline at end of file