suncalc-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +2 -0
- data/Rakefile +1 -0
- data/lib/suncalc.rb +32 -0
- data/lib/suncalc/version.rb +3 -0
- data/spec/spec_helper.rb +6 -0
- data/suncalc-ruby.gemspec +20 -0
- data/vendor/assets/javascripts/suncalc.js +302 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ae3f62e2f7c37e318284ccb38a83c52a454d7120
|
4
|
+
data.tar.gz: 936263f27c12752af5ebbb7d55d55d25df187b8b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 67c1b304161c8e1040afda5c5955cd9595c1e90246945101a69b5d704a0624743bb52077729258e2616651a41ab5f3992ea6aa449fd4597f6a6bf452bc4fe434
|
7
|
+
data.tar.gz: 7f4f1014e71b6e944f948a2a85b180611fdb471e202a1b75b5890745544dab0a9c80a5cddbee56e08d33077a2ef46e6be0f6069bd3c4017e8df2532d41f6b8b6
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Mateus Maso
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/suncalc.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require "suncalc/version"
|
2
|
+
require "pathname"
|
3
|
+
require "execjs"
|
4
|
+
|
5
|
+
module SunCalc
|
6
|
+
def self.source
|
7
|
+
"window = {}; #{File.read(Pathname(__FILE__).dirname.join('..', 'vendor', 'assets', 'javascripts', 'suncalc.js'))}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.context
|
11
|
+
ExecJS.compile(source)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.times(date, latitude, longitude)
|
15
|
+
times = self.context.eval("window.SunCalc.getTimes(new Date(#{date.to_f * 1000}), #{latitude}, #{longitude})")
|
16
|
+
|
17
|
+
times.keys.each do |key|
|
18
|
+
old_key = key
|
19
|
+
key = key.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
20
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
21
|
+
tr('-', '_').
|
22
|
+
gsub(/\s/, '_').
|
23
|
+
gsub(/__+/, '_').
|
24
|
+
downcase.
|
25
|
+
to_sym
|
26
|
+
|
27
|
+
times[key] = times.delete(old_key)
|
28
|
+
end
|
29
|
+
|
30
|
+
times
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'suncalc/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "suncalc-ruby"
|
6
|
+
spec.version = SunCalc::VERSION
|
7
|
+
spec.authors = ["mateusmaso"]
|
8
|
+
spec.email = ["m.maso25@gmail.com"]
|
9
|
+
spec.description = %q{Ruby port of SunCalc via ExecJS}
|
10
|
+
spec.summary = %q{Ruby port of SunCalc via ExecJS}
|
11
|
+
spec.homepage = "https://github.com/mateusmaso/suncalc-ruby"
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
spec.files = `git ls-files`.split($/)
|
15
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_dependency 'execjs', ">= 1.3"
|
20
|
+
end
|
@@ -0,0 +1,302 @@
|
|
1
|
+
/*
|
2
|
+
(c) 2011-2014, Vladimir Agafonkin
|
3
|
+
SunCalc is a JavaScript library for calculating sun/mooon position and light phases.
|
4
|
+
https://github.com/mourner/suncalc
|
5
|
+
*/
|
6
|
+
|
7
|
+
(function () { 'use strict';
|
8
|
+
|
9
|
+
// shortcuts for easier to read formulas
|
10
|
+
|
11
|
+
var PI = Math.PI,
|
12
|
+
sin = Math.sin,
|
13
|
+
cos = Math.cos,
|
14
|
+
tan = Math.tan,
|
15
|
+
asin = Math.asin,
|
16
|
+
atan = Math.atan2,
|
17
|
+
acos = Math.acos,
|
18
|
+
rad = PI / 180;
|
19
|
+
|
20
|
+
// sun calculations are based on http://aa.quae.nl/en/reken/zonpositie.html formulas
|
21
|
+
|
22
|
+
|
23
|
+
// date/time constants and conversions
|
24
|
+
|
25
|
+
var dayMs = 1000 * 60 * 60 * 24,
|
26
|
+
J1970 = 2440588,
|
27
|
+
J2000 = 2451545;
|
28
|
+
|
29
|
+
function toJulian(date) { return date.valueOf() / dayMs - 0.5 + J1970; }
|
30
|
+
function fromJulian(j) { return new Date((j + 0.5 - J1970) * dayMs); }
|
31
|
+
function toDays(date) { return toJulian(date) - J2000; }
|
32
|
+
|
33
|
+
|
34
|
+
// general calculations for position
|
35
|
+
|
36
|
+
var e = rad * 23.4397; // obliquity of the Earth
|
37
|
+
|
38
|
+
function rightAscension(l, b) { return atan(sin(l) * cos(e) - tan(b) * sin(e), cos(l)); }
|
39
|
+
function declination(l, b) { return asin(sin(b) * cos(e) + cos(b) * sin(e) * sin(l)); }
|
40
|
+
|
41
|
+
function azimuth(H, phi, dec) { return atan(sin(H), cos(H) * sin(phi) - tan(dec) * cos(phi)); }
|
42
|
+
function altitude(H, phi, dec) { return asin(sin(phi) * sin(dec) + cos(phi) * cos(dec) * cos(H)); }
|
43
|
+
|
44
|
+
function siderealTime(d, lw) { return rad * (280.16 + 360.9856235 * d) - lw; }
|
45
|
+
|
46
|
+
|
47
|
+
// general sun calculations
|
48
|
+
|
49
|
+
function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }
|
50
|
+
|
51
|
+
function eclipticLongitude(M) {
|
52
|
+
|
53
|
+
var C = rad * (1.9148 * sin(M) + 0.02 * sin(2 * M) + 0.0003 * sin(3 * M)), // equation of center
|
54
|
+
P = rad * 102.9372; // perihelion of the Earth
|
55
|
+
|
56
|
+
return M + C + P + PI;
|
57
|
+
}
|
58
|
+
|
59
|
+
function sunCoords(d) {
|
60
|
+
|
61
|
+
var M = solarMeanAnomaly(d),
|
62
|
+
L = eclipticLongitude(M);
|
63
|
+
|
64
|
+
return {
|
65
|
+
dec: declination(L, 0),
|
66
|
+
ra: rightAscension(L, 0)
|
67
|
+
};
|
68
|
+
}
|
69
|
+
|
70
|
+
|
71
|
+
var SunCalc = {};
|
72
|
+
|
73
|
+
|
74
|
+
// calculates sun position for a given date and latitude/longitude
|
75
|
+
|
76
|
+
SunCalc.getPosition = function (date, lat, lng) {
|
77
|
+
|
78
|
+
var lw = rad * -lng,
|
79
|
+
phi = rad * lat,
|
80
|
+
d = toDays(date),
|
81
|
+
|
82
|
+
c = sunCoords(d),
|
83
|
+
H = siderealTime(d, lw) - c.ra;
|
84
|
+
|
85
|
+
return {
|
86
|
+
azimuth: azimuth(H, phi, c.dec),
|
87
|
+
altitude: altitude(H, phi, c.dec)
|
88
|
+
};
|
89
|
+
};
|
90
|
+
|
91
|
+
|
92
|
+
// sun times configuration (angle, morning name, evening name)
|
93
|
+
|
94
|
+
var times = SunCalc.times = [
|
95
|
+
[-0.833, 'sunrise', 'sunset' ],
|
96
|
+
[ -0.3, 'sunriseEnd', 'sunsetStart' ],
|
97
|
+
[ -6, 'dawn', 'dusk' ],
|
98
|
+
[ -12, 'nauticalDawn', 'nauticalDusk'],
|
99
|
+
[ -18, 'nightEnd', 'night' ],
|
100
|
+
[ 6, 'goldenHourEnd', 'goldenHour' ]
|
101
|
+
];
|
102
|
+
|
103
|
+
// adds a custom time to the times config
|
104
|
+
|
105
|
+
SunCalc.addTime = function (angle, riseName, setName) {
|
106
|
+
times.push([angle, riseName, setName]);
|
107
|
+
};
|
108
|
+
|
109
|
+
|
110
|
+
// calculations for sun times
|
111
|
+
|
112
|
+
var J0 = 0.0009;
|
113
|
+
|
114
|
+
function julianCycle(d, lw) { return Math.round(d - J0 - lw / (2 * PI)); }
|
115
|
+
|
116
|
+
function approxTransit(Ht, lw, n) { return J0 + (Ht + lw) / (2 * PI) + n; }
|
117
|
+
function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * sin(M) - 0.0069 * sin(2 * L); }
|
118
|
+
|
119
|
+
function hourAngle(h, phi, d) { return acos((sin(h) - sin(phi) * sin(d)) / (cos(phi) * cos(d))); }
|
120
|
+
|
121
|
+
// returns set time for the given sun altitude
|
122
|
+
function getSetJ(h, lw, phi, dec, n, M, L) {
|
123
|
+
|
124
|
+
var w = hourAngle(h, phi, dec),
|
125
|
+
a = approxTransit(w, lw, n);
|
126
|
+
return solarTransitJ(a, M, L);
|
127
|
+
}
|
128
|
+
|
129
|
+
|
130
|
+
// calculates sun times for a given date and latitude/longitude
|
131
|
+
|
132
|
+
SunCalc.getTimes = function (date, lat, lng) {
|
133
|
+
|
134
|
+
var lw = rad * -lng,
|
135
|
+
phi = rad * lat,
|
136
|
+
|
137
|
+
d = toDays(date),
|
138
|
+
n = julianCycle(d, lw),
|
139
|
+
ds = approxTransit(0, lw, n),
|
140
|
+
|
141
|
+
M = solarMeanAnomaly(ds),
|
142
|
+
L = eclipticLongitude(M),
|
143
|
+
dec = declination(L, 0),
|
144
|
+
|
145
|
+
Jnoon = solarTransitJ(ds, M, L),
|
146
|
+
|
147
|
+
i, len, time, Jset, Jrise;
|
148
|
+
|
149
|
+
|
150
|
+
var result = {
|
151
|
+
solarNoon: fromJulian(Jnoon),
|
152
|
+
nadir: fromJulian(Jnoon - 0.5)
|
153
|
+
};
|
154
|
+
|
155
|
+
for (i = 0, len = times.length; i < len; i += 1) {
|
156
|
+
time = times[i];
|
157
|
+
|
158
|
+
Jset = getSetJ(time[0] * rad, lw, phi, dec, n, M, L);
|
159
|
+
Jrise = Jnoon - (Jset - Jnoon);
|
160
|
+
|
161
|
+
result[time[1]] = fromJulian(Jrise);
|
162
|
+
result[time[2]] = fromJulian(Jset);
|
163
|
+
}
|
164
|
+
|
165
|
+
return result;
|
166
|
+
};
|
167
|
+
|
168
|
+
|
169
|
+
// moon calculations, based on http://aa.quae.nl/en/reken/hemelpositie.html formulas
|
170
|
+
|
171
|
+
function moonCoords(d) { // geocentric ecliptic coordinates of the moon
|
172
|
+
|
173
|
+
var L = rad * (218.316 + 13.176396 * d), // ecliptic longitude
|
174
|
+
M = rad * (134.963 + 13.064993 * d), // mean anomaly
|
175
|
+
F = rad * (93.272 + 13.229350 * d), // mean distance
|
176
|
+
|
177
|
+
l = L + rad * 6.289 * sin(M), // longitude
|
178
|
+
b = rad * 5.128 * sin(F), // latitude
|
179
|
+
dt = 385001 - 20905 * cos(M); // distance to the moon in km
|
180
|
+
|
181
|
+
return {
|
182
|
+
ra: rightAscension(l, b),
|
183
|
+
dec: declination(l, b),
|
184
|
+
dist: dt
|
185
|
+
};
|
186
|
+
}
|
187
|
+
|
188
|
+
SunCalc.getMoonPosition = function (date, lat, lng) {
|
189
|
+
|
190
|
+
var lw = rad * -lng,
|
191
|
+
phi = rad * lat,
|
192
|
+
d = toDays(date),
|
193
|
+
|
194
|
+
c = moonCoords(d),
|
195
|
+
H = siderealTime(d, lw) - c.ra,
|
196
|
+
h = altitude(H, phi, c.dec);
|
197
|
+
|
198
|
+
// altitude correction for refraction
|
199
|
+
h = h + rad * 0.017 / tan(h + rad * 10.26 / (h + rad * 5.10));
|
200
|
+
|
201
|
+
return {
|
202
|
+
azimuth: azimuth(H, phi, c.dec),
|
203
|
+
altitude: h,
|
204
|
+
distance: c.dist
|
205
|
+
};
|
206
|
+
};
|
207
|
+
|
208
|
+
|
209
|
+
// calculations for illumination parameters of the moon,
|
210
|
+
// based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and
|
211
|
+
// Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.
|
212
|
+
|
213
|
+
SunCalc.getMoonIllumination = function (date) {
|
214
|
+
|
215
|
+
var d = toDays(date),
|
216
|
+
s = sunCoords(d),
|
217
|
+
m = moonCoords(d),
|
218
|
+
|
219
|
+
sdist = 149598000, // distance from Earth to Sun in km
|
220
|
+
|
221
|
+
phi = acos(sin(s.dec) * sin(m.dec) + cos(s.dec) * cos(m.dec) * cos(s.ra - m.ra)),
|
222
|
+
inc = atan(sdist * sin(phi), m.dist - sdist * cos(phi)),
|
223
|
+
angle = atan(cos(s.dec) * sin(s.ra - m.ra), sin(s.dec) * cos(m.dec) -
|
224
|
+
cos(s.dec) * sin(m.dec) * cos(s.ra - m.ra));
|
225
|
+
|
226
|
+
return {
|
227
|
+
fraction: (1 + cos(inc)) / 2,
|
228
|
+
phase: 0.5 + 0.5 * inc * (angle < 0 ? -1 : 1) / Math.PI,
|
229
|
+
angle: angle
|
230
|
+
};
|
231
|
+
};
|
232
|
+
|
233
|
+
|
234
|
+
function hoursLater(date, h) {
|
235
|
+
return new Date(date.valueOf() + h * dayMs / 24);
|
236
|
+
}
|
237
|
+
|
238
|
+
// calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article
|
239
|
+
|
240
|
+
SunCalc.getMoonTimes = function (date, lat, lng) {
|
241
|
+
var t = new Date(date);
|
242
|
+
t.setHours(0);
|
243
|
+
t.setMinutes(0);
|
244
|
+
t.setSeconds(0);
|
245
|
+
t.setMilliseconds(0);
|
246
|
+
|
247
|
+
var hc = 0.133 * rad,
|
248
|
+
h0 = SunCalc.getMoonPosition(t, lat, lng).altitude - hc,
|
249
|
+
h1, h2, rise, set, a, b, xe, ye, d, roots, x1, x2, dx;
|
250
|
+
|
251
|
+
// go in 2-hour chunks, each time seeing if a 3-point quadratic curve crosses zero (which means rise or set)
|
252
|
+
for (var i = 1; i <= 24; i += 2) {
|
253
|
+
h1 = SunCalc.getMoonPosition(hoursLater(t, i), lat, lng).altitude - hc;
|
254
|
+
h2 = SunCalc.getMoonPosition(hoursLater(t, i + 1), lat, lng).altitude - hc;
|
255
|
+
|
256
|
+
a = (h0 + h2) / 2 - h1;
|
257
|
+
b = (h2 - h0) / 2;
|
258
|
+
xe = -b / (2 * a);
|
259
|
+
ye = (a * xe + b) * xe + h1;
|
260
|
+
d = b * b - 4 * a * h1;
|
261
|
+
roots = 0;
|
262
|
+
|
263
|
+
if (d >= 0) {
|
264
|
+
dx = Math.sqrt(d) / (Math.abs(a) * 2);
|
265
|
+
x1 = xe - dx;
|
266
|
+
x2 = xe + dx;
|
267
|
+
if (Math.abs(x1) <= 1) roots++;
|
268
|
+
if (Math.abs(x2) <= 1) roots++;
|
269
|
+
if (x1 < -1) x1 = x2;
|
270
|
+
}
|
271
|
+
|
272
|
+
if (roots === 1) {
|
273
|
+
if (h0 < 0) rise = i + x1;
|
274
|
+
else set = i + x1;
|
275
|
+
|
276
|
+
} else if (roots === 2) {
|
277
|
+
rise = i + (ye < 0 ? x2 : x1);
|
278
|
+
set = i + (ye < 0 ? x1 : x2);
|
279
|
+
}
|
280
|
+
|
281
|
+
if (rise && set) break;
|
282
|
+
|
283
|
+
h0 = h2;
|
284
|
+
}
|
285
|
+
|
286
|
+
var result = {};
|
287
|
+
|
288
|
+
if (rise) result.rise = hoursLater(t, rise);
|
289
|
+
if (set) result.set = hoursLater(t, set);
|
290
|
+
|
291
|
+
if (!rise && !set) result[ye > 0 ? 'alwaysUp' : 'alwaysDown'] = true;
|
292
|
+
|
293
|
+
return result;
|
294
|
+
};
|
295
|
+
|
296
|
+
|
297
|
+
// export as AMD module / Node module / browser variable
|
298
|
+
if (typeof define === 'function' && define.amd) define(SunCalc);
|
299
|
+
else if (typeof module !== 'undefined') module.exports = SunCalc;
|
300
|
+
else window.SunCalc = SunCalc;
|
301
|
+
|
302
|
+
}());
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: suncalc-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- mateusmaso
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: execjs
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
description: Ruby port of SunCalc via ExecJS
|
28
|
+
email:
|
29
|
+
- m.maso25@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- .gitignore
|
35
|
+
- .rspec
|
36
|
+
- Gemfile
|
37
|
+
- LICENSE.txt
|
38
|
+
- README.md
|
39
|
+
- Rakefile
|
40
|
+
- lib/suncalc.rb
|
41
|
+
- lib/suncalc/version.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
- suncalc-ruby.gemspec
|
44
|
+
- vendor/assets/javascripts/suncalc.js
|
45
|
+
homepage: https://github.com/mateusmaso/suncalc-ruby
|
46
|
+
licenses:
|
47
|
+
- MIT
|
48
|
+
metadata: {}
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
requirements: []
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 2.0.14
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: Ruby port of SunCalc via ExecJS
|
69
|
+
test_files:
|
70
|
+
- spec/spec_helper.rb
|