libgeo 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
- [![Build Status](https://travis-ci.org/Ptico/libgeo.png?branch=master)](https://travis-ci.org/Ptico/libgeo)
|
6
|
+
- [![Code Climate](https://codeclimate.com/github/Ptico/libgeo.png)](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
|