vincenty 1.0.4 → 1.0.6
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/History.txt +34 -52
- data/Rakefile +2 -2
- data/lib/angle.rb +50 -22
- data/lib/coordinate.rb +10 -8
- data/lib/core_extensions.rb +21 -15
- data/lib/latitude.rb +7 -4
- data/lib/longitude.rb +7 -4
- data/lib/track_and_distance.rb +11 -6
- data/lib/vincenty.rb +26 -25
- data/test/ts_all.rb +1 -0
- data/test/ts_angle.rb +15 -15
- data/test/ts_coordinate.rb +4 -4
- data/test/ts_latitude.rb +14 -14
- data/test/ts_longitude.rb +8 -8
- data/test/ts_vincenty.rb +14 -14
- metadata +28 -32
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5e0dc86953a464cd13b0daae7bfcae5fdc3a9a08
|
4
|
+
data.tar.gz: 15ae536fb78d3e30adcc193ead5b44b8d43a4b31
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f67a7f239fb8ae378e1353d1b3a2a8392e6c112e6fa9a62d93eee5eaf24ffc5a864f57ce357cfef02f9b499361e9f889f41a8958cdd664be96f12ea23674883d
|
7
|
+
data.tar.gz: 60e77884385f94913eeedb7dc2bcaceecf076c90af883eaa5f99afb13e6b22513cd50c25fcf3a8f70878d12c8405768655ace7e9474ea140ebab1153416c8476
|
data/History.txt
CHANGED
@@ -1,52 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
Added version method to Vincenty to verify which gem version we are actually using.
|
37
|
-
|
38
|
-
Changed : to ; in case statements to be ruby 1.9 compatible.
|
39
|
-
|
40
|
-
commit cee92bca2c1da98980579d518951729fa17db8b2
|
41
|
-
Author: rbur004 <rob@burrowes.org>
|
42
|
-
Date: Fri Mar 6 04:36:51 2009 +1300
|
43
|
-
|
44
|
-
Minor fix to require list in test/ts_all and added two tests.
|
45
|
-
|
46
|
-
Tidy up to work with "hoe" for gem creation and uploading to Rubyforge.
|
47
|
-
|
48
|
-
commit e5813363fc192b071ccfb54a799ecdca38abc887
|
49
|
-
Author: rbur004 <rob@burrowes.org>
|
50
|
-
Date: Tue Mar 3 19:17:36 2009 +1300
|
51
|
-
|
52
|
-
Initial commit of version 1.0.1.
|
1
|
+
robertburrowes Wed Aug 13 20:36:13 2014 +1200
|
2
|
+
Change to_d to to_deg
|
3
|
+
robertburrowes Sun Jan 13 11:19:28 2013 +1300
|
4
|
+
removed .yardoc from repository
|
5
|
+
robertburrowes Sun Jan 13 11:18:10 2013 +1300
|
6
|
+
removed .yard from repository
|
7
|
+
robertburrowes Sun Jan 13 11:14:48 2013 +1300
|
8
|
+
History now autogenerated, so doesn't need to be in repo
|
9
|
+
robertburrowes Sun Jan 13 11:14:07 2013 +1300
|
10
|
+
Auto generating history file
|
11
|
+
robertburrowes Sun Jan 13 10:49:28 2013 +1300
|
12
|
+
Tidy up of documentation to include more yard tags. Added to_f in Angle.dms to allow more param types to work with dms
|
13
|
+
robertburrowes Sat Jan 12 13:14:58 2013 +1300
|
14
|
+
Updated the install script version to match Vincenty.version Added copy of test suite that uses the install gem, rather than the source code.
|
15
|
+
robertburrowes Sat Jan 12 13:04:54 2013 +1300
|
16
|
+
Changed comments and Readme to 'yard' markdown. Added missing Angle tests into ts_angle.rb Fixed Angle.dms constructer Changed Angle strings to format d m' s" , removing the degree symbol and alternate ' and " symbols. Fixed private function in Angle, that produces output strings (no critical bug).
|
17
|
+
robertburrowes Thu Jan 10 22:04:45 2013 +1300
|
18
|
+
Tidy up
|
19
|
+
rbur004 Sat Sep 29 15:20:04 2012 +1200
|
20
|
+
-
|
21
|
+
rbur004 Sat Sep 29 15:14:21 2012 +1200
|
22
|
+
Missing from the repo, though just generated from git log anyway
|
23
|
+
rbur004 Fri Jan 1 11:10:33 2010 +1300
|
24
|
+
Found the error generating gems with gem 1.3.5 and Hoe. The url in README.txt should not have quotes around it.
|
25
|
+
rbur004 Thu Dec 31 23:39:08 2009 +1300
|
26
|
+
Commented out the require 'lib/vincenty.rb' as it is no longer required
|
27
|
+
rbur004 Thu Dec 31 22:50:16 2009 +1300
|
28
|
+
Hoe gem builder version changed, requiring changes in Hoe calls
|
29
|
+
rbur004 Thu Dec 31 20:06:29 2009 +1300
|
30
|
+
Added version method to Vincenty to verify which gem version we are actually using.
|
31
|
+
rbur004 Fri Mar 6 04:36:51 2009 +1300
|
32
|
+
Minor fix to require list in test/ts_all and added two tests.
|
33
|
+
rbur004 Tue Mar 3 19:17:36 2009 +1300
|
34
|
+
Initial commit of version 1.0.1.
|
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/local/bin/ruby
|
2
2
|
# -*- ruby -*-
|
3
3
|
|
4
4
|
require 'rubygems'
|
@@ -7,7 +7,7 @@ require 'hoe'
|
|
7
7
|
Hoe.plugin :yard
|
8
8
|
|
9
9
|
Hoe.spec 'vincenty' do
|
10
|
-
self.rubyforge_name = "vincenty"
|
10
|
+
#self.rubyforge_name = "vincenty"
|
11
11
|
self.developer( "Rob Burrowes","r.burrowes@auckland.ac.nz")
|
12
12
|
|
13
13
|
self.yard_title = 'Vincenty'
|
data/lib/angle.rb
CHANGED
@@ -9,14 +9,13 @@ require 'core_extensions.rb'
|
|
9
9
|
class Angle
|
10
10
|
include Comparable
|
11
11
|
|
12
|
-
|
13
|
-
attr_accessor :angle
|
12
|
+
# @return [Float] stored in radians
|
13
|
+
attr_accessor :angle
|
14
14
|
alias :value :angle #Older version of angle used volue rather than angle
|
15
15
|
alias :value= :angle= #Older version of angle used volue rather than angle
|
16
16
|
|
17
|
-
#angle may be anything that has a to_f and to_radians.
|
18
|
-
#
|
19
|
-
#if radians is passed true or :radians, then angle is in radians, not degrees.
|
17
|
+
# @param [#to_f,#to_radians] angle may be anything that has a to_f and to_radians.
|
18
|
+
# @param [true,false, :radians] radians Angle is in degrees unless radians == true (or set to :radians).
|
20
19
|
def initialize(angle=0, radians=false)
|
21
20
|
#assumes that we are getting an angle in degrees.
|
22
21
|
if radians == true || radians == :radians
|
@@ -32,9 +31,11 @@ class Angle
|
|
32
31
|
|
33
32
|
|
34
33
|
#Class level function that converts 4 arguments into decimal degrees.
|
35
|
-
#Dircection is one of 'N', 'S', 'E', 'W'.
|
36
|
-
# direction is optional, as you might want to specify a negative value for degrees
|
37
34
|
# @return [Float] signed decimal degrees.
|
35
|
+
# @param [Numeric] degrees
|
36
|
+
# @param [Numeric] minutes
|
37
|
+
# @param [Numeric] seconds
|
38
|
+
# @param ['N', 'S', 'E', 'W'] direction Optional, as the direction might be specified by a negative value for degrees
|
38
39
|
def self.decimal_deg(degrees=0, minutes=0, seconds=0, direction='N')
|
39
40
|
s = { 'N'=>1, 'S'=>-1, 'E'=>1, 'W'=>-1, 'n'=>1, 's'=>-1, 'e'=>1, 'w'=>-1 }
|
40
41
|
sign = s[direction]
|
@@ -45,9 +46,9 @@ class Angle
|
|
45
46
|
sign * (degrees.abs + minutes/60.0 + seconds/3600.0)
|
46
47
|
end
|
47
48
|
|
48
|
-
#Class level function that takes an array of [degress,minutes, seconds, direction]
|
49
|
-
# and returns decimal degrees
|
49
|
+
#Class level function that takes an array of [degress,minutes, seconds, direction] or [degrees,minutes,seconds]
|
50
50
|
# @return [Float] signed decimal degrees.
|
51
|
+
# @param [Array] a Array is expanded and passed as degrees,minutes,seconds,direction to Angle#decimal_deg
|
51
52
|
def self.decimal_deg_from_ary(a)
|
52
53
|
self.decimal_deg(*a)
|
53
54
|
end
|
@@ -57,8 +58,11 @@ class Angle
|
|
57
58
|
# @return [Array] of signed deg, min, sec.
|
58
59
|
#Nb. * That min will be negative if the angle is negative and deg == 0
|
59
60
|
# * That sec will be negative if the angle is negative and deg == 0 && min == 0
|
61
|
+
# @param [#to_f,#to_degrees] angle may be anything that has a to_f and to_radians.
|
62
|
+
# @param [true,false, :radians] radians Angle is in degrees unless radians == true (or set to :radians).
|
60
63
|
def self.dms(angle, radians = false)
|
61
|
-
|
64
|
+
ongle = angle.to_f #means Strings, Numeric, and anything accepting a #to_f will work.
|
65
|
+
angle = angle.to_degrees if radians == true || radians == :radians
|
62
66
|
v = angle.abs
|
63
67
|
deg = v.floor
|
64
68
|
min = ((v-deg)*60.0).floor
|
@@ -81,18 +85,21 @@ class Angle
|
|
81
85
|
|
82
86
|
#Class level function equivalent to Angle.new(r, true)
|
83
87
|
# @return [Angle]
|
88
|
+
# @param [#to_f] r Value in radians to create the new Angle class with.
|
84
89
|
def self.radians(r=0) #passed in radians.
|
85
90
|
self.new(r.to_f, true) #Nb. self is Angle, be we don't Angle.new, as we want subclasses to return their class, not Angle.
|
86
91
|
end
|
87
92
|
|
88
93
|
#Class level function equivalent to Angle.new(d, false) or just Angle.new(d)
|
89
94
|
# @return [Angle]
|
95
|
+
# @param [#to_radians] d Angle to convert to radians, to create new Angle object from.
|
90
96
|
def self.degrees(d=0) #passed in degrees.
|
91
97
|
self.new(d.to_radians, true)
|
92
98
|
end
|
93
99
|
|
94
100
|
#Provides test for Module Comparable, giving us <,>,<=,>=,== between angles
|
95
101
|
# @return [true,false]
|
102
|
+
# @param [Angle,Float] angle Can be another Angle, or a Numeric value to compare @angle with.
|
96
103
|
def <=>(angle)
|
97
104
|
if angle.class == Angle
|
98
105
|
@angle <=> angle.angle
|
@@ -102,49 +109,55 @@ class Angle
|
|
102
109
|
end
|
103
110
|
|
104
111
|
#unary +
|
105
|
-
# @return [Angle] equivalent to @angle
|
112
|
+
# @return [Angle,self] equivalent to @angle
|
106
113
|
def +@
|
107
114
|
self.class.radians(@angle) #Nb. Not Angle.new, as we want subclasses to return their class, not Angle.
|
108
115
|
end
|
109
116
|
|
110
117
|
#Unary -
|
111
|
-
# @return [Angle] -@angle
|
118
|
+
# @return [Angle,self] -@angle
|
112
119
|
def -@
|
113
120
|
self.class.radians(-@angle)
|
114
121
|
end
|
115
122
|
|
116
123
|
# Binary addition operator. Can add angles and numbers, or two angles.
|
117
|
-
# @return [Angle]
|
124
|
+
# @return [Angle,self]
|
125
|
+
# @param [Angle,Numeric] angle
|
118
126
|
def +(angle)
|
119
127
|
self.class.radians(@angle + angle)
|
120
128
|
end
|
121
129
|
|
122
130
|
# Binary subtraction operator. Can add angles and numbers, or two angles.
|
123
|
-
# @return [Angle]
|
131
|
+
# @return [Angle,self]
|
132
|
+
# @param [Angle,Numeric] angle
|
124
133
|
def -(angle)
|
125
134
|
self.class.radians(@angle - angle)
|
126
135
|
end
|
127
136
|
|
128
137
|
# Binary multiply operator. Can add angles and numbers, or two angles.
|
129
|
-
# @return [Angle]
|
138
|
+
# @return [Angle,self]
|
139
|
+
# @param [Angle,Numeric] angle
|
130
140
|
def *(angle)
|
131
141
|
self.class.radians(@angle * angle)
|
132
142
|
end
|
133
143
|
|
134
144
|
# Binary power of operator. Can add angles and numbers, or two angles.
|
135
|
-
# @return [Angle]
|
145
|
+
# @return [Angle,self]
|
146
|
+
# @param [Angle,Numeric] angle
|
136
147
|
def **(angle)
|
137
148
|
self.class.radians(@angle ** angle)
|
138
149
|
end
|
139
150
|
|
140
151
|
# Binary division operator. Can add angles and numbers, or two angles.
|
141
|
-
# @return [Angle]
|
152
|
+
# @return [Angle,self]
|
153
|
+
# @param [Angle,Numeric] angle
|
142
154
|
def /(angle)
|
143
155
|
self.class.radians(@angle / angle)
|
144
156
|
end
|
145
157
|
|
146
158
|
# Binary mod operator. Can add angles and numbers, or two angles.
|
147
|
-
# @return [Angle]
|
159
|
+
# @return [Angle,self]
|
160
|
+
# @param [Angle,Numeric] angle
|
148
161
|
def %(angle)
|
149
162
|
self.class.radians(@angle % angle)
|
150
163
|
end
|
@@ -155,13 +168,15 @@ class Angle
|
|
155
168
|
end
|
156
169
|
|
157
170
|
# @return [Float] angle in degrees
|
158
|
-
alias to_d to_degrees
|
171
|
+
#alias to_d to_degrees
|
172
|
+
alias to_deg to_degrees
|
159
173
|
|
160
|
-
#
|
174
|
+
# @return [Float] angle in radians
|
161
175
|
def to_radians
|
162
176
|
@angle
|
163
177
|
end
|
164
178
|
|
179
|
+
alias to_rad to_radians
|
165
180
|
alias to_r to_radians
|
166
181
|
|
167
182
|
# Returns @angle as decimal_degrees
|
@@ -201,6 +216,7 @@ class Angle
|
|
201
216
|
alias to_int to_i
|
202
217
|
|
203
218
|
# @return [Array] the angle parameter as a Float and the @angle parameter from this class.
|
219
|
+
# @param [Numeric] angle
|
204
220
|
def coerce(angle)
|
205
221
|
[Float(angle), @angle]
|
206
222
|
end
|
@@ -231,13 +247,14 @@ class Angle
|
|
231
247
|
|
232
248
|
|
233
249
|
# @return [String] angle in radians as a string.
|
250
|
+
# @param [String] fmt Optional format string passed to Angle#strf
|
234
251
|
def to_s(fmt = nil)
|
235
252
|
return to_radians.to_s if(fmt == nil)
|
236
253
|
return strf(fmt)
|
237
254
|
end
|
238
255
|
|
239
256
|
#formated output of the angle.
|
240
|
-
#The default format is a signed deg
|
257
|
+
# @param [String] fmt The default format is a signed deg minutes'seconds" with leading 0's in the minutes and seconds and 4 decimal places for seconds.
|
241
258
|
#formats are:
|
242
259
|
# * %wd output the degrees as an integer.
|
243
260
|
# ** where w is 0, 1, 2 or 3 and represents the field width.
|
@@ -349,9 +366,11 @@ class Angle
|
|
349
366
|
private
|
350
367
|
#Output angle_dec as a string to the number of decimal places specified by places.
|
351
368
|
#Assumes the angle is 0 <= angle_dec < 1
|
352
|
-
#No leading '0' is output. The string starts with a '.'
|
369
|
+
#No leading '0' is output. The string starts with a '.' if places is non-zero.
|
353
370
|
#If ploces is -1, then all decimal places are returned.
|
354
371
|
# @return [String]
|
372
|
+
# @param [Float] angle_dec Angle's fractional part
|
373
|
+
# @param [Fixnum] places Number of decimal places to output
|
355
374
|
def s_places(angle_dec, places)
|
356
375
|
if places != -1
|
357
376
|
places > 0 ? ".%0#{places}d" % (angle_dec * 10 ** places).round : ''
|
@@ -367,6 +386,10 @@ class Angle
|
|
367
386
|
#-1 places means print all decimal places.
|
368
387
|
#abs means print the absolute value.
|
369
388
|
# @return [String]
|
389
|
+
# @param [Float] angle In radians
|
390
|
+
# @param [Fixnum] width Output field width, padded with leading 0's
|
391
|
+
# @param [Fixnum] places Number of decimal places to output
|
392
|
+
# @param [true,false] abs Output absolute value.
|
370
393
|
def s_float(angle, width, places, abs)
|
371
394
|
angle_int, angle_dec = angle.abs.divmod(1)
|
372
395
|
f = "%0#{width > 0 ? width : ''}d"
|
@@ -377,6 +400,9 @@ class Angle
|
|
377
400
|
#Return the integer part of angle as a string of fixed width
|
378
401
|
#If abs == true, then return the absolute value.
|
379
402
|
# @return [Fixnum]
|
403
|
+
# @param [Float] angle In radians
|
404
|
+
# @param [Fixnum] width Output field width, padded with leading 0's
|
405
|
+
# @param [true,false] abs Output absolute value.
|
380
406
|
def s_int(angle, width, abs)
|
381
407
|
f = "%0#{width > 0 ? width : ''}d"
|
382
408
|
s = (abs == false && angle.sign == -1) ? '-' : '' #catch the case of -0
|
@@ -388,6 +414,8 @@ class Angle
|
|
388
414
|
#No leading '0' is output. The string starts with a '.'
|
389
415
|
#If ploces is -1, then all decimal places are returned.
|
390
416
|
# @return [String]
|
417
|
+
# @param [Float] angle In radians
|
418
|
+
# @param [Fixnum] places Number of decimal places to output
|
391
419
|
def s_only_places(angle, places)
|
392
420
|
angle_int, angle_dec = angle.abs.divmod(1)
|
393
421
|
s_places(angle_dec, places)
|
data/lib/coordinate.rb
CHANGED
@@ -3,32 +3,34 @@ require 'angle.rb'
|
|
3
3
|
|
4
4
|
#Holds the latitude, longitude, and the altitude for the coordinate
|
5
5
|
class Coordinate
|
6
|
-
|
6
|
+
# @return [Latitude]
|
7
|
+
attr_accessor :latitude
|
8
|
+
# @return [Longitude]
|
9
|
+
attr_accessor :longitude
|
10
|
+
# @return [Numeric]
|
11
|
+
attr_accessor :altitude
|
7
12
|
|
8
13
|
#latitude and longitude can be Strings or Numeric, or anything else with to_radians and to_f
|
9
14
|
#latitude and longitude are in degrees unless radians == true (or set to :radians)
|
10
15
|
def initialize(latitude=0, longitude=0, altitude=0, radians = false)
|
11
|
-
@latitude = Latitude.new(latitude,radians)
|
16
|
+
@latitude = Latitude.new(latitude,radians)
|
12
17
|
@longitude = Longitude.new(longitude,radians)
|
13
18
|
@altitude = altitude.to_f
|
14
19
|
end
|
15
20
|
|
16
|
-
#
|
17
|
-
#Should add an optional format string to this.
|
21
|
+
# @return [String] Latitude longitude and altitude as a single space separated string.
|
18
22
|
def to_s
|
19
23
|
"#{@latitude.to_s } #{@longitude.to_s} #{@altitude}m"
|
20
24
|
end
|
21
25
|
|
22
|
-
#
|
23
|
-
#members, latitude, longitude and altitude
|
26
|
+
# @return [Latitude, Longitude, Float] with members, latitude, longitude and altitude
|
24
27
|
def to_ary
|
25
28
|
[ @latitude, @longitude, @altitude ]
|
26
29
|
end
|
27
30
|
|
28
31
|
alias to_a to_ary
|
29
32
|
|
30
|
-
#return
|
31
|
-
#keys :latitude, :longitude, and :altitude
|
33
|
+
# @return [Hash] with keys :latitude, :longitude, and :altitude
|
32
34
|
def to_hash
|
33
35
|
{ :latitude => @latitude, :longitude => @longitude, :altitude => @altitude }
|
34
36
|
end
|
data/lib/core_extensions.rb
CHANGED
@@ -4,8 +4,8 @@ require 'scanf'
|
|
4
4
|
#Also adds in sign.
|
5
5
|
class Numeric
|
6
6
|
#Convert Radians to Degrees
|
7
|
-
#
|
8
|
-
#
|
7
|
+
# @return [Numeric] degrees
|
8
|
+
# @param [true,false] mod Optional argument mod == true, then applies % 360
|
9
9
|
def to_degrees(mod=false)
|
10
10
|
if mod
|
11
11
|
(self * 180 / Math::PI) % 360
|
@@ -15,8 +15,8 @@ class Numeric
|
|
15
15
|
end
|
16
16
|
|
17
17
|
#Converts degrees to Radians
|
18
|
-
#
|
19
|
-
#
|
18
|
+
# @return [Numeric] radians
|
19
|
+
# @param [true,false] mod Optional argument mod == true, then applies % Math::PI
|
20
20
|
def to_radians(mod=false)
|
21
21
|
if mod
|
22
22
|
(self * Math::PI / 180) % Math::PI
|
@@ -26,9 +26,10 @@ class Numeric
|
|
26
26
|
end
|
27
27
|
|
28
28
|
alias to_r to_radians
|
29
|
-
alias
|
29
|
+
alias to_rad to_radians
|
30
|
+
alias to_deg to_degrees
|
30
31
|
|
31
|
-
#
|
32
|
+
# @return [Fixnum] 1 if number is positive, -1 if negative.
|
32
33
|
def sign
|
33
34
|
self < 0 ? -1 : 1
|
34
35
|
end
|
@@ -37,10 +38,14 @@ end
|
|
37
38
|
|
38
39
|
#Alters round method to have an optional number of decimal places.
|
39
40
|
class Float
|
41
|
+
|
42
|
+
#Replace default round, so we can reference it later.
|
43
|
+
# @return [Float]
|
40
44
|
alias round0 round
|
45
|
+
|
41
46
|
#Compatible Replacement for Float.round
|
42
|
-
#
|
43
|
-
#
|
47
|
+
# @return [Float] float rounded to n decimal places.
|
48
|
+
# @param [Numeric] n Optional argument n is the number of decimal places to round to.
|
44
49
|
def round(n = 0)
|
45
50
|
m = 10.0**n
|
46
51
|
(self * m).round0 / m
|
@@ -51,7 +56,7 @@ end
|
|
51
56
|
class String
|
52
57
|
#string expected to be degrees, returns decimal degrees.
|
53
58
|
#common forms are S37 001'7.5'', 37 001'7.5''S , -37 001'7.5'', -37 0 1.512'. -37.01875 0, 37 001'.512S, S37 001'.512, ...
|
54
|
-
#
|
59
|
+
# @return [Float] angle in decimal degrees
|
55
60
|
def to_dec_degrees
|
56
61
|
#reorder 37 001'.512S, S37 001'.512 into 37 001.512'S, S37 001.512' respectively
|
57
62
|
s = self.gsub(/([0-9])([''])\.([0-9]+)/, '\1.\3\2')
|
@@ -71,20 +76,21 @@ class String
|
|
71
76
|
end
|
72
77
|
end
|
73
78
|
|
74
|
-
#Convert Radians to Degrees
|
75
|
-
#
|
76
|
-
#
|
79
|
+
#Convert String number in Radians to Degrees
|
80
|
+
# @return [Float] degrees
|
81
|
+
# @param [true,false] mod Optional argument mod == true, then applies % 360
|
77
82
|
def to_degrees(mod=false) #string expected to be radians, returns degrees
|
78
83
|
self.to_f.to_degrees(mod)
|
79
84
|
end
|
80
85
|
|
81
86
|
#Converts string degrees to to_decimal_degrees, then to Radians
|
82
|
-
#
|
83
|
-
#
|
87
|
+
# @return [Float] radians
|
88
|
+
# @param [true,false] mod Optional argument mod == true, then applies % Math::PI
|
84
89
|
def to_radians(mod=false) #string expected to be degrees, returns radians
|
85
90
|
self.to_dec_degrees.to_radians(mod)
|
86
91
|
end
|
87
92
|
|
93
|
+
alias to_rad to_radians
|
88
94
|
alias to_r to_radians
|
89
|
-
alias
|
95
|
+
alias to_deg to_degrees
|
90
96
|
end
|
data/lib/latitude.rb
CHANGED
@@ -6,7 +6,7 @@ require 'angle.rb'
|
|
6
6
|
|
7
7
|
class Latitude < Angle
|
8
8
|
|
9
|
-
#
|
9
|
+
# @return [Float] angle as degrees in range -90 and 90
|
10
10
|
def to_degrees
|
11
11
|
degrees = super
|
12
12
|
case
|
@@ -18,7 +18,7 @@ class Latitude < Angle
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
#
|
21
|
+
# @return [Float] angle as degrees in range -PI and PI
|
22
22
|
def to_radians
|
23
23
|
case
|
24
24
|
when @angle > 3*Math::PI/2 ; @angle - Math::PI * 2
|
@@ -29,13 +29,16 @@ class Latitude < Angle
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
#
|
32
|
+
# @return [String] angle as string in degrees minutes seconds direction.
|
33
33
|
#A South angle is negative, North is Positive.
|
34
|
+
# @param [String] fmt Optional format string passed to Angle#to_s
|
34
35
|
def to_s(fmt="%2d %2m'%2.4s\"%N")
|
35
36
|
super(fmt)
|
36
37
|
end
|
37
38
|
|
38
39
|
alias to_r to_radians
|
39
|
-
alias
|
40
|
+
alias to_rad to_radians
|
41
|
+
#alias to_d to_degrees
|
42
|
+
alias to_deg to_degrees
|
40
43
|
|
41
44
|
end
|
data/lib/longitude.rb
CHANGED
@@ -6,7 +6,7 @@ require 'angle.rb'
|
|
6
6
|
|
7
7
|
class Longitude < Angle
|
8
8
|
|
9
|
-
#
|
9
|
+
# @return [Float] angle as degrees in range -180 and 180
|
10
10
|
def to_degrees
|
11
11
|
degrees = super
|
12
12
|
case
|
@@ -15,7 +15,7 @@ class Longitude < Angle
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
#
|
18
|
+
# @return [Float] angle as degrees in range -2PI and 2PI
|
19
19
|
def to_radians
|
20
20
|
case
|
21
21
|
when @angle > Math::PI ; @angle - 2 * Math::PI
|
@@ -23,13 +23,16 @@ class Longitude < Angle
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
#
|
26
|
+
# @return [String] angle as string in degrees minutes seconds direction.
|
27
27
|
#A West angle is negative, East is Positive.
|
28
|
+
# @param [String] fmt Optional format string passed to Angle#to_s
|
28
29
|
def to_s(fmt="%3d %2m'%2.4s\"%E")
|
29
30
|
super(fmt)
|
30
31
|
end
|
31
32
|
|
32
33
|
alias to_r to_radians
|
33
|
-
alias
|
34
|
+
alias to_rad to_radians
|
35
|
+
#alias to_d to_degrees
|
36
|
+
alias to_deg to_degrees
|
34
37
|
|
35
38
|
end
|
data/lib/track_and_distance.rb
CHANGED
@@ -3,10 +3,14 @@ require 'angle.rb'
|
|
3
3
|
|
4
4
|
#Holds a bearing and distance
|
5
5
|
class TrackAndDistance
|
6
|
-
|
6
|
+
# @return [Angle]
|
7
|
+
attr_accessor :bearing
|
8
|
+
# @return [Float]
|
9
|
+
attr_accessor :distance
|
7
10
|
|
8
|
-
#
|
9
|
-
#
|
11
|
+
# @param [String, Numeric, #to_radian, #to_f] Bearing can be a String or Numeric or any object with to_radians and to_f
|
12
|
+
# @param [Numeric] distance
|
13
|
+
# @param [true,false, :radians] radians Bearing is in degrees unless radians == true (or set to :radians).
|
10
14
|
def initialize(bearing, distance, radians=false)
|
11
15
|
@bearing = Angle.new(bearing, radians)
|
12
16
|
@distance = distance
|
@@ -14,7 +18,8 @@ class TrackAndDistance
|
|
14
18
|
|
15
19
|
#format string fmt is currently just for the bearing angle.
|
16
20
|
#Need to change this to include the distance is single format string.
|
17
|
-
#
|
21
|
+
# @return [String] Bearing angle and distance in meters.
|
22
|
+
# @param [String] fmt Optional format string passed to Coordinate#strf
|
18
23
|
def to_s(fmt = nil)
|
19
24
|
if(fmt)
|
20
25
|
#needs work to include distance as well as angle fmt.
|
@@ -24,12 +29,12 @@ class TrackAndDistance
|
|
24
29
|
end
|
25
30
|
end
|
26
31
|
|
27
|
-
#
|
32
|
+
# @return [Array] with members bearing and distance.
|
28
33
|
def to_ary
|
29
34
|
[ @bearing, @distance ]
|
30
35
|
end
|
31
36
|
|
32
|
-
#
|
37
|
+
# @return [Hash] with keys :bearing and :distance
|
33
38
|
def to_hash
|
34
39
|
{ :bearing => @bearing, :distance => @distance }
|
35
40
|
end
|
data/lib/vincenty.rb
CHANGED
@@ -12,8 +12,9 @@ require 'coordinate.rb'
|
|
12
12
|
# Modified to incorporate corrections to formulae as found in script on http://www.movable-type.co.uk/scripts/LatLongVincenty.html
|
13
13
|
# Added my Modification of the distanceAndAngle formulae to correct the compass bearing.
|
14
14
|
class Vincenty < Coordinate
|
15
|
-
VERSION = '1.0.
|
15
|
+
VERSION = '1.0.6'
|
16
16
|
|
17
|
+
# @return [String] constant VERSION
|
17
18
|
def version
|
18
19
|
VERSION
|
19
20
|
end
|
@@ -21,22 +22,22 @@ class Vincenty < Coordinate
|
|
21
22
|
#Great Circle formulae http://en.wikipedia.org/wiki/Great-circle_distance
|
22
23
|
#Reference calculation for testing, assumes the earth is a sphere, which it isn't.
|
23
24
|
#This gives us an approximation to verify Vincenty algorithm.
|
24
|
-
#
|
25
|
-
#
|
25
|
+
# @param [Coordinate] p2 is target coordinate that we want the bearing to.
|
26
|
+
# @return [TrackAndDistance] with the compass bearing and distance in meters to P2
|
26
27
|
def sphericalDistanceAndAngle( p2 )
|
27
28
|
a = 6378137 #equatorial radius in meters (+/-2 m)
|
28
29
|
b = 6356752.31424518 #polar radius in meters
|
29
30
|
r = (a+b)/2 #average diametre as a rough estimate for our tests.
|
30
31
|
|
31
|
-
sin_lat1 = Math.sin(@latitude.
|
32
|
-
sin_lat2 = Math.sin(p2.latitude.
|
33
|
-
cos_lat1 = Math.cos(@latitude.
|
32
|
+
sin_lat1 = Math.sin(@latitude.to_rad)
|
33
|
+
sin_lat2 = Math.sin(p2.latitude.to_rad)
|
34
|
+
cos_lat1 = Math.cos(@latitude.to_rad)
|
34
35
|
atan1_2 = Math.atan(1) * 2
|
35
|
-
t1 = cos_lat1 * Math.cos(p2.latitude.
|
36
|
+
t1 = cos_lat1 * Math.cos(p2.latitude.to_rad) * ( Math.cos(@longitude.to_rad - p2.longitude.to_rad) ) + sin_lat1 * sin_lat2
|
36
37
|
angular_distance = Math.atan(-t1/Math.sqrt(-t1 * t1 +1)) + atan1_2 #central angle in radians so we can calculate the arc length.
|
37
38
|
|
38
39
|
t2 = (sin_lat2 - sin_lat1 * Math.cos(angular_distance)) / (cos_lat1 * Math.sin(angular_distance))
|
39
|
-
if(Math.sin(p2.longitude.
|
40
|
+
if(Math.sin(p2.longitude.to_rad - @longitude.to_rad) < 0)
|
40
41
|
bearing = 2 * Math::PI - (Math.atan(-t2 / Math.sqrt(-t2 * t2 + 1)) + atan1_2) #Compass Bearing in radians (clockwise)
|
41
42
|
else
|
42
43
|
bearing = Math.atan(-t2 / Math.sqrt(-t2 * t2 + 1)) + atan1_2 #Compass Bearing in radians (clockwise)
|
@@ -48,18 +49,18 @@ class Vincenty < Coordinate
|
|
48
49
|
|
49
50
|
#Vincenty's algorithm for finding bearing and distance between to coordinates.
|
50
51
|
#Assumes earth is a WGS-84 Ellipsod.
|
51
|
-
#
|
52
|
-
#
|
52
|
+
# @param [Coordinate] p2 is target coordinate that we want the bearing to.
|
53
|
+
# @return [TrackAndDistance] with the compass bearing and distance in meters to P2
|
53
54
|
def distanceAndAngle( p2 )
|
54
55
|
# a, b = major & minor semiaxes of the ellipsoid
|
55
56
|
a = 6378137 #equatorial radius in meters (+/-2 m)
|
56
57
|
b = 6356752.31424518 #polar radius in meters
|
57
58
|
f = (a-b)/a # flattening
|
58
59
|
|
59
|
-
lat1 = @latitude.
|
60
|
-
lon1 = @longitude.
|
61
|
-
lat2 = p2.latitude.
|
62
|
-
lon2 = p2.longitude.
|
60
|
+
lat1 = @latitude.to_rad
|
61
|
+
lon1 = @longitude.to_rad
|
62
|
+
lat2 = p2.latitude.to_rad
|
63
|
+
lon2 = p2.longitude.to_rad
|
63
64
|
lat1 = lat1.sign * (Math::PI/2-(1e-10)) if (Math::PI/2-lat1.abs).abs < 1.0e-10
|
64
65
|
lat2 = lat2.sign * (Math::PI/2-(1e-10)) if (Math::PI/2-lat2.abs).abs < 1.0e-10
|
65
66
|
|
@@ -104,7 +105,7 @@ class Vincenty < Coordinate
|
|
104
105
|
|
105
106
|
#This test isn't in original formulae, and fixes the problem of all angles returned being between 0 - PI (0-180)
|
106
107
|
#Also converts the result to compass bearing, rather than the mathmatical anticlockwise angles.
|
107
|
-
if(Math.sin(p2.longitude.
|
108
|
+
if(Math.sin(p2.longitude.to_rad - @longitude.to_rad) < 0)
|
108
109
|
alpha_1 = Math::PI*2-Math.atan2( cos_u2 * sin_lambda_v, cos_u1 * sin_u2 - sin_u1 * cos_u2 * cos_lambda_v)
|
109
110
|
#alpha_2 = Math::PI*2-Math.atan2(cos_u1 * sin_lambda_v, -sin_u1 * cos_u2 + cos_u1 * sin_u2 * cos_lambda_v)
|
110
111
|
else
|
@@ -118,8 +119,8 @@ class Vincenty < Coordinate
|
|
118
119
|
|
119
120
|
#spherical earth estimate of calculation for finding target coordinate from start coordinate, bearing and distance
|
120
121
|
#Used to run checks on the Vincenty algorithm
|
121
|
-
#
|
122
|
-
#
|
122
|
+
# @param [TrackAndDistance] track_and_distance specifying bearing and distance.
|
123
|
+
# @return [Vincenty] with the destination coordinates.
|
123
124
|
def sphereDestination( track_and_distance )
|
124
125
|
a = 6378137 #equatorial radius in meters (+/-2 m)
|
125
126
|
b = 6356752.31424518 #polar radius in meters
|
@@ -128,10 +129,10 @@ class Vincenty < Coordinate
|
|
128
129
|
d = track_and_distance.distance.abs
|
129
130
|
sin_dor = Math.sin(d/r)
|
130
131
|
cos_dor = Math.cos(d/r)
|
131
|
-
sin_lat1 = Math.sin(@latitude.
|
132
|
-
cos_lat1 = Math.cos(@latitude.
|
133
|
-
lat2 = Math.asin( sin_lat1 * cos_dor + cos_lat1 * sin_dor * Math.cos(track_and_distance.bearing.
|
134
|
-
lon2 = @longitude.
|
132
|
+
sin_lat1 = Math.sin(@latitude.to_rad)
|
133
|
+
cos_lat1 = Math.cos(@latitude.to_rad)
|
134
|
+
lat2 = Math.asin( sin_lat1 * cos_dor + cos_lat1 * sin_dor * Math.cos(track_and_distance.bearing.to_rad) )
|
135
|
+
lon2 = @longitude.to_rad + Math.atan2(Math.sin(track_and_distance.bearing.to_rad) * sin_dor * cos_lat1, cos_dor-sin_lat1 * Math.sin(lat2))
|
135
136
|
|
136
137
|
Vincenty.new(lat2, lon2, 0, true);
|
137
138
|
end
|
@@ -139,8 +140,8 @@ class Vincenty < Coordinate
|
|
139
140
|
#
|
140
141
|
# Calculate destination point given start point lat/long, bearing and distance.
|
141
142
|
#Assumes earth is a WGS-84 Ellipsod.
|
142
|
-
#
|
143
|
-
#
|
143
|
+
# @param [TrackAndDistance] specifying bearing and distance.
|
144
|
+
# @return [Vincenty] with the destination coordinates.
|
144
145
|
def destination( track_and_distance )
|
145
146
|
# a, b = major & minor semiaxes of the ellipsoid
|
146
147
|
a = 6378137 #equatorial radius in meters (+/-2 m)
|
@@ -148,11 +149,11 @@ class Vincenty < Coordinate
|
|
148
149
|
f = (a-b)/a # flattening
|
149
150
|
|
150
151
|
s = track_and_distance.distance.abs;
|
151
|
-
alpha1 = track_and_distance.bearing.
|
152
|
+
alpha1 = track_and_distance.bearing.to_rad
|
152
153
|
sin_alpha1 = Math.sin(alpha1)
|
153
154
|
cos_alpha1 = Math.cos(alpha1)
|
154
155
|
|
155
|
-
tanU1 = (1-f) * Math.tan(@latitude.
|
156
|
+
tanU1 = (1-f) * Math.tan(@latitude.to_rad);
|
156
157
|
cosU1 = 1 / Math.sqrt((1 + tanU1 * tanU1))
|
157
158
|
sinU1 = tanU1 * cosU1
|
158
159
|
sigma1 = Math.atan2(tanU1, cos_alpha1)
|
data/test/ts_all.rb
CHANGED
data/test/ts_angle.rb
CHANGED
@@ -5,21 +5,21 @@ class TestAngle< Test::Unit::TestCase
|
|
5
5
|
#test Angle creation
|
6
6
|
def test_angle
|
7
7
|
assert_equal(Angle.new(), 0)
|
8
|
-
assert_equal(Angle.new("S37 01'7.5\"").
|
9
|
-
assert_equal(Angle.new("37 01'7.5\"S").
|
10
|
-
assert_equal(Angle.new("-37 01'7.5\"").
|
11
|
-
assert_equal(Angle.new("-37 1.125'").
|
12
|
-
assert_equal(Angle.new("-37 01'.125").
|
13
|
-
assert_equal(Angle.new("S37 01'.125").
|
14
|
-
assert_equal(Angle.new("37 01'.125S").
|
15
|
-
assert_equal(Angle.new("-37.01875 ").
|
16
|
-
assert_equal(Angle.new([-37, 1, 7.5]).
|
17
|
-
assert_equal(Angle.new(-37.01875).
|
18
|
-
assert_equal(Angle.degrees(-37.01875).
|
19
|
-
assert_equal(Angle.degrees(-37.01875).
|
20
|
-
assert_equal(Angle.new(-0.646099072472651, true).
|
21
|
-
assert_equal(Angle.new(-0.646099072472651, true).
|
22
|
-
assert_equal(Angle.radians(-0.646099072472651).
|
8
|
+
assert_equal(Angle.new("S37 01'7.5\"").to_deg, -37.01875) #Leading NSEW
|
9
|
+
assert_equal(Angle.new("37 01'7.5\"S").to_deg , -37.01875) #Trailing NSEW
|
10
|
+
assert_equal(Angle.new("-37 01'7.5\"").to_deg, -37.01875) #Use of - rather than S or W
|
11
|
+
assert_equal(Angle.new("-37 1.125'").to_deg, -37.01875) #Decimal minutes, rather than minutes and seconds.
|
12
|
+
assert_equal(Angle.new("-37 01'.125").to_deg, -37.01875) #Nb. the minute marker ' between the minutes and fraction
|
13
|
+
assert_equal(Angle.new("S37 01'.125").to_deg, -37.01875) #Nb. the minute marker ' between the minutes and fraction
|
14
|
+
assert_equal(Angle.new("37 01'.125S").to_deg, -37.01875) #Nb. the minute marker ' between the minutes and fraction
|
15
|
+
assert_equal(Angle.new("-37.01875 ").to_deg, -37.01875) #decimal degrees, rather than deg, min, sec.
|
16
|
+
assert_equal(Angle.new([-37, 1, 7.5]).to_deg, -37.01875) #an array of deg,min,sec
|
17
|
+
assert_equal(Angle.new(-37.01875).to_deg, -37.01875)
|
18
|
+
assert_equal(Angle.degrees(-37.01875).to_deg, -37.01875)
|
19
|
+
assert_equal(Angle.degrees(-37.01875).to_rad.round(15), -0.646099072472651)
|
20
|
+
assert_equal(Angle.new(-0.646099072472651, true).to_deg.round(5), -37.01875)
|
21
|
+
assert_equal(Angle.new(-0.646099072472651, true).to_rad, -0.646099072472651)
|
22
|
+
assert_equal(Angle.radians(-0.646099072472651).to_deg.round(5), -37.01875)
|
23
23
|
assert_equal(Angle.radians(-0.646099072472651).value, Angle.radians(-0.646099072472651).angle)
|
24
24
|
assert_equal(Angle.decimal_deg(1,2,3,'S'), -(1.0 + 2/60.0 + 3/3600.0))
|
25
25
|
assert_equal(Angle.decimal_deg(1,2,3,'E'), (1.0 + 2/60.0 + 3/3600.0))
|
data/test/ts_coordinate.rb
CHANGED
@@ -6,12 +6,12 @@ class TestAngle< Test::Unit::TestCase
|
|
6
6
|
def test_coordinate
|
7
7
|
c = Coordinate.new(-36.9923293459124, 174.485341187381,13.5)
|
8
8
|
ca = c.to_ary
|
9
|
-
assert_equal(-36.9923293459124, ca[0].
|
10
|
-
assert_equal(174.485341187381, ca[1].
|
9
|
+
assert_equal(-36.9923293459124, ca[0].to_deg)
|
10
|
+
assert_equal(174.485341187381, ca[1].to_deg)
|
11
11
|
assert_equal(13.5, ca[2])
|
12
12
|
ch = c.to_hash
|
13
|
-
assert_equal(-36.9923293459124, ch[:latitude].
|
14
|
-
assert_equal(174.485341187381, ch[:longitude].
|
13
|
+
assert_equal(-36.9923293459124, ch[:latitude].to_deg)
|
14
|
+
assert_equal(174.485341187381, ch[:longitude].to_deg)
|
15
15
|
assert_equal(13.5, ch[:altitude])
|
16
16
|
assert_equal("36 59'32.3856\"S 174 29'07.2283\"E 13.5m", c.to_s)
|
17
17
|
end
|
data/test/ts_latitude.rb
CHANGED
@@ -11,21 +11,21 @@ class TestAngle< Test::Unit::TestCase
|
|
11
11
|
assert_equal("37 01'07.5000\"N", Latitude.new("37 01'7.5\"N").to_s)
|
12
12
|
end
|
13
13
|
def test_to_radians
|
14
|
-
assert_equal(Math::PI/4, Latitude.degrees(45).
|
15
|
-
assert_equal(Math::PI/4, Latitude.degrees(135).
|
16
|
-
assert_equal(-Math::PI/4, Latitude.degrees(225).
|
17
|
-
assert_equal(-Math::PI/4, Latitude.degrees(315).
|
14
|
+
assert_equal(Math::PI/4, Latitude.degrees(45).to_rad)
|
15
|
+
assert_equal(Math::PI/4, Latitude.degrees(135).to_rad)
|
16
|
+
assert_equal(-Math::PI/4, Latitude.degrees(225).to_rad)
|
17
|
+
assert_equal(-Math::PI/4, Latitude.degrees(315).to_rad)
|
18
18
|
end
|
19
19
|
def test_to_degrees
|
20
|
-
assert_equal(45, Latitude.degrees(45).
|
21
|
-
assert_equal(45, Latitude.degrees(135).
|
22
|
-
assert_equal(-45, Latitude.degrees(225).
|
23
|
-
assert_equal(-45, Latitude.degrees(315).
|
24
|
-
assert_equal(1, Latitude.degrees(179).
|
25
|
-
assert_equal(-1, Latitude.degrees(181).
|
26
|
-
assert_equal(-89, Latitude.degrees(269).
|
27
|
-
assert_equal(-89, Latitude.degrees(271).
|
28
|
-
assert_equal(89, Latitude.degrees(89).
|
29
|
-
assert_equal(89, Latitude.degrees(91).
|
20
|
+
assert_equal(45, Latitude.degrees(45).to_deg)
|
21
|
+
assert_equal(45, Latitude.degrees(135).to_deg)
|
22
|
+
assert_equal(-45, Latitude.degrees(225).to_deg)
|
23
|
+
assert_equal(-45, Latitude.degrees(315).to_deg)
|
24
|
+
assert_equal(1, Latitude.degrees(179).to_deg)
|
25
|
+
assert_equal(-1, Latitude.degrees(181).to_deg)
|
26
|
+
assert_equal(-89, Latitude.degrees(269).to_deg)
|
27
|
+
assert_equal(-89, Latitude.degrees(271).to_deg)
|
28
|
+
assert_equal(89, Latitude.degrees(89).to_deg)
|
29
|
+
assert_equal(89, Latitude.degrees(91).to_deg)
|
30
30
|
end
|
31
31
|
end
|
data/test/ts_longitude.rb
CHANGED
@@ -11,15 +11,15 @@ class TestAngle< Test::Unit::TestCase
|
|
11
11
|
assert_equal("037 01'07.5000\"E", Longitude.new("37 01'7.5\"E").to_s)
|
12
12
|
end
|
13
13
|
def test_to_radians
|
14
|
-
assert_equal(Math::PI/4, Longitude.degrees(45).
|
15
|
-
assert_equal(3*Math::PI/4, Longitude.degrees(135).
|
16
|
-
assert_equal(-3*Math::PI/4, Longitude.degrees(225).
|
17
|
-
assert_equal(-Math::PI/4, Longitude.degrees(315).
|
14
|
+
assert_equal(Math::PI/4, Longitude.degrees(45).to_rad)
|
15
|
+
assert_equal(3*Math::PI/4, Longitude.degrees(135).to_rad)
|
16
|
+
assert_equal(-3*Math::PI/4, Longitude.degrees(225).to_rad)
|
17
|
+
assert_equal(-Math::PI/4, Longitude.degrees(315).to_rad)
|
18
18
|
end
|
19
19
|
def test_to_degrees
|
20
|
-
assert_equal(45, Longitude.degrees(45).
|
21
|
-
assert_equal(135, Longitude.degrees(135).
|
22
|
-
assert_equal(-135, Longitude.degrees(225).
|
23
|
-
assert_equal(-45, Longitude.degrees(315).
|
20
|
+
assert_equal(45, Longitude.degrees(45).to_deg)
|
21
|
+
assert_equal(135, Longitude.degrees(135).to_deg)
|
22
|
+
assert_equal(-135, Longitude.degrees(225).to_deg)
|
23
|
+
assert_equal(-45, Longitude.degrees(315).to_deg)
|
24
24
|
end
|
25
25
|
end
|
data/test/ts_vincenty.rb
CHANGED
@@ -42,15 +42,15 @@ class TestVincenty< Test::Unit::TestCase
|
|
42
42
|
start = Vincenty.new(-36.9921838030711, 174.485468469841)
|
43
43
|
|
44
44
|
next_p = start
|
45
|
-
# print "Start at coordinate #{next_p.longitude.
|
45
|
+
# print "Start at coordinate #{next_p.longitude.to_deg}, #{next_p.latitude.to_deg}\n"
|
46
46
|
@path.each_with_index do |leg,i|
|
47
47
|
next_p, spherical_ans = next_p.destination( leg ) , next_p.sphereDestination(leg)
|
48
48
|
|
49
|
-
assert_equal(@waypoints[i].longitude.
|
50
|
-
assert_equal(@waypoints[i].latitude.
|
51
|
-
# print "Expect #{waypoints[i].longitude.
|
52
|
-
# print "Moved #{leg.bearing.
|
53
|
-
# print "Spherical #{leg.bearing.
|
49
|
+
assert_equal(@waypoints[i].longitude.to_deg.round(12), next_p.longitude.to_deg.round(12))
|
50
|
+
assert_equal(@waypoints[i].latitude.to_deg.round(12), next_p.latitude.to_deg.round(12))
|
51
|
+
# print "Expect #{waypoints[i].longitude.to_deg.round(4)}, #{waypoints[i].latitude.to_deg.round(4)}\n"
|
52
|
+
# print "Moved #{leg.bearing.to_deg.round(4)} #{leg.distance.round(4)}m to #{next_p.longitude.to_deg.round(4)}, #{next_p.latitude.to_deg.round(4)}\n"
|
53
|
+
# print "Spherical #{leg.bearing.to_deg.round(4)} #{leg.distance.round(4)}m to #{spherical_ans.longitude.to_deg.round(4)}, #{spherical_ans.latitude.to_deg.round(4)}\n"
|
54
54
|
# puts
|
55
55
|
end
|
56
56
|
# assert_equal(0, next_p.distanceAndAngle(start).distance)
|
@@ -63,16 +63,16 @@ class TestVincenty< Test::Unit::TestCase
|
|
63
63
|
start = Vincenty.new(-36.9921838030711, 174.485468469841)
|
64
64
|
next_p = start
|
65
65
|
# print "\nReverse test, c\n"
|
66
|
-
# print "Start at coordinate #{next_p.longitude.
|
66
|
+
# print "Start at coordinate #{next_p.longitude.to_deg}, #{next_p.latitude.to_deg}\n"
|
67
67
|
@waypoints.each_with_index do |point,i|
|
68
68
|
vtrack_and_bearing = next_p.distanceAndAngle( point )
|
69
69
|
# strack_and_bearing = next_p.sphericalDistanceAndAngle( point )
|
70
70
|
|
71
|
-
assert_equal(@path[i].bearing.
|
71
|
+
assert_equal(@path[i].bearing.to_deg.round(4), vtrack_and_bearing.bearing.to_deg.round(4))
|
72
72
|
assert_equal(@path[i].distance.round(4), vtrack_and_bearing.distance.round(4))
|
73
|
-
# print "Expected #{path[i].bearing.
|
74
|
-
# print "WGS-84 track #{vtrack_and_bearing.bearing.
|
75
|
-
# print "Spherical track #{strack_and_bearing.bearing.
|
73
|
+
# print "Expected #{path[i].bearing.to_deg.round(4)}(#{((path[i].bearing.to_deg+180)%360).round(4)}), #{path[i].distance.round(4)}m\n"
|
74
|
+
# print "WGS-84 track #{vtrack_and_bearing.bearing.to_deg.round(4)} #{vtrack_and_bearing.distance.round(4)}m from #{next_p.longitude.to_deg.round(4)}, #{next_p.latitude.to_deg.round(4)} to #{point.longitude.to_deg.round(4)}, #{point.latitude.to_deg.round(4)}\n"
|
75
|
+
# print "Spherical track #{strack_and_bearing.bearing.to_deg.round(4)} #{strack_and_bearing.distance.round(4)}m from #{next_p.longitude.to_deg.round(4)}, #{next_p.latitude.to_deg.round(4)} to #{point.longitude.to_deg.round(4)}, #{point.latitude.to_deg.round(4)}\n"
|
76
76
|
# puts
|
77
77
|
next_p = point
|
78
78
|
end
|
@@ -85,12 +85,12 @@ class TestVincenty< Test::Unit::TestCase
|
|
85
85
|
flindersPeak = Vincenty.new("-37 57'3.72030″", "144 25'29.52440″" )
|
86
86
|
buninyong = Vincenty.new("-37 39 ' 10.15610 ''", "143 55 ' 35.38390 ''") #Buninyong
|
87
87
|
track_and_bearing = flindersPeak.distanceAndAngle( buninyong )
|
88
|
-
assert_equal(Angle.new("306 52 ' 5.37 ''").
|
88
|
+
assert_equal(Angle.new("306 52 ' 5.37 ''").to_deg.round(4), track_and_bearing.bearing.to_deg.round(4))
|
89
89
|
assert_equal(54972.271, track_and_bearing.distance.round(3))
|
90
90
|
|
91
91
|
destination = flindersPeak.destination(TrackAndDistance.new("306 52 ' 5.37 ''", 54972.271))
|
92
|
-
assert_equal(buninyong.latitude.
|
93
|
-
assert_equal(buninyong.longitude.
|
92
|
+
assert_equal(buninyong.latitude.to_deg.round(4), destination.latitude.to_deg.round(4))
|
93
|
+
assert_equal(buninyong.longitude.to_deg.round(4), destination.longitude.to_deg.round(4))
|
94
94
|
end
|
95
95
|
|
96
96
|
end
|
metadata
CHANGED
@@ -1,49 +1,44 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vincenty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.6
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Rob Burrowes
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-08-23 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: hoe-yard
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 0.1.2
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 0.1.2
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: hoe
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: '3.
|
33
|
+
version: '3.12'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version: '3.
|
46
|
-
description:
|
40
|
+
version: '3.12'
|
41
|
+
description: "* Vincenty wrote an algorithm for calculating the bearing and distance
|
47
42
|
between two coordinates on the earth\n and an algorithm for finding a second coordinate,
|
48
43
|
given a starting coordinate, bearing and destination.\n The algorithms model the
|
49
44
|
earth as an ellipsoid, using the WGS-84 model. This is the common GPS model for\n
|
@@ -73,7 +68,9 @@ extensions: []
|
|
73
68
|
extra_rdoc_files:
|
74
69
|
- History.txt
|
75
70
|
- Manifest.txt
|
71
|
+
- README.md
|
76
72
|
files:
|
73
|
+
- ".gemtest"
|
77
74
|
- History.txt
|
78
75
|
- Manifest.txt
|
79
76
|
- README.md
|
@@ -87,42 +84,41 @@ files:
|
|
87
84
|
- lib/vincenty.rb
|
88
85
|
- test/ts_all.rb
|
89
86
|
- test/ts_angle.rb
|
87
|
+
- test/ts_coordinate.rb
|
90
88
|
- test/ts_latitude.rb
|
91
89
|
- test/ts_longitude.rb
|
92
|
-
- test/ts_vincenty.rb
|
93
|
-
- test/ts_coordinate.rb
|
94
90
|
- test/ts_track_and_distance.rb
|
95
|
-
- .
|
91
|
+
- test/ts_vincenty.rb
|
96
92
|
homepage: http://rbur004.github.com/vincenty/
|
97
|
-
licenses:
|
93
|
+
licenses:
|
94
|
+
- MIT
|
95
|
+
metadata: {}
|
98
96
|
post_install_message:
|
99
97
|
rdoc_options:
|
100
|
-
- --markup
|
98
|
+
- "--markup"
|
101
99
|
- markdown
|
102
|
-
- --protected
|
103
|
-
- --title
|
100
|
+
- "--protected"
|
101
|
+
- "--title"
|
104
102
|
- Vincenty
|
105
|
-
- --quiet
|
103
|
+
- "--quiet"
|
106
104
|
require_paths:
|
107
105
|
- lib
|
108
106
|
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
-
none: false
|
110
107
|
requirements:
|
111
|
-
- -
|
108
|
+
- - ">="
|
112
109
|
- !ruby/object:Gem::Version
|
113
110
|
version: '0'
|
114
111
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
-
none: false
|
116
112
|
requirements:
|
117
|
-
- -
|
113
|
+
- - ">="
|
118
114
|
- !ruby/object:Gem::Version
|
119
115
|
version: '0'
|
120
116
|
requirements: []
|
121
|
-
rubyforge_project:
|
122
|
-
rubygems_version:
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.2.2
|
123
119
|
signing_key:
|
124
|
-
specification_version:
|
125
|
-
summary:
|
126
|
-
|
127
|
-
|
120
|
+
specification_version: 4
|
121
|
+
summary: "* Vincenty wrote an algorithm for calculating the bearing and distance between
|
122
|
+
two coordinates on the earth and an algorithm for finding a second coordinate, given
|
123
|
+
a starting coordinate, bearing and destination"
|
128
124
|
test_files: []
|