solar_geometry_calculation 0.1.4

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 900bb37f7b3f5cdbe8dc83bd45585cc66ff45f02
4
+ data.tar.gz: d1704fa9695996338eb4d0d01f95f8deb47dbcba
5
+ SHA512:
6
+ metadata.gz: 1dc72c21d597a19454cbc2a83197deda1eb428775dfc456b078bd2d138e8f206239fa218298fc0c2e78d6a4b9fe5d41fabb9ea45599411d681e690e40d8dd963
7
+ data.tar.gz: 9a2faaef30525a75e90696d0c7b9675a75cec9c5ad411912d646f8967a3d5d0500409e0ddafcdcb2f4bebaaec968659fb77bc1ea58c98015141c97fe45720d64
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ solar_geometry_calculation
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in solar_geometry_calculation.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010-2014 Tadatoshi Takahashi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # Solar Geometry Calculation
2
+
3
+ Calculate solar geometry, such as height or azimuth of the Sun for the purpose of obtaining information for solar panel installation.
4
+
5
+
6
+ ## Installation
7
+
8
+ Add to your Gemfile and run the `bundle` command to install it.
9
+
10
+ ```ruby
11
+ gem "solar_geometry_calculation"
12
+ ```
13
+
14
+ **Requires Ruby 2.0.0 or later.**
15
+
16
+
17
+ ## Usage
18
+
19
+ Instantiate SolarPositionCalculation class.
20
+
21
+ ```ruby
22
+ solar_position_calculation = SolarPositionCalculation.new(latitude: "45.5")
23
+ ```
24
+
25
+
26
+ ## Development
27
+
28
+ Questions or problems? Please post them on the [issue tracker](https://github.com/tadatoshi/solar_geometry_calculation/issues). You can contribute changes by forking the project and submitting a pull request. You can ensure the tests passing by running `bundle` and `rake`.
29
+
30
+ This gem is created by Tadatoshi Takahashi and is under the MIT License.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,9 @@
1
+ require 'bigdecimal'
2
+
3
+ module SolarGeometryCalculation
4
+
5
+ autoload :SolarPositionCalculation, 'solar_geometry_calculation/solar_position_calculation'
6
+ autoload :SolarTime, 'solar_geometry_calculation/solar_time'
7
+ autoload :CalculationHelper, 'solar_geometry_calculation/calculation_helper'
8
+
9
+ end
@@ -0,0 +1,45 @@
1
+ module SolarGeometryCalculation
2
+
3
+ module CalculationHelper
4
+
5
+ def day_of_the_year(year, month, day, hour = 0, minute = 0)
6
+ if hour == 0 && minute == 0
7
+ BigDecimal((Date.new(year.to_i, month.to_i, day.to_i).yday).to_s)
8
+ else
9
+ day_of_the_year_one_day_before = BigDecimal((Date.new(year.to_i, month.to_i, day.to_i).yday).to_s) - 1
10
+ decimal_hour_minute = BigDecimal(hour.to_s) + BigDecimal(minute.to_s) / 60
11
+ (day_of_the_year_one_day_before * 24 + decimal_hour_minute + 12) / 24
12
+ end
13
+ end
14
+
15
+ def degree_to_radian(degree)
16
+ degree * BigDecimal(Math::PI.to_s) / 180
17
+ end
18
+
19
+ def radian_to_degree(radian)
20
+ radian * 180 / BigDecimal(Math::PI.to_s)
21
+ end
22
+
23
+ def big_decimal_sin(angle_in_radian)
24
+ BigDecimal(Math.sin(angle_in_radian).to_s)
25
+ end
26
+
27
+ def big_decimal_cos(angle_in_radian)
28
+ BigDecimal(Math.cos(angle_in_radian).to_s)
29
+ end
30
+
31
+ def big_decimal_tan(angle_in_radian)
32
+ BigDecimal(Math.tan(angle_in_radian).to_s)
33
+ end
34
+
35
+ def big_decimal_asin(angle_in_radian)
36
+ BigDecimal(Math.asin(angle_in_radian).to_s)
37
+ end
38
+
39
+ def big_decimal_acos(angle_in_radian)
40
+ BigDecimal(Math.acos(angle_in_radian).to_s)
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,116 @@
1
+ require 'active_support/core_ext/object/blank'
2
+
3
+ module SolarGeometryCalculation
4
+
5
+ class SolarPositionCalculation
6
+ include CalculationHelper
7
+
8
+ attr_accessor :id, :latitude, :meridian, :longitude, :year, :month, :day, :hour, :minute, :surface_inclination, :surface_azimuth, :solar_time
9
+ attr_writer :timezone_identifier
10
+
11
+ def initialize(attributes = {})
12
+ attributes.each { |attribute_name, attribute_value| self.send("#{attribute_name}=".to_sym, attribute_value) }
13
+ get_solar_time
14
+ end
15
+
16
+
17
+ def declination(with_hour_and_minutes: true)
18
+ day_of_the_year = with_hour_and_minutes ? day_of_the_year(@solar_time.year, @solar_time.month, @solar_time.day, @solar_time.hour, @solar_time.minute) : day_of_the_year(@solar_time.year, @solar_time.month, @solar_time.day)
19
+ radian = degree_to_radian(BigDecimal("360") / BigDecimal("365") * (day_of_the_year + 284))
20
+ (23.45 * big_decimal_sin(radian)).round(2)
21
+ end
22
+
23
+ def hour_angle
24
+ if @solar_time.blank?
25
+ hour_for_calculation = BigDecimal(@hour.to_s)
26
+ minute_for_calculation = BigDecimal(@minute.to_s)
27
+ else
28
+ hour_for_calculation = @solar_time.hour
29
+ minute_for_calculation = @solar_time.minute
30
+ end
31
+
32
+ hour_with_minutes_in_digit = hour_for_calculation + minute_for_calculation.div(60, 2)
33
+
34
+ ((hour_with_minutes_in_digit - 12) * 15).round(2)
35
+ end
36
+
37
+ def solar_elevation
38
+ latitude_in_radian = degree_to_radian(BigDecimal(self.latitude.to_s))
39
+ declination_in_radian = degree_to_radian(self.declination)
40
+ hour_angle_in_radian = degree_to_radian(self.hour_angle)
41
+
42
+ sine_solar_elevation = big_decimal_sin(latitude_in_radian) * big_decimal_sin(declination_in_radian) +
43
+ big_decimal_cos(latitude_in_radian) * big_decimal_cos(declination_in_radian) * big_decimal_cos(hour_angle_in_radian)
44
+ radian_to_degree(big_decimal_asin(sine_solar_elevation)).round(2)
45
+ end
46
+
47
+ def solar_azimuth
48
+ declination_in_radian = degree_to_radian(self.declination)
49
+ hour_angle_in_radian = degree_to_radian(self.hour_angle)
50
+ solar_elevation_in_radian = degree_to_radian(self.solar_elevation)
51
+
52
+ sine_solar_azimuth = big_decimal_cos(declination_in_radian) * big_decimal_sin(hour_angle_in_radian) / big_decimal_cos(solar_elevation_in_radian)
53
+ radian_to_degree(big_decimal_asin(sine_solar_azimuth)).round(2)
54
+ end
55
+
56
+ def sunrise
57
+ sunrise_time_with_munutes_in_digit = BigDecimal((12 - (sunrise_sunset_base_angle / 15)).to_s)
58
+ sunrise_sunset_time(sunrise_time_with_munutes_in_digit)
59
+ end
60
+
61
+ def sunset
62
+ sunset_time_with_munutes_in_digit = BigDecimal((12 + (sunrise_sunset_base_angle / 15)).to_s)
63
+ sunrise_sunset_time(sunset_time_with_munutes_in_digit)
64
+ end
65
+
66
+ def angle_of_incidence
67
+ latitude_in_radian = degree_to_radian(BigDecimal(self.latitude.to_s))
68
+ declination_in_radian = degree_to_radian(self.declination)
69
+ hour_angle_in_radian = degree_to_radian(self.hour_angle)
70
+ surface_inclination_in_radian = degree_to_radian(BigDecimal(@surface_inclination.to_s))
71
+ surface_azimuth_in_radian = degree_to_radian(BigDecimal(@surface_azimuth.to_s))
72
+
73
+ first_value = big_decimal_sin(declination_in_radian) * big_decimal_sin(latitude_in_radian) * big_decimal_cos(surface_inclination_in_radian)
74
+ second_value = big_decimal_sin(declination_in_radian) * big_decimal_cos(latitude_in_radian) * big_decimal_sin(surface_inclination_in_radian) * big_decimal_cos(surface_azimuth_in_radian)
75
+ third_value = big_decimal_cos(declination_in_radian) * big_decimal_cos(latitude_in_radian) * big_decimal_cos(surface_inclination_in_radian) * big_decimal_cos(hour_angle_in_radian)
76
+ fourth_value = big_decimal_cos(declination_in_radian) * big_decimal_sin(latitude_in_radian) * big_decimal_sin(surface_inclination_in_radian) * big_decimal_cos(surface_azimuth_in_radian) * big_decimal_cos(hour_angle_in_radian)
77
+ fifth_value = big_decimal_cos(declination_in_radian) * big_decimal_sin(surface_inclination_in_radian) * big_decimal_sin(surface_azimuth_in_radian) * big_decimal_sin(hour_angle_in_radian)
78
+ cosine_of_angle_of_incidence = first_value - second_value + third_value + fourth_value + fifth_value
79
+
80
+ radian_to_degree(big_decimal_acos(cosine_of_angle_of_incidence)).round(2)
81
+ end
82
+
83
+ private
84
+ def get_solar_time
85
+ if @year.present? && @month.present? && @day.present?
86
+ if @address.present? && @place.present?
87
+ @solar_time = SolarTime.create_by_standard_time(BigDecimal(@year.to_s), BigDecimal(@month.to_s), BigDecimal(@day.to_s), BigDecimal(@hour.to_s), BigDecimal(@minute.to_s), @place.meridian, @place.longitude, @place.timezone_identifier)
88
+ elsif @meridian.present? && @longitude.present? && @timezone_identifier.present?
89
+ @solar_time = SolarTime.create_by_standard_time(BigDecimal(@year.to_s), BigDecimal(@month.to_s), BigDecimal(@day.to_s), BigDecimal(@hour.to_s), BigDecimal(@minute.to_s), @meridian, @longitude, @timezone_identifier)
90
+ end
91
+ end
92
+ end
93
+
94
+ def sunrise_sunset_base_angle
95
+ latitude_in_radian = degree_to_radian(BigDecimal(self.latitude.to_s))
96
+ declination_in_radian = degree_to_radian(self.declination(with_hour_and_minutes: false))
97
+
98
+ sunrise_sunset_base_angle_in_radian = big_decimal_acos(-(big_decimal_tan(latitude_in_radian) * big_decimal_tan(declination_in_radian)))
99
+ radian_to_degree(sunrise_sunset_base_angle_in_radian)
100
+ end
101
+
102
+ def sunrise_sunset_time(sunrise_or_sunset_time_with_munute_in_digit)
103
+ sunrise_or_sunset_hour, sunrise_or_sunset_minute_in_10_base = sunrise_or_sunset_time_with_munute_in_digit.divmod(1)
104
+ sunrise_or_sunset_solar_time = SolarTime.create_by_solar_time_values(@solar_time.year, @solar_time.month, @solar_time.day, sunrise_or_sunset_hour, (sunrise_or_sunset_minute_in_10_base * 60).round, @meridian, @longitude, @solar_time.timezone_identifier)
105
+ "#{sunrise_or_sunset_solar_time.standard_time_hour.to_i}:#{self.class.format_minute(sunrise_or_sunset_solar_time.standard_time_minute.to_i)}"
106
+ end
107
+
108
+ class << self
109
+ def format_minute(minute)
110
+ minute.to_s.length == 1 ? "0#{minute.to_s}" : minute.to_s
111
+ end
112
+ end
113
+
114
+ end
115
+
116
+ end
@@ -0,0 +1,206 @@
1
+ require 'tzinfo'
2
+ require 'active_support/core_ext/time/calculations'
3
+ require 'active_support/core_ext/date/calculations'
4
+
5
+ module SolarGeometryCalculation
6
+
7
+ class SolarTime
8
+
9
+ attr_accessor :year, :month, :day, :hour, :minute, :meridian, :longitude, :timezone_identifier
10
+ attr_writer :standard_time
11
+
12
+ # Methods for standard_time provided because the method to get minute for Time is min and that naming is not consistent with minute method for this class:
13
+ def standard_time_year
14
+ @standard_time.year
15
+ end
16
+
17
+ def standard_time_month
18
+ @standard_time.month
19
+ end
20
+
21
+ def standard_time_day
22
+ @standard_time.day
23
+ end
24
+
25
+ def standard_time_hour
26
+ @standard_time.hour
27
+ end
28
+
29
+ def standard_time_minute
30
+ @standard_time.min
31
+ end
32
+
33
+ class << self
34
+
35
+ # Moved from app/models/factories/solar_time_factory.rb because "rails server" in development environment cannot find this module.
36
+ # -- At least after I tried rack-mini-profiler. Even after I commented it out in Gemfile, the problem still persists.
37
+ def create_by_standard_time(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute, meridian, longitude, timezone_identifier)
38
+ solar_time = SolarTime.new
39
+
40
+ # Uses Time because DateTime doesn't take daylight savings time even with the one from Rails:
41
+ solar_time.standard_time = Time.new(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute)
42
+
43
+ solar_time.meridian = meridian
44
+ solar_time.longitude = longitude
45
+ solar_time.timezone_identifier = timezone_identifier
46
+
47
+ standard_time_year_without_offset, standard_time_month_without_offset, standard_time_day_without_offset, standard_time_hour_without_offset, standard_time_minute_without_offset =
48
+ SolarTime.standard_time_without_daylight_savings_time_offset(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute, meridian, longitude, timezone_identifier)
49
+
50
+ solar_time.year, solar_time.month, solar_time.day, solar_time.hour, solar_time.minute =
51
+ SolarTime.standard_time_without_daylight_savings_time_offset_to_solar_time(standard_time_year_without_offset, standard_time_month_without_offset, standard_time_day_without_offset, standard_time_hour_without_offset, standard_time_minute_without_offset, meridian, longitude, timezone_identifier)
52
+
53
+ solar_time
54
+ end
55
+
56
+ # Moved from app/models/factories/solar_time_factory.rb because "rails server" in development environment cannot find this module.
57
+ # -- At least after I tried rack-mini-profiler. Even after I commented it out in Gemfile, the problem still persists.
58
+ def create_by_solar_time_values(solar_time_year, solar_time_month, solar_time_day, solar_time_hour, solar_time_minute, meridian, longitude, timezone_identifier)
59
+ solar_time = SolarTime.new
60
+ solar_time.year = solar_time_year
61
+ solar_time.month = solar_time_month
62
+ solar_time.day = solar_time_day
63
+ solar_time.hour = solar_time_hour
64
+ solar_time.minute = solar_time_minute
65
+ solar_time.meridian = meridian
66
+ solar_time.longitude = longitude
67
+ solar_time.timezone_identifier = timezone_identifier
68
+
69
+ standard_time_year_without_offset, standard_time_month_without_offset, standard_time_day_without_offset, standard_time_hour_without_offset, standard_time_minute_without_offset =
70
+ SolarTime.solar_time_to_standard_time_without_daylight_savings_time_offset(solar_time.year, solar_time.month, solar_time.day, solar_time.hour, solar_time.minute, meridian, longitude, timezone_identifier)
71
+
72
+ standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute =
73
+ SolarTime.standard_time_with_daylight_savings_time_offset(standard_time_year_without_offset, standard_time_month_without_offset, standard_time_day_without_offset, standard_time_hour_without_offset, standard_time_minute_without_offset, meridian, longitude, timezone_identifier)
74
+
75
+ # Uses Time because DateTime doesn't take daylight savings time even with the one from Rails:
76
+ solar_time.standard_time = Time.new(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute)
77
+
78
+ solar_time
79
+ end
80
+
81
+ def standard_time_without_daylight_savings_time_offset(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute, meridian, longitude, timezone_identifier)
82
+ NegativeDaylightSavingsTimeConverter.new.convert(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute, meridian, longitude, timezone_identifier)
83
+ end
84
+
85
+ def standard_time_with_daylight_savings_time_offset(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute, meridian, longitude, timezone_identifier)
86
+ PositiveDaylightSavingsTimeConverter.new.convert(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute, meridian, longitude, timezone_identifier)
87
+ end
88
+
89
+ def standard_time_without_daylight_savings_time_offset_to_solar_time(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute, meridian, longitude, timezone_identifier)
90
+ ToSolarTimeConverter.new.convert(standard_time_year, standard_time_month, standard_time_day, standard_time_hour, standard_time_minute, meridian, longitude, timezone_identifier)
91
+ end
92
+
93
+ def solar_time_to_standard_time_without_daylight_savings_time_offset(solar_time_year, solar_time_month, solar_time_day, solar_time_hour, solar_time_minute, meridian, longitude, timezone_identifier)
94
+ FromSolarTimeConverter.new.convert(solar_time_year, solar_time_month, solar_time_day, solar_time_hour, solar_time_minute, meridian, longitude, timezone_identifier)
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
101
+ module TimeConverter
102
+
103
+ def convert(year, month, day, hour, minute, meridian, longitude, timezone_identifier)
104
+
105
+ # Creating Time object as UTC since Time.local gets Time object in machine's timezone.
106
+ time = Time.utc(year, month, day, hour, minute)
107
+
108
+ time = convert_by_offset(time, meridian, longitude, timezone_identifier)
109
+
110
+ [BigDecimal(time.year.to_s), BigDecimal(time.month.to_s), BigDecimal(time.day.to_s), BigDecimal(time.hour.to_s), BigDecimal(time.min.to_s)]
111
+
112
+ end
113
+
114
+ private
115
+ def convert_by_offset(time, meridian, longitude, timezone_identifier)
116
+ raise "must be implemented by a class"
117
+ end
118
+
119
+ def target_time(time, offset_in_seconds)
120
+ raise "must be implemented by a class"
121
+ end
122
+
123
+ end
124
+
125
+ module DaylightSavingsTimeConverter
126
+ include TimeConverter
127
+
128
+ private
129
+ def convert_by_offset(time, meridian, longitude, timezone_identifier)
130
+ timezone = TZInfo::Timezone.get(timezone_identifier)
131
+ timezone_period = timezone.period_for_local(time, true)
132
+
133
+ if timezone_period.dst?
134
+ time = target_time(time, timezone_period.std_offset)
135
+ end
136
+
137
+ time
138
+ end
139
+
140
+ def target_time(time, offset_in_seconds)
141
+ raise "must be implemented by a class"
142
+ end
143
+
144
+ end
145
+
146
+ module SolarTimeConverter
147
+ include TimeConverter
148
+ include SolarGeometryCalculation::CalculationHelper
149
+
150
+ private
151
+ def convert_by_offset(time, meridian, longitude, timezone_identifier)
152
+ minutes_difference = minutes_difference(time.year, time.month, time.day, meridian, longitude)
153
+ time = target_time(time, minutes_difference * 60)
154
+ end
155
+
156
+ def target_time(time, offset_in_seconds)
157
+ raise "must be implemented by a class"
158
+ end
159
+
160
+ def minutes_difference(year, month, day, meridian, longitude)
161
+ -(4 * (BigDecimal(meridian.to_s) - BigDecimal(longitude.to_s))) + equation_of_time(year, month, day).round
162
+ end
163
+
164
+ def equation_of_time(year, month, day)
165
+ b_in_radian = degree_to_radian((day_of_the_year(year, month, day) - 1) * BigDecimal("360") / BigDecimal("365"))
166
+
167
+ BigDecimal("229.2") * (BigDecimal("0.000075") + BigDecimal("0.001868") * big_decimal_cos(b_in_radian) - BigDecimal("0.032077") * big_decimal_sin(b_in_radian) - BigDecimal("0.014615") * big_decimal_cos(2 * b_in_radian) - BigDecimal("0.04089") * big_decimal_sin(2 * b_in_radian))
168
+ end
169
+
170
+ end
171
+
172
+ module OffsetAdvanceConverter
173
+ private
174
+ def target_time(time, offset_in_seconds)
175
+ time.advance(seconds: offset_in_seconds)
176
+ end
177
+ end
178
+
179
+ module OffsetSubtractionConverter
180
+ private
181
+ def target_time(time, offset_in_seconds)
182
+ time.ago(offset_in_seconds)
183
+ end
184
+ end
185
+
186
+ class NegativeDaylightSavingsTimeConverter
187
+ include DaylightSavingsTimeConverter
188
+ include OffsetSubtractionConverter
189
+ end
190
+
191
+ class PositiveDaylightSavingsTimeConverter
192
+ include DaylightSavingsTimeConverter
193
+ include OffsetAdvanceConverter
194
+ end
195
+
196
+ class ToSolarTimeConverter
197
+ include SolarTimeConverter
198
+ include OffsetAdvanceConverter
199
+ end
200
+
201
+ class FromSolarTimeConverter
202
+ include SolarTimeConverter
203
+ include OffsetSubtractionConverter
204
+ end
205
+
206
+ end
@@ -0,0 +1,3 @@
1
+ module SolarGeometryCalculation
2
+ VERSION = "0.1.4"
3
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "solar_geometry_calculation/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "solar_geometry_calculation"
7
+ s.version = SolarGeometryCalculation::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Tadatoshi Takahashi"]
10
+ s.email = ["tadatoshi@gmail.com"]
11
+ s.homepage = "https://github.com/tadatoshi/solar_geometry_calculation"
12
+ s.summary = %q{Performs calculation for solar geometry}
13
+ s.description = %q{Mathematical part of obtaining solar geometry information}
14
+
15
+ s.rubyforge_project = "solar_geometry_calculation"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency 'tzinfo'
23
+ s.add_dependency 'activesupport', ">= 4.1.1"
24
+
25
+ s.add_development_dependency "rspec"
26
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe SolarGeometryCalculation::CalculationHelper do
4
+
5
+ class CalculationHelperExtender; extend SolarGeometryCalculation::CalculationHelper; end
6
+
7
+ context "Day of the year" do
8
+
9
+ it "should calculate the day of the year" do
10
+
11
+ CalculationHelperExtender.day_of_the_year(2012, 2, 19).should == 50
12
+
13
+ end
14
+
15
+ it "should calculate the day of the year taking into account of the time in the day" do
16
+
17
+ CalculationHelperExtender.day_of_the_year(2012, 2, 19, 6, 50).should be_within(0.01).of(49.78)
18
+ CalculationHelperExtender.day_of_the_year(2012, 2, 19, 17, 10).should be_within(0.01).of(50.22)
19
+
20
+ end
21
+
22
+ end
23
+
24
+ context "Radian degree" do
25
+
26
+ it "should convert a degree to Radian because Math.sin expects Radian" do
27
+
28
+ CalculationHelperExtender.degree_to_radian(1).should be_within(0.0001).of(0.0175)
29
+
30
+ end
31
+
32
+ it "should convert radian to degree" do
33
+
34
+ CalculationHelperExtender.radian_to_degree(1).should be_within(0.0001).of(57.2958)
35
+
36
+ end
37
+
38
+ end
39
+
40
+ end
@@ -0,0 +1,176 @@
1
+ require 'spec_helper'
2
+
3
+ describe SolarGeometryCalculation::SolarPositionCalculation do
4
+
5
+ context "declination" do
6
+
7
+ it "should calculate declination" do
8
+
9
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 9, :day => 21, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
10
+ solar_position_calculation_1.declination.should == -0.19
11
+
12
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 1, :day => 21, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
13
+ solar_position_calculation_2.declination.should == -20.14
14
+
15
+ solar_position_calculation_3 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 7, :day => 24, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
16
+ solar_position_calculation_3.declination.should == 19.83
17
+
18
+ end
19
+
20
+ context "(solar energy and applications course - homework 2)" do
21
+
22
+ it "should calculate declination with latitude 45 degrees 28 minutes" do
23
+
24
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2012, :month => 2, :day => 19, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
25
+ solar_position_calculation_1.declination.should be_within(0.1).of(-11.95)
26
+
27
+ # At sunrise 6:50 (6.83h):
28
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2012, :month => 2, :day => 19, :hour => 6, :minute => 50, :surface_inclination => "0", :surface_azimuth => "0")
29
+ solar_position_calculation_2.declination.should be_within(0.1).of(-12.02)
30
+
31
+ # At sunset 17:10 (17.17h):
32
+ solar_position_calculation_3 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 2, :day => 19, :hour => 17, :minute => 10, :surface_inclination => "0", :surface_azimuth => "0")
33
+ solar_position_calculation_3.declination.should be_within(0.1).of(-11.87)
34
+
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ context "hour angle" do
42
+
43
+ it "should calculate hour angle" do
44
+
45
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 9, :day => 21, :hour => 10, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
46
+ solar_position_calculation_1.hour_angle.should be_within(0.1).of(-42.03)
47
+
48
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 1, :day => 21, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
49
+ solar_position_calculation_2.hour_angle.should be_within(0.15).of(-1.40)
50
+
51
+ solar_position_calculation_3 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 7, :day => 24, :hour => 13, :minute => 15, :surface_inclination => "0", :surface_azimuth => "0")
52
+ solar_position_calculation_3.hour_angle.should be_within(0.1).of(3.37)
53
+
54
+ end
55
+
56
+ end
57
+
58
+ context "height of the sun" do
59
+
60
+ it "should calculate solar elevation" do
61
+
62
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 9, :day => 21, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
63
+ solar_position_calculation_1.solar_elevation.should be_within(0.1).of(43.09)
64
+
65
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 1, :day => 21, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
66
+ solar_position_calculation_2.solar_elevation.should == 24.35
67
+
68
+ solar_position_calculation_3 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.5", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 7, :day => 24, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
69
+ solar_position_calculation_3.solar_elevation.should be_within(0.1).of(61.37)
70
+
71
+ end
72
+
73
+ end
74
+
75
+ context "Solar azimuth" do
76
+
77
+ it "should calculate solar azimuth" do
78
+
79
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.46", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 9, :day => 21, :hour => 10, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
80
+ solar_position_calculation_1.solar_azimuth.should be_within(0.1).of(-51.58)
81
+
82
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.46", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 1, :day => 21, :hour => 10, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
83
+ solar_position_calculation_2.solar_azimuth.should be_within(0.1).of(-31.03)
84
+
85
+ solar_position_calculation_3 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.46", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 7, :day => 24, :hour => 10, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
86
+ solar_position_calculation_3.solar_azimuth.should be_within(0.1).of(-70.83)
87
+
88
+ end
89
+
90
+ end
91
+
92
+ context "Sunrise" do
93
+
94
+ it "should calculate sunrise" do
95
+
96
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.46", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 9, :day => 21, :hour => 10, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
97
+ solar_position_calculation_1.sunrise.should == "6:49"
98
+
99
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.46", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 1, :day => 21, :hour => 10, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
100
+ solar_position_calculation_2.sunrise.should == "7:34"
101
+
102
+ solar_position_calculation_3 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.46", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 7, :day => 24, :hour => 10, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
103
+ solar_position_calculation_3.sunrise.should == "5:36"
104
+
105
+ end
106
+
107
+ it "should calculate the same sunrise time throughout the same day" do
108
+
109
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.46", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 9, :day => 21, :hour => 3, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
110
+ solar_position_calculation_1.sunrise.should == "6:49"
111
+
112
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.46", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 9, :day => 21, :hour => 21, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
113
+ solar_position_calculation_2.sunrise.should == "6:49"
114
+
115
+ solar_position_calculation_1.sunrise.should == solar_position_calculation_2.sunrise
116
+
117
+ end
118
+
119
+ context "(solar energy and applications course - homework 2)" do
120
+
121
+ it "should calculate sunrise with latitude 45 degrees 28 minutes" do
122
+
123
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2012, :month => 2, :day => 19, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
124
+ solar_position_calculation_1.sunrise.should == "6:59"
125
+
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+
132
+ context "Sunset" do
133
+
134
+ it "should calculate the same sunset time throughout the same day" do
135
+
136
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2012, :month => 2, :day => 19, :hour => 2, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
137
+ solar_position_calculation_1.sunset.should == "17:19"
138
+
139
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2012, :month => 2, :day => 19, :hour => 22, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
140
+ solar_position_calculation_2.sunset.should == "17:19"
141
+
142
+ solar_position_calculation_1.sunset.should == solar_position_calculation_2.sunset
143
+
144
+ end
145
+
146
+ context "(solar energy and applications course - homework 2)" do
147
+
148
+ it "should calculate sunset with latitude 45 degrees 28 minutes" do
149
+
150
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2012, :month => 2, :day => 19, :hour => 12, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
151
+ solar_position_calculation_1.sunset.should == "17:19"
152
+
153
+ end
154
+
155
+ end
156
+
157
+ end
158
+
159
+ context "Angle of incidence" do
160
+
161
+ it "should calculate angle of incidence" do
162
+
163
+ solar_position_calculation_1 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 9, :day => 21, :hour => 10, :minute => 0, :surface_inclination => "0", :surface_azimuth => "0")
164
+ solar_position_calculation_1.angle_of_incidence.should be_within(0.1).of(58.73)
165
+
166
+ solar_position_calculation_2 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 1, :day => 21, :hour => 10, :minute => 0, :surface_inclination => "70", :surface_azimuth => "-45")
167
+ solar_position_calculation_2.angle_of_incidence.should be_within(0.1).of(13.28)
168
+
169
+ solar_position_calculation_3 = SolarGeometryCalculation::SolarPositionCalculation.new(:latitude => "45.47", :meridian => "-75", :longitude => "-73.75", :timezone_identifier => "America/Montreal", :year => 2010, :month => 7, :day => 24, :hour => 10, :minute => 0, :surface_inclination => "70", :surface_azimuth => "-45")
170
+ solar_position_calculation_3.angle_of_incidence.should == 32.78
171
+
172
+ end
173
+
174
+ end
175
+
176
+ end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ describe SolarGeometryCalculation::SolarTime do
4
+
5
+ context "Factory" do
6
+
7
+ it "should create an instance based on the standard time" do
8
+
9
+ solar_time = SolarGeometryCalculation::SolarTime.create_by_standard_time(2010, 9, 21, 12, 0, -75, -73.75, "America/Los_Angeles")
10
+
11
+ solar_time.standard_time_year.should == 2010
12
+ solar_time.standard_time_month.should == 9
13
+ solar_time.standard_time_day.should == 21
14
+ solar_time.standard_time_hour.should == 12
15
+ solar_time.standard_time_minute.should == 0
16
+
17
+ solar_time.year.should == 2010
18
+ solar_time.month.should == 9
19
+ solar_time.day.should == 21
20
+ solar_time.hour.should == 11
21
+ solar_time.minute.should == 12
22
+
23
+ end
24
+
25
+ it "should create an instance based on the solar time values" do
26
+
27
+ solar_time = SolarGeometryCalculation::SolarTime.create_by_solar_time_values(2010, 9, 21, 11, 12, -75, -73.75, "America/Los_Angeles")
28
+
29
+ solar_time.year.should == 2010
30
+ solar_time.month.should == 9
31
+ solar_time.day.should == 21
32
+ solar_time.hour.should == 11
33
+ solar_time.minute.should == 12
34
+
35
+ solar_time.standard_time_year.should == 2010
36
+ solar_time.standard_time_month.should == 9
37
+ solar_time.standard_time_day.should == 21
38
+ solar_time.standard_time_hour.should == 12
39
+ solar_time.standard_time_minute.should == 0
40
+
41
+ end
42
+
43
+ end
44
+
45
+ context "helper" do
46
+
47
+ it "should get the time without daylight saving time offset from the time with daylight saving time offset" do
48
+
49
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset, 2012, 07, 13, 10, 12, -75, -78.63, "America/Los_Angeles").should == [2012, 7, 13, 9, 12]
50
+
51
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset, 2012, 8, 1, 0, 30, -75, -78.63, "America/Los_Angeles").should == [2012, 7, 31, 23, 30]
52
+
53
+ end
54
+
55
+ it "should get the time with daylight saving time offset from the time without daylight saving time offset" do
56
+
57
+ SolarGeometryCalculation::SolarTime.send(:standard_time_with_daylight_savings_time_offset, 2012, 07, 13, 9, 12, -75, -78.63, "America/Los_Angeles").should == [2012, 7, 13, 10, 12]
58
+
59
+ SolarGeometryCalculation::SolarTime.send(:standard_time_with_daylight_savings_time_offset, 2012, 7, 31, 23, 30, -75, -78.63, "America/Los_Angeles").should == [2012, 8, 1, 0, 30]
60
+
61
+ end
62
+
63
+ it "should calculate solar time" do
64
+
65
+ # Data for Toronto:
66
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset_to_solar_time, 2010, 2, 19, 7, 14, -75, -78.63, "America/Los_Angeles").should == [2010, 2, 19, 6, 45]
67
+
68
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset_to_solar_time, 2010, 9, 21, 10, 0, -75, -73.55, "America/Los_Angeles").should == [2010, 9, 21, 10, 12]
69
+
70
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset_to_solar_time, 2010, 9, 21, 10, 0, BigDecimal("-75"), BigDecimal("-73.55"), "America/Los_Angeles").should == [2010, 9, 21, 10, 12]
71
+
72
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset_to_solar_time, 2010, 9, 21, 10, 0, -75, -78.30, "America/Los_Angeles").should == [2010, 9, 21, 9, 53]
73
+
74
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset_to_solar_time, 2010, 8, 1, 0, 0, -75, -78.30, "America/Los_Angeles").should == [2010, 7, 31, 23, 39]
75
+
76
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset_to_solar_time, 2010, 7, 31, 23, 59, -75, -78.30, "America/Los_Angeles").should == [2010, 7, 31, 23, 38]
77
+
78
+ SolarGeometryCalculation::SolarTime.send(:standard_time_without_daylight_savings_time_offset_to_solar_time, 2010, 9, 21, 12, 0, -75, -73.75, "America/Los_Angeles").should == [2010, 9, 21, 12, 12]
79
+
80
+ end
81
+
82
+ end
83
+
84
+ context "(solar energy and applications course - homework 2)" do
85
+
86
+ it "should calculate average solar hour" do
87
+
88
+ solar_time_1 = SolarGeometryCalculation::SolarTime.create_by_standard_time(2012, 02, 19, 12, 30, -75, -73.75, "America/Los_Angeles")
89
+ solar_time_1.year.should == 2012
90
+ solar_time_1.month.should == 2
91
+ solar_time_1.day.should == 19
92
+ solar_time_1.hour.should == 12
93
+ solar_time_1.minute.should be_within(1).of(21)
94
+
95
+ solar_time_2 = SolarGeometryCalculation::SolarTime.create_by_standard_time(2012, 02, 19, 12, 30, BigDecimal("-75"), BigDecimal("-73.75"), "America/Los_Angeles")
96
+ solar_time_1.year.should == 2012
97
+ solar_time_1.month.should == 2
98
+ solar_time_1.day.should == 19
99
+ solar_time_1.hour.should == 12
100
+ solar_time_1.minute.should be_within(1).of(21)
101
+
102
+ end
103
+
104
+ end
105
+
106
+ context "converter" do
107
+
108
+ class TempSolarTimeConverter; include SolarGeometryCalculation::SolarTimeConverter; end
109
+
110
+ it "should calculate the adjustment by the Equation of time" do
111
+
112
+ TempSolarTimeConverter.new.send(:equation_of_time, 2012, 02, 19).should be_within(0.01).of(-14.11)
113
+
114
+ end
115
+
116
+ end
117
+
118
+ end
@@ -0,0 +1,2 @@
1
+ require 'solar_geometry_calculation'
2
+
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: solar_geometry_calculation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.4
5
+ platform: ruby
6
+ authors:
7
+ - Tadatoshi Takahashi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tzinfo
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 4.1.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 4.1.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Mathematical part of obtaining solar geometry information
56
+ email:
57
+ - tadatoshi@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".ruby-gemset"
65
+ - ".ruby-version"
66
+ - Gemfile
67
+ - LICENSE
68
+ - README.md
69
+ - Rakefile
70
+ - lib/solar_geometry_calculation.rb
71
+ - lib/solar_geometry_calculation/calculation_helper.rb
72
+ - lib/solar_geometry_calculation/solar_position_calculation.rb
73
+ - lib/solar_geometry_calculation/solar_time.rb
74
+ - lib/solar_geometry_calculation/version.rb
75
+ - solar_geometry_calculation.gemspec
76
+ - spec/solar_geometry_calculation/calculation_helper_spec.rb
77
+ - spec/solar_geometry_calculation/solar_position_calculation_spec.rb
78
+ - spec/solar_geometry_calculation/solar_time_spec.rb
79
+ - spec/spec_helper.rb
80
+ homepage: https://github.com/tadatoshi/solar_geometry_calculation
81
+ licenses: []
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project: solar_geometry_calculation
99
+ rubygems_version: 2.2.2
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Performs calculation for solar geometry
103
+ test_files:
104
+ - spec/solar_geometry_calculation/calculation_helper_spec.rb
105
+ - spec/solar_geometry_calculation/solar_position_calculation_spec.rb
106
+ - spec/solar_geometry_calculation/solar_time_spec.rb
107
+ - spec/spec_helper.rb