geo_position 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +51 -6
- data/lib/geo_position/conversion/dms.rb +14 -4
- data/lib/geo_position/conversion/latitude.rb +62 -0
- data/lib/geo_position/conversion/longitude.rb +62 -0
- data/lib/geo_position/error/invalid_dms_string_error.rb +6 -0
- data/lib/geo_position/error/invalid_latitude_error.rb +6 -0
- data/lib/geo_position/error/invalid_longitude_error.rb +6 -0
- data/lib/geo_position/error/invalid_minutes_error.rb +6 -0
- data/lib/geo_position/error/invalid_seconds_error.rb +6 -0
- data/lib/geo_position/error.rb +6 -0
- data/lib/geo_position/parser/dms.rb +49 -0
- data/lib/geo_position/version.rb +1 -1
- data/lib/geo_position.rb +17 -0
- data/spec/conversion/dms_spec.rb +10 -2
- data/spec/conversion/latitude_spec.rb +50 -0
- data/spec/conversion/longitude_spec.rb +50 -0
- data/spec/parser/dms_spec.rb +91 -0
- metadata +18 -4
data/README.md
CHANGED
@@ -3,7 +3,8 @@
|
|
3
3
|
A simple utility to allow you to convert DMS (Degrees, Minutes, Seconds)
|
4
4
|
to a latitude and longitude. The initial driver for this utility was
|
5
5
|
working on an application that took Geo Position information from EXIF
|
6
|
-
data
|
6
|
+
data and converted it to lat/lon for use in both the database storage
|
7
|
+
and querying Google's API.
|
7
8
|
|
8
9
|
## Installation
|
9
10
|
|
@@ -21,7 +22,11 @@ Or install it yourself as:
|
|
21
22
|
|
22
23
|
## Usage
|
23
24
|
|
24
|
-
|
25
|
+
I prefer smaller components that can be put together in different ways.
|
26
|
+
|
27
|
+
Usage is simple:
|
28
|
+
|
29
|
+
### Convert from Degrees, Minutes, Seconds, and Direction to a float
|
25
30
|
|
26
31
|
```ruby
|
27
32
|
# This can be any positive number between 0 and 360. It will be coerced
|
@@ -47,12 +52,52 @@ conversion.to_f
|
|
47
52
|
=> -12.061783333333333
|
48
53
|
```
|
49
54
|
|
55
|
+
### Convert from Latitude to DMS
|
56
|
+
```ruby
|
57
|
+
latitude = "70.4947"
|
58
|
+
|
59
|
+
conversion = GeoPosition::Conversion::Latitude.new(latitude)
|
60
|
+
|
61
|
+
conversion.to_s
|
62
|
+
=> "70 deg 29' 40\" N"
|
63
|
+
```
|
64
|
+
|
65
|
+
### Convert from Longitude to DMS
|
66
|
+
```ruby
|
67
|
+
longitude = "-157.441"
|
68
|
+
|
69
|
+
conversion = GeoPosition::Conversion::Longitude.new(longitude)
|
70
|
+
|
71
|
+
conversion.to_s
|
72
|
+
=> "157 deg 26' 27\" W"
|
73
|
+
```
|
74
|
+
|
75
|
+
### Parsing from a DMS string
|
76
|
+
```ruby
|
77
|
+
dms_string = "77 deg 8 42.00 W"
|
78
|
+
|
79
|
+
parser = GeoPosition::Parser::Dms.new(dms_string)
|
80
|
+
|
81
|
+
parser.degrees
|
82
|
+
=> 77
|
83
|
+
|
84
|
+
parser.minutes
|
85
|
+
=> 8
|
86
|
+
|
87
|
+
parser.seconds
|
88
|
+
=> 42.0
|
89
|
+
|
90
|
+
parser.direction
|
91
|
+
=> "W"
|
92
|
+
|
93
|
+
parser.to_hash
|
94
|
+
=> {:degrees=>77, :minutes=>8, :seconds=>42.0, :direction=>"W"}
|
95
|
+
```
|
96
|
+
|
97
|
+
|
98
|
+
|
50
99
|
## Todo
|
51
100
|
|
52
|
-
* Add ability to parse from the EXIF string and extract into the
|
53
|
-
conversion object
|
54
|
-
* Add ability to convert from lat/lon to DMS
|
55
|
-
* Add simple methods in the root object to handle conversions
|
56
101
|
* Add a command line component
|
57
102
|
|
58
103
|
## Contributing
|
@@ -13,12 +13,12 @@ module GeoPosition
|
|
13
13
|
# => -12.061783333333333
|
14
14
|
#
|
15
15
|
class Dms
|
16
|
-
|
16
|
+
ALLOWED_SECONDS = (0.0..60.0)
|
17
|
+
ALLOWED_DEGREES = (0.0..180.0)
|
17
18
|
ALLOWED_DIRECTIONS = %w( N n E e S s W w )
|
18
19
|
MINUTES_CONVERSION = 60
|
19
20
|
SECONDS_CONVERSION = 3600
|
20
21
|
|
21
|
-
|
22
22
|
# Creates a new instance of the DMS conversion object
|
23
23
|
#
|
24
24
|
# @param degrees [String,Integer]
|
@@ -31,8 +31,10 @@ module GeoPosition
|
|
31
31
|
raise GeoPosition::Error::InvalidDirectionError.new("Please provided a direction of N, S, E, or W") unless valid_direction?(direction)
|
32
32
|
raise GeoPosition::Error::InvalidFloatError.new("Arguments could not be coerced to a float") unless valid_floats?([degrees, minutes, seconds])
|
33
33
|
raise GeoPosition::Error::InvalidDegreesError.new("Degrees must be between 0 and 360. %s was provided" % [degrees]) unless valid_degrees?(degrees)
|
34
|
+
raise GeoPosition::Error::InvalidMinutesError.new("Minutes must be between 0 and 60. %s was provided" % [minutes]) unless valid_minutes?(minutes)
|
35
|
+
raise GeoPosition::Error::InvalidSecondsError.new("Seonds must be between 0 and 60. %s was provided" % [seconds]) unless valid_seconds?(seconds)
|
34
36
|
|
35
|
-
@degrees = degrees
|
37
|
+
@degrees = degrees
|
36
38
|
@minutes = minutes
|
37
39
|
@seconds = seconds
|
38
40
|
|
@@ -94,9 +96,17 @@ module GeoPosition
|
|
94
96
|
ALLOWED_DEGREES.include?(deg.to_f.abs)
|
95
97
|
end
|
96
98
|
|
99
|
+
def valid_minutes?(min)
|
100
|
+
ALLOWED_SECONDS.include?(min.to_f.abs)
|
101
|
+
end
|
102
|
+
|
103
|
+
def valid_seconds?(sec)
|
104
|
+
ALLOWED_SECONDS.include?(sec.to_f.abs)
|
105
|
+
end
|
106
|
+
|
97
107
|
def convert!
|
98
108
|
result = (self.degrees + ((self.minutes/MINUTES_CONVERSION) + (self.seconds/SECONDS_CONVERSION)))
|
99
|
-
if negative? then
|
109
|
+
if negative? then (result * -1) else result end
|
100
110
|
end
|
101
111
|
|
102
112
|
def negative?
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module GeoPosition
|
2
|
+
module Conversion
|
3
|
+
class Latitude
|
4
|
+
BOUNDS = (-90.0..90.0)
|
5
|
+
|
6
|
+
def initialize(latitude)
|
7
|
+
raise GeoPosition::Error::InvalidFloatError.new("Arguments could not be coerced to a float") unless valid_float?(latitude)
|
8
|
+
raise GeoPosition::Error::InvalidLatitudeError.new("Latitde must be between -90 and 90 degrees: %s provided" % [latitude]) unless within_bounds?(latitude)
|
9
|
+
|
10
|
+
@latitude = latitude.to_f
|
11
|
+
|
12
|
+
@degrees = 0
|
13
|
+
@minutes = 0
|
14
|
+
@seconds = 0
|
15
|
+
|
16
|
+
convert!
|
17
|
+
end
|
18
|
+
|
19
|
+
def degrees
|
20
|
+
@degrees
|
21
|
+
end
|
22
|
+
|
23
|
+
def minutes
|
24
|
+
@minutes
|
25
|
+
end
|
26
|
+
|
27
|
+
def seconds
|
28
|
+
@seconds
|
29
|
+
end
|
30
|
+
|
31
|
+
def direction
|
32
|
+
determine_direction
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
"%s deg %s' %s\" %s" % [self.degrees, self.minutes, self.seconds, self.direction]
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def within_bounds?(lat)
|
41
|
+
BOUNDS.include?(lat.to_f)
|
42
|
+
end
|
43
|
+
|
44
|
+
def valid_float?(lat)
|
45
|
+
lat.respond_to?(:to_f)
|
46
|
+
end
|
47
|
+
|
48
|
+
def convert!
|
49
|
+
decimal = @latitude.abs
|
50
|
+
@degrees = decimal.floor
|
51
|
+
|
52
|
+
initial_seconds = (decimal - @degrees) * 3600
|
53
|
+
@minutes = initial_seconds.floor / 60
|
54
|
+
@seconds = (initial_seconds - (@minutes * 60)).floor
|
55
|
+
end
|
56
|
+
|
57
|
+
def determine_direction
|
58
|
+
if @latitude < 0 then 'S' else 'N' end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module GeoPosition
|
2
|
+
module Conversion
|
3
|
+
class Longitude
|
4
|
+
BOUNDS = (-180.0..180.0)
|
5
|
+
|
6
|
+
def initialize(longitude)
|
7
|
+
raise GeoPosition::Error::InvalidFloatError.new("Arguments could not be coerced to a float") unless valid_float?(longitude)
|
8
|
+
raise GeoPosition::Error::InvalidLongitudeError.new("Latitde must be between -180 and 180 degrees: %s provided" % [longitude]) unless within_bounds?(longitude)
|
9
|
+
|
10
|
+
@longitude = longitude.to_f
|
11
|
+
|
12
|
+
@degrees = 0
|
13
|
+
@minutes = 0
|
14
|
+
@seconds = 0
|
15
|
+
|
16
|
+
convert!
|
17
|
+
end
|
18
|
+
|
19
|
+
def degrees
|
20
|
+
@degrees
|
21
|
+
end
|
22
|
+
|
23
|
+
def minutes
|
24
|
+
@minutes
|
25
|
+
end
|
26
|
+
|
27
|
+
def seconds
|
28
|
+
@seconds
|
29
|
+
end
|
30
|
+
|
31
|
+
def direction
|
32
|
+
determine_direction
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
"%s deg %s' %s\" %s" % [self.degrees, self.minutes, self.seconds, self.direction]
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def within_bounds?(lat)
|
41
|
+
BOUNDS.include?(lat.to_f)
|
42
|
+
end
|
43
|
+
|
44
|
+
def valid_float?(lat)
|
45
|
+
lat.respond_to?(:to_f)
|
46
|
+
end
|
47
|
+
|
48
|
+
def convert!
|
49
|
+
decimal = @longitude.abs
|
50
|
+
@degrees = decimal.floor
|
51
|
+
|
52
|
+
initial_seconds = (decimal - @degrees) * 3600
|
53
|
+
@minutes = initial_seconds.floor / 60
|
54
|
+
@seconds = (initial_seconds - (@minutes * 60)).floor
|
55
|
+
end
|
56
|
+
|
57
|
+
def determine_direction
|
58
|
+
if @longitude < 0 then 'W' else 'E' end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/geo_position/error.rb
CHANGED
@@ -3,5 +3,11 @@ module GeoPosition
|
|
3
3
|
autoload :InvalidDirectionError, File.join(File.dirname(__FILE__), 'error/invalid_direction_error')
|
4
4
|
autoload :InvalidFloatError, File.join(File.dirname(__FILE__), 'error/invalid_float_error')
|
5
5
|
autoload :InvalidDegreesError, File.join(File.dirname(__FILE__), 'error/invalid_degrees_error')
|
6
|
+
autoload :InvalidMinutesError, File.join(File.dirname(__FILE__), 'error/invalid_minutes_error')
|
7
|
+
autoload :InvalidSecondsError, File.join(File.dirname(__FILE__), 'error/invalid_seconds_error')
|
8
|
+
|
9
|
+
autoload :InvalidDmsStringError, File.join(File.dirname(__FILE__), 'error/invalid_dms_string_error')
|
10
|
+
autoload :InvalidLatitudeError, File.join(File.dirname(__FILE__), 'error/invalid_latitude_error')
|
11
|
+
autoload :InvalidLongitudeError, File.join(File.dirname(__FILE__), 'error/invalid_longitude_error')
|
6
12
|
end
|
7
13
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module GeoPosition
|
2
|
+
module Parser
|
3
|
+
class Dms
|
4
|
+
FORMAT_REGEX = Regexp.new(/^(?<degrees>[\d]+)\s{1}[^\d]*(?<minutes>[\d]+)\s{1}(?<seconds>[\d]+(\.?[\d]+))\s{1}(?<direction>[nNsSeEwW]{1})/)
|
5
|
+
|
6
|
+
def initialize(dms_string)
|
7
|
+
sanitize_string!(dms_string)
|
8
|
+
|
9
|
+
raise GeoPosition::Error::InvalidDmsStringError.new('String could not be parsed') unless valid_string?(dms_string)
|
10
|
+
|
11
|
+
@dms_string = dms_string.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def degrees
|
15
|
+
parsed[:degrees].to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def minutes
|
19
|
+
parsed[:minutes].to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
def seconds
|
23
|
+
parsed[:seconds].to_f
|
24
|
+
end
|
25
|
+
|
26
|
+
def direction
|
27
|
+
parsed[:direction].upcase
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_hash
|
31
|
+
keys = [:degrees, :minutes, :seconds, :direction]
|
32
|
+
keys.inject({}) { |hsh, key| hsh[key] = self.send(key); hsh }
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def valid_string?(str)
|
37
|
+
FORMAT_REGEX.match(str.to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
def sanitize_string!(str)
|
41
|
+
str.gsub!(/['"]/, '')
|
42
|
+
end
|
43
|
+
|
44
|
+
def parsed
|
45
|
+
@dms_string.match(FORMAT_REGEX)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/geo_position/version.rb
CHANGED
data/lib/geo_position.rb
CHANGED
@@ -9,9 +9,26 @@ require File.join(root, 'geo_position', 'error')
|
|
9
9
|
# Conversions
|
10
10
|
require File.join(root, 'geo_position', 'conversion')
|
11
11
|
require File.join(root, 'geo_position', 'conversion', 'dms')
|
12
|
+
require File.join(root, 'geo_position', 'conversion', 'latitude')
|
13
|
+
require File.join(root, 'geo_position', 'conversion', 'longitude')
|
12
14
|
|
13
15
|
# Parsers
|
14
16
|
require File.join(root, 'geo_position', 'parser')
|
17
|
+
require File.join(root, 'geo_position', 'parser', 'dms')
|
15
18
|
|
16
19
|
module GeoPosition
|
20
|
+
def self.from_dms(degrees, minutes, seconds, direction)
|
21
|
+
conversion = GeoPosition::Conversion::Dms.new(degrees, minutes, seconds, direction)
|
22
|
+
conversion.to_f
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.from_latitude(latitude)
|
26
|
+
conversion = GeoPosition::Conversion::Latitude.new(latitude)
|
27
|
+
conversion.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.from_longitude(longitude)
|
31
|
+
conversion = GeoPosition::Conversion::Longitude.new(longitude)
|
32
|
+
conversion.to_s
|
33
|
+
end
|
17
34
|
end
|
data/spec/conversion/dms_spec.rb
CHANGED
@@ -20,8 +20,16 @@ describe GeoPosition::Conversion::Dms do
|
|
20
20
|
lambda { described_class.new([12], [3], [42.42], 'w') }.should raise_error(GeoPosition::Error::InvalidFloatError)
|
21
21
|
end
|
22
22
|
|
23
|
-
it "raises an exception if degrees are greater than
|
24
|
-
lambda{ described_class.new(
|
23
|
+
it "raises an exception if degrees are greater than 180" do
|
24
|
+
lambda{ described_class.new(181, 12, 123, 'n') }.should raise_error(GeoPosition::Error::InvalidDegreesError)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises an exception if minutes are greater than 60" do
|
28
|
+
lambda { described_class.new(12, 61, 12, 'n') }.should raise_error(GeoPosition::Error::InvalidMinutesError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "raises an exception if seconds are greater than 60" do
|
32
|
+
lambda { described_class.new(12, 30, 61, 'n') }.should raise_error(GeoPosition::Error::InvalidSecondsError)
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GeoPosition::Conversion::Latitude do
|
4
|
+
let(:latitude) { '70.4947' }
|
5
|
+
subject { described_class.new(latitude) }
|
6
|
+
|
7
|
+
context('Error Handling') do
|
8
|
+
it "raises an exception if latitude is greater than 90" do
|
9
|
+
lambda { described_class.new(91) }.should raise_error(GeoPosition::Error::InvalidLatitudeError)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "raises an exception if latitude is greater than -90" do
|
13
|
+
lambda { described_class.new(-91) }.should raise_error(GeoPosition::Error::InvalidLatitudeError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises an exception if latitude cannot be coerced to a float" do
|
17
|
+
lambda { described_class.new([12]) }.should raise_error(GeoPosition::Error::InvalidFloatError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "responds to #to_s" do
|
22
|
+
subject.should respond_to(:to_s)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns 'N' for the direction" do
|
26
|
+
subject.direction.should == 'N'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns 'S' for the direction" do
|
30
|
+
south = latitude.to_f * -1
|
31
|
+
lc = described_class.new(south)
|
32
|
+
lc.direction.should == 'S'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns 70 degrees" do
|
36
|
+
subject.degrees.should eql(70)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns 29 minutes" do
|
40
|
+
subject.minutes.should eql(29)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns 40 seconds" do
|
44
|
+
subject.seconds.should eql(40)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns the DMS string" do
|
48
|
+
subject.to_s.should == "70 deg 29' 40\" N"
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GeoPosition::Conversion::Longitude do
|
4
|
+
let(:longitude) { '-157.441' }
|
5
|
+
subject { described_class.new(longitude) }
|
6
|
+
|
7
|
+
context('Error Handling') do
|
8
|
+
it "raises an exception if longitude is greater than 180" do
|
9
|
+
lambda { described_class.new(181) }.should raise_error(GeoPosition::Error::InvalidLongitudeError)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "raises an exception if longitude is greater than -180" do
|
13
|
+
lambda { described_class.new(-181) }.should raise_error(GeoPosition::Error::InvalidLongitudeError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises an exception if longitude cannot be coerced to a float" do
|
17
|
+
lambda { described_class.new([12]) }.should raise_error(GeoPosition::Error::InvalidFloatError)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "responds to #to_s" do
|
22
|
+
subject.should respond_to(:to_s)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns 'W' for the direction" do
|
26
|
+
subject.direction.should == 'W'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns 'E' for the direction" do
|
30
|
+
east = longitude.to_f * -1
|
31
|
+
lc = described_class.new(east)
|
32
|
+
lc.direction.should == 'E'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns 157 degrees" do
|
36
|
+
subject.degrees.should eql(157)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns 26 minutes" do
|
40
|
+
subject.minutes.should eql(26)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns 27 seconds" do
|
44
|
+
subject.seconds.should eql(27)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns the DMS string" do
|
48
|
+
subject.to_s.should == "157 deg 26' 27\" W"
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GeoPosition::Parser::Dms do
|
4
|
+
let(:dms_string) { "40 deg 20' 13.20\" N" }
|
5
|
+
subject { described_class.new(dms_string) }
|
6
|
+
|
7
|
+
context('Error Handling') do
|
8
|
+
it "raises an exception if the string is not in an accepted format" do
|
9
|
+
lambda { described_class.new('invalid format') }.should raise_error(GeoPosition::Error::InvalidDmsStringError)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context("Simple format") do
|
14
|
+
let(:simple_string) { "12 12 42.42 n" }
|
15
|
+
subject { described_class.new(simple_string) }
|
16
|
+
|
17
|
+
it "returns 12 degrees" do
|
18
|
+
subject.degrees.should eql(12)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns 12 minutes" do
|
22
|
+
subject.minutes.should eql(12)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "returns 42.42 seconds" do
|
26
|
+
subject.seconds.should eql(42.42)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns 'W' for the direction" do
|
30
|
+
subject.direction.should == "N"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "serializes to a hash" do
|
34
|
+
expected = {
|
35
|
+
:degrees => 12,
|
36
|
+
:minutes => 12,
|
37
|
+
:seconds => 42.42,
|
38
|
+
:direction => 'N'
|
39
|
+
}
|
40
|
+
subject.to_hash.should == expected
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context("With 'deg' in the name") do
|
45
|
+
it "returns 40 degrees" do
|
46
|
+
subject.degrees.should eql(40)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "returns 20 minutes" do
|
50
|
+
subject.minutes.should eql(20)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns 13.20 seconds" do
|
54
|
+
subject.seconds.should eql(13.20)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns 'N' for the direction" do
|
58
|
+
subject.direction.should == "N"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "serializes to a hash" do
|
62
|
+
expected = {
|
63
|
+
:degrees => 40,
|
64
|
+
:minutes => 20,
|
65
|
+
:seconds => 13.20,
|
66
|
+
:direction => 'N'
|
67
|
+
}
|
68
|
+
subject.to_hash.should == expected
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "responds to #degrees" do
|
73
|
+
subject.should respond_to(:degrees)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "responds to #minutes" do
|
77
|
+
subject.should respond_to(:minutes)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "responds to #seconds" do
|
81
|
+
subject.should respond_to(:seconds)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "responds to #direction" do
|
85
|
+
subject.should respond_to(:direction)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "responds to #to_hash" do
|
89
|
+
subject.should respond_to(:to_hash)
|
90
|
+
end
|
91
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geo_position
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -93,14 +93,25 @@ files:
|
|
93
93
|
- lib/geo_position.rb
|
94
94
|
- lib/geo_position/conversion.rb
|
95
95
|
- lib/geo_position/conversion/dms.rb
|
96
|
+
- lib/geo_position/conversion/latitude.rb
|
97
|
+
- lib/geo_position/conversion/longitude.rb
|
96
98
|
- lib/geo_position/error.rb
|
97
99
|
- lib/geo_position/error/invalid_degrees_error.rb
|
98
100
|
- lib/geo_position/error/invalid_direction_error.rb
|
101
|
+
- lib/geo_position/error/invalid_dms_string_error.rb
|
99
102
|
- lib/geo_position/error/invalid_float_error.rb
|
103
|
+
- lib/geo_position/error/invalid_latitude_error.rb
|
104
|
+
- lib/geo_position/error/invalid_longitude_error.rb
|
105
|
+
- lib/geo_position/error/invalid_minutes_error.rb
|
106
|
+
- lib/geo_position/error/invalid_seconds_error.rb
|
100
107
|
- lib/geo_position/parser.rb
|
108
|
+
- lib/geo_position/parser/dms.rb
|
101
109
|
- lib/geo_position/version.rb
|
102
110
|
- reload_yard
|
103
111
|
- spec/conversion/dms_spec.rb
|
112
|
+
- spec/conversion/latitude_spec.rb
|
113
|
+
- spec/conversion/longitude_spec.rb
|
114
|
+
- spec/parser/dms_spec.rb
|
104
115
|
- spec/spec_helper.rb
|
105
116
|
homepage: https://github.com/archivability/geo_position
|
106
117
|
licenses: []
|
@@ -116,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
127
|
version: '0'
|
117
128
|
segments:
|
118
129
|
- 0
|
119
|
-
hash:
|
130
|
+
hash: 1503743246014824343
|
120
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
132
|
none: false
|
122
133
|
requirements:
|
@@ -125,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
136
|
version: '0'
|
126
137
|
segments:
|
127
138
|
- 0
|
128
|
-
hash:
|
139
|
+
hash: 1503743246014824343
|
129
140
|
requirements: []
|
130
141
|
rubyforge_project:
|
131
142
|
rubygems_version: 1.8.24
|
@@ -134,5 +145,8 @@ specification_version: 3
|
|
134
145
|
summary: Converting between Deciman/Hours/Seconds and Latitude/Longitude
|
135
146
|
test_files:
|
136
147
|
- spec/conversion/dms_spec.rb
|
148
|
+
- spec/conversion/latitude_spec.rb
|
149
|
+
- spec/conversion/longitude_spec.rb
|
150
|
+
- spec/parser/dms_spec.rb
|
137
151
|
- spec/spec_helper.rb
|
138
152
|
has_rdoc:
|