libgeo 0.1.0
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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +13 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +1 -0
- data/lib/libgeo.rb +24 -0
- data/lib/libgeo/coordinate.rb +187 -0
- data/lib/libgeo/coordinate/class_methods.rb +243 -0
- data/lib/libgeo/coordinate/hemi_helpers.rb +80 -0
- data/lib/libgeo/coordinate/presenters.rb +67 -0
- data/lib/libgeo/formatter.rb +61 -0
- data/lib/libgeo/formatter/compiler.rb +128 -0
- data/lib/libgeo/formatter/evaluator.rb +53 -0
- data/lib/libgeo/latitude.rb +36 -0
- data/lib/libgeo/longitude.rb +48 -0
- data/lib/libgeo/version.rb +3 -0
- data/libgeo.gemspec +23 -0
- data/spec/shared_examples/coordinate_attrs.rb +74 -0
- data/spec/shared_examples/coordinate_inputs.rb +127 -0
- data/spec/shared_examples/coordinate_presenters.rb +16 -0
- data/spec/shared_examples/coordinate_validation.rb +89 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/unit/libgeo/coordinate_spec.rb +82 -0
- data/spec/unit/libgeo/formatter/compiler_spec.rb +76 -0
- data/spec/unit/libgeo/formatter/evaluator_spec.rb +69 -0
- data/spec/unit/libgeo/formatter_spec.rb +34 -0
- data/spec/unit/libgeo/latitude_spec.rb +378 -0
- data/spec/unit/libgeo/longitude_spec.rb +377 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 795971339fd7c0de9304b188ec33f51057cd4adb
|
4
|
+
data.tar.gz: 27003885f254776998b25dd67b6aa41d84c24270
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ab071931a81588e30804c7f008d77eb8bb49c9abeaae7b2e155a99a3e76aa6e12a97eedfa10bfc35a83582f45e8426ff7041267594bd400442c276b96aea0027
|
7
|
+
data.tar.gz: 9367c5f271715e96b56de6033d41b18ed918e0f874baeaa23cce61cbca2fb113d803e675d61c4135b385bf2b73f8299450fc8a72a76371632b6781501eb91126
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Andrey Savchenko
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Libgeo
|
2
|
+
|
3
|
+
Collection of geographical primitives
|
4
|
+
|
5
|
+
- [](https://travis-ci.org/Ptico/libgeo)
|
6
|
+
- [](https://codeclimate.com/github/Ptico/libgeo)
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'libgeo'
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install libgeo
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
### Latitude/Longitude
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
lng = Longitude.decimal(39.342679)
|
28
|
+
|
29
|
+
lng.hemisphere # => :E
|
30
|
+
lng.degrees # => 39
|
31
|
+
lng.minutes # => 20
|
32
|
+
lng.seconds # => 33.6444
|
33
|
+
|
34
|
+
lng.western? # => false
|
35
|
+
lng.eastern? # => true
|
36
|
+
|
37
|
+
lng.to_s # => '39°20′33.6444″E'
|
38
|
+
lng.to_nmea # => '03920.56074,E'
|
39
|
+
|
40
|
+
lng.western!
|
41
|
+
lng.hemisphere # => :W
|
42
|
+
|
43
|
+
ltt = Latitude.nmea('03920.56074,N')
|
44
|
+
|
45
|
+
ltt.to_s # => '39°20′33.6444″N'
|
46
|
+
|
47
|
+
ltt_dms = Latitude.dms('39°20′33.6444″N')
|
48
|
+
|
49
|
+
ltt_dms.to_s # => '39°20′33.6444″N'
|
50
|
+
ltt_dms.to_nmea # => '3920.56074,N'
|
51
|
+
|
52
|
+
```
|
53
|
+
|
54
|
+
## Contributing
|
55
|
+
|
56
|
+
1. Fork it ( http://github.com/Ptico/libgeo/fork )
|
57
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
58
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
59
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
60
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/libgeo.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require 'libgeo/version'
|
6
|
+
require 'libgeo/formatter'
|
7
|
+
|
8
|
+
module Libgeo
|
9
|
+
|
10
|
+
NORTH = :N
|
11
|
+
SOUTH = :S
|
12
|
+
WEST = :W
|
13
|
+
EAST = :E
|
14
|
+
|
15
|
+
module Format
|
16
|
+
DMS = Formatter.new('%2d°%2m′%S″%H')
|
17
|
+
NMEA_LAT = Formatter.new('%2d%2M,%H')
|
18
|
+
NMEA_LON = Formatter.new('%3d%2M,%H')
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'libgeo/coordinate'
|
23
|
+
require 'libgeo/latitude'
|
24
|
+
require 'libgeo/longitude'
|
@@ -0,0 +1,187 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'bigdecimal'
|
4
|
+
require 'bigdecimal/util'
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
require 'libgeo/coordinate/class_methods'
|
8
|
+
require 'libgeo/coordinate/presenters'
|
9
|
+
require 'libgeo/coordinate/hemi_helpers'
|
10
|
+
|
11
|
+
module Libgeo
|
12
|
+
##
|
13
|
+
# Class: basic coordinate
|
14
|
+
#
|
15
|
+
# Provides basic functionality for Latitude and Longitude.
|
16
|
+
# In some cases can be used as standalone class.
|
17
|
+
#
|
18
|
+
class Coordinate
|
19
|
+
extend ClassMethods
|
20
|
+
include Presenters
|
21
|
+
include HemiHelpers
|
22
|
+
|
23
|
+
HEMISPHERES = Set.new([:N, :E, :S, :W]).freeze
|
24
|
+
NEGATIVE_HEMISPHERES = Set.new([:S, :W]).freeze
|
25
|
+
|
26
|
+
attr_accessor :degrees, :minutes, :seconds, :hemisphere
|
27
|
+
|
28
|
+
##
|
29
|
+
# Shortcuts
|
30
|
+
alias :hemi :hemisphere
|
31
|
+
alias :deg :degrees
|
32
|
+
alias :mins :minutes
|
33
|
+
alias :secs :seconds
|
34
|
+
|
35
|
+
##
|
36
|
+
# Coordinate type
|
37
|
+
#
|
38
|
+
def type
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Check coordinates equality
|
44
|
+
#
|
45
|
+
# Returns: {Boolean} true if coordinates are same
|
46
|
+
#
|
47
|
+
def eql?(other)
|
48
|
+
degrees.eql?(other.degrees) &&
|
49
|
+
minutes.eql?(other.minutes) &&
|
50
|
+
seconds.eql?(other.seconds) &&
|
51
|
+
hemisphere.eql?(other.hemisphere)
|
52
|
+
end
|
53
|
+
alias_method :==, :eql?
|
54
|
+
|
55
|
+
##
|
56
|
+
# Decimal minutes with seconds included
|
57
|
+
#
|
58
|
+
# Returns: {Float} minutes
|
59
|
+
#
|
60
|
+
def minutes_only
|
61
|
+
(minutes + seconds.to_d / 60).to_f
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Hemisphere validator
|
66
|
+
#
|
67
|
+
# Validates if given value can be assigned to Coordinate
|
68
|
+
# or if current hemi is valid
|
69
|
+
#
|
70
|
+
# Params:
|
71
|
+
# - value hemisphere value to check (optional)
|
72
|
+
#
|
73
|
+
# Returns: {Boolean}
|
74
|
+
#
|
75
|
+
def valid_hemisphere?(value=nil)
|
76
|
+
self.class::HEMISPHERES.include?(value || hemisphere)
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Check if current hemisphere negative
|
81
|
+
#
|
82
|
+
# Returns: {Boolean}
|
83
|
+
#
|
84
|
+
def negative_hemisphere?
|
85
|
+
if valid_hemisphere?
|
86
|
+
NEGATIVE_HEMISPHERES.include?(hemi)
|
87
|
+
elsif direction
|
88
|
+
:< == direction
|
89
|
+
else
|
90
|
+
false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Freeze all the things!
|
96
|
+
#
|
97
|
+
def freeze
|
98
|
+
normalize_data
|
99
|
+
|
100
|
+
[@degrees, @minutes, @seconds, @hemisphere, @direction].each { |ivar| ivar.freeze }
|
101
|
+
|
102
|
+
super
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
attr_reader :direction
|
108
|
+
|
109
|
+
##
|
110
|
+
# Constructor:
|
111
|
+
#
|
112
|
+
# Params:
|
113
|
+
# - hemi_or_dir {Symbol|String} hemisphere value or direction
|
114
|
+
# - degrees {Fixnum} degrees part
|
115
|
+
# - minutes {Fixnum} minutes part
|
116
|
+
# - seconds {Float} seconds part
|
117
|
+
#
|
118
|
+
def initialize(hemi_or_dir, degrees, minutes, seconds)
|
119
|
+
@degrees = degrees
|
120
|
+
@minutes = minutes
|
121
|
+
@seconds = seconds
|
122
|
+
|
123
|
+
if [:<, :>].include?(hemi_or_dir)
|
124
|
+
@direction = hemi_or_dir
|
125
|
+
else
|
126
|
+
@hemisphere = hemi_or_dir
|
127
|
+
end
|
128
|
+
|
129
|
+
normalize_data
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# Private: make sure that all attrs has right types
|
134
|
+
#
|
135
|
+
def normalize_data
|
136
|
+
normalize_hemi
|
137
|
+
normalize_values
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# Private: detect and assign hemisphere value
|
142
|
+
#
|
143
|
+
# Check if hemisphere can be properly detected
|
144
|
+
# and assign it
|
145
|
+
#
|
146
|
+
def normalize_hemi
|
147
|
+
if hemisphere
|
148
|
+
normalize_hemi_wording
|
149
|
+
elsif direction
|
150
|
+
get_hemi_from_direction
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
##
|
155
|
+
# Private: normalize hemisphere value
|
156
|
+
#
|
157
|
+
# If hemisphere have incorrect value - lookup for
|
158
|
+
# available correction from dictionary
|
159
|
+
#
|
160
|
+
def normalize_hemi_wording
|
161
|
+
unless valid_hemisphere?
|
162
|
+
self.class::CORRECTIONS.each_pair do |v, c|
|
163
|
+
@hemisphere = v if c.include?(hemisphere)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
##
|
169
|
+
# Private: get hemisphere value from direction
|
170
|
+
#
|
171
|
+
# Mostly for plain Coordinate instance (not Latitude or Longitude)
|
172
|
+
#
|
173
|
+
def get_hemi_from_direction
|
174
|
+
@hemisphere = self.class::DIRECTIONS[direction]
|
175
|
+
end
|
176
|
+
|
177
|
+
##
|
178
|
+
# Private: normalize attribute types
|
179
|
+
#
|
180
|
+
def normalize_values
|
181
|
+
@degrees = degrees.to_i
|
182
|
+
@minutes = minutes.to_i
|
183
|
+
@seconds = seconds.to_f
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Libgeo
|
4
|
+
class Coordinate
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
DMS_SEPARATORS = /['°′"`\ \,]+/.freeze
|
8
|
+
NMEA_SEPARATORS = /(,\ |,|\ )/.freeze
|
9
|
+
|
10
|
+
##
|
11
|
+
# Factory: make a coordinate from decimal value
|
12
|
+
#
|
13
|
+
# Examples:
|
14
|
+
#
|
15
|
+
# Longitude.decimal(39.342679) # => #<Longitude hemisphere=E degrees=39 minutes=20 ...
|
16
|
+
#
|
17
|
+
# Params:
|
18
|
+
# - value {Float} decimal coordinate
|
19
|
+
#
|
20
|
+
# Returns: {Latitude|Longitude|Coordinate} instance
|
21
|
+
#
|
22
|
+
def decimal(value)
|
23
|
+
minutes = value.abs.to_d.modulo(1) * 60 # extract minutes from decimal degrees
|
24
|
+
create(dir_from(value), value.abs.to_i, *min_with_sec(minutes))
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Factory: make a coordinate from nmea input
|
29
|
+
#
|
30
|
+
# Examples:
|
31
|
+
#
|
32
|
+
# Longitude.nmea('03920.56074,E') # => #<Longitude hemisphere=E degrees=39 minutes=20 ...
|
33
|
+
#
|
34
|
+
# Params:
|
35
|
+
# - input {String} nmea coordinate
|
36
|
+
#
|
37
|
+
# Returns: {Latitude|Longitude|Coordinate} instance
|
38
|
+
#
|
39
|
+
def nmea(input)
|
40
|
+
value, hemi = prepare_nmea(input)
|
41
|
+
|
42
|
+
value = value.to_f
|
43
|
+
|
44
|
+
direction = dir_from_values(value, hemi)
|
45
|
+
|
46
|
+
degrees = value.to_i.abs / 100
|
47
|
+
|
48
|
+
create(direction, degrees, *min_with_sec_nmea(value.abs), hemi)
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Factory: make a coordinate from dms value
|
53
|
+
#
|
54
|
+
# Examples:
|
55
|
+
#
|
56
|
+
# Longitude.dms("58°39′13.5 S") # => #<Longitude hemisphere=S degrees=58 minutes=39 ...
|
57
|
+
#
|
58
|
+
# Params:
|
59
|
+
# - inputs {String} dms coordinate
|
60
|
+
#
|
61
|
+
# Returns: {Latitude|Longitude|Coordinate} instance
|
62
|
+
#
|
63
|
+
def dms(input)
|
64
|
+
string_values = input.split(DMS_SEPARATORS)
|
65
|
+
|
66
|
+
degrees = string_values[0].to_i # get degrees and minutes
|
67
|
+
minutes = (string_values[1] || 0).to_i
|
68
|
+
seconds = (string_values[2] || 0).to_f
|
69
|
+
hemi = string_values[3]
|
70
|
+
|
71
|
+
direction = dir_from_values(degrees, hemi)
|
72
|
+
|
73
|
+
create(direction, degrees.abs, minutes, seconds, hemi)
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Factory: make a coordinate from degrees and full minutes
|
78
|
+
#
|
79
|
+
# Params:
|
80
|
+
# - degrees {Fixnum} degrees part
|
81
|
+
# - minutes {Float} full minutes, with seconds
|
82
|
+
#
|
83
|
+
# Examples:
|
84
|
+
#
|
85
|
+
# Latitude.degrees_minutes(-39, 20.56074) # => #<Latitude hemisphere=S degrees=39 minutes=20 ...
|
86
|
+
#
|
87
|
+
# Returns: {Latitude|Longitude|Coordinate} instance
|
88
|
+
#
|
89
|
+
def degrees_minutes(degrees, minutes)
|
90
|
+
create(dir_from(degrees), degrees.abs.to_i, *min_with_sec(minutes))
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
##
|
96
|
+
# Private: extract splited values from nmea notation
|
97
|
+
#
|
98
|
+
# Params:
|
99
|
+
# - input {String} input string in nmea notation
|
100
|
+
#
|
101
|
+
# Examples:
|
102
|
+
#
|
103
|
+
# input # => "03922.54, E"
|
104
|
+
# prepare_nmea(input) # => ["03922.54", "E"]
|
105
|
+
#
|
106
|
+
# input2 # => "+03922.54"
|
107
|
+
# prepare_nmea(input) # => ["+03922.54"]
|
108
|
+
#
|
109
|
+
# Returns: [{String}, {String}] numbers and hemisphere
|
110
|
+
#
|
111
|
+
def prepare_nmea(input)
|
112
|
+
splited_values = input.split(NMEA_SEPARATORS)
|
113
|
+
|
114
|
+
splited_values.delete_if { |str| str =~ NMEA_SEPARATORS }
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# Private: extract integer minutes and float seconds from float minutes
|
119
|
+
#
|
120
|
+
# Params:
|
121
|
+
# - minutes {Float|Decimal} minutes
|
122
|
+
#
|
123
|
+
# Returns: [{Ineteger}, {Float}] rounded minutes and exracted seconds
|
124
|
+
#
|
125
|
+
def min_with_sec(minutes_f)
|
126
|
+
seconds = minutes_f.to_d.modulo(1) * 60
|
127
|
+
|
128
|
+
[minutes_f.to_i, seconds.to_f]
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Private: extract minutes and seconds from nmea coord
|
133
|
+
#
|
134
|
+
# Params:
|
135
|
+
# - value {Float} nmea coordinate
|
136
|
+
#
|
137
|
+
# Returns: [{Ineteger}, {Float}] extracted minutes and seconds
|
138
|
+
#
|
139
|
+
def min_with_sec_nmea(value)
|
140
|
+
minutes = value.to_i % 100
|
141
|
+
seconds = (value.modulo(1) * 60).round(4)
|
142
|
+
|
143
|
+
[minutes, seconds]
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Private: detect direction based on neg/pos
|
148
|
+
#
|
149
|
+
# Params:
|
150
|
+
# - degrees {Integer} degrees
|
151
|
+
#
|
152
|
+
# Examples:
|
153
|
+
#
|
154
|
+
# dir_from(-5) # => :<
|
155
|
+
# dir_from(10) # => :>
|
156
|
+
#
|
157
|
+
# Returns: {Symbol} symbol of direction
|
158
|
+
#
|
159
|
+
def dir_from(degrees)
|
160
|
+
degrees < 0 ? :< : :>
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# Private: detect direction from degrees of hemisphere
|
165
|
+
#
|
166
|
+
# Params:
|
167
|
+
# - numbers {Ineteger|Float|Decimal} numerical value of coordinate (degrees)
|
168
|
+
# - hemi {String|Symbol|nil} hemisphere if available
|
169
|
+
#
|
170
|
+
# Examples:
|
171
|
+
#
|
172
|
+
# dir_from_values(43, 'S') # => :<
|
173
|
+
# dir_from_values(43, nil) # => :>
|
174
|
+
#
|
175
|
+
# Returns: {Symbol} symbol of direction
|
176
|
+
#
|
177
|
+
def dir_from_values(numbers, hemi)
|
178
|
+
if hemi
|
179
|
+
(NEGATIVE_HEMISPHERES.include? hemi.to_sym) ? :< : :>
|
180
|
+
else
|
181
|
+
dir_from(numbers.to_i)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
##
|
186
|
+
# Private: fabric. Make a coordinate from given values
|
187
|
+
#
|
188
|
+
# Params:
|
189
|
+
# - direction {Symbol} symbol of hemisphere direction
|
190
|
+
# - degrees {Integer}
|
191
|
+
# - minutes {Integer}
|
192
|
+
# - second {Integer|Float}
|
193
|
+
# - hemi {Symbol|String} (optional) hemisphere
|
194
|
+
#
|
195
|
+
# Raises:
|
196
|
+
# - {ArgumentError} on wrong params values
|
197
|
+
#
|
198
|
+
# Returns: {Longitude|Latotude} created coordinate
|
199
|
+
|
200
|
+
def create(direction, degrees, minutes, seconds, hemi=nil)
|
201
|
+
validate_values(degrees, minutes, seconds, hemi)
|
202
|
+
|
203
|
+
self.new(direction, degrees, minutes, seconds)
|
204
|
+
end
|
205
|
+
|
206
|
+
##
|
207
|
+
# Private: validates given values
|
208
|
+
#
|
209
|
+
# Params:
|
210
|
+
# - degrees {Ineteger}
|
211
|
+
# - minutes {Integer}
|
212
|
+
# - seconds {Ineteger|Float}
|
213
|
+
# - hemi {Symbol|String|nil} hemisphere
|
214
|
+
#
|
215
|
+
# Raises:
|
216
|
+
# - {ArgumentError} on wrong values
|
217
|
+
#
|
218
|
+
def validate_values(degrees, minutes, seconds, hemi)
|
219
|
+
if degrees > self::MAX_DEGREES || minutes > 60 || seconds > 60
|
220
|
+
raise ArgumentError.new('values out of range')
|
221
|
+
end
|
222
|
+
|
223
|
+
validate_hemisphere(hemi.to_sym) if hemi
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
##
|
228
|
+
# Hemisphere validator
|
229
|
+
#
|
230
|
+
# Validates given hemisphere
|
231
|
+
#
|
232
|
+
# Params:
|
233
|
+
# - value {Symbol} - hemisphere
|
234
|
+
#
|
235
|
+
# Raises:
|
236
|
+
# - {ArgumentError} on wrong hemisphere
|
237
|
+
#
|
238
|
+
def validate_hemisphere(value)
|
239
|
+
raise ArgumentError.new('wrong hemisphere') unless HEMISPHERES.include?(value)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|