suncalc-ruby 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
@@ -0,0 +1,12 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ InstalledFiles
7
+ _yardoc
8
+ coverage
9
+ pkg
10
+ rdoc
11
+ tags
12
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -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.
@@ -0,0 +1,2 @@
1
+ # suncalc-ruby
2
+ Ruby port of SunCalc via ExecJS
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -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
@@ -0,0 +1,3 @@
1
+ module SunCalc
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ RSpec.configure do |config|
2
+ config.treat_symbols_as_metadata_keys_with_true_values = true
3
+ config.run_all_when_everything_filtered = true
4
+ config.filter_run :focus
5
+ config.order = 'random'
6
+ end
@@ -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