suncalc-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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