vincenty 1.0.4 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
data/lib/angle.rb CHANGED
@@ -1,246 +1,259 @@
1
- require 'core_extensions.rb'
1
+ require_relative 'core_extensions.rb'
2
2
 
3
- #Class Angle is a utility class that allows
3
+ # Class Angle is a utility class that allows
4
4
  # * Angle arithmetic ( +,-,*,/,**,% and unary +,-)
5
5
  # * Angle comparison ( <=>, hence, <, >, >=, <=, == )
6
6
  # * Conversion to and from degrees and radians
7
7
  # * Conversion to string as radians or DMS format
8
-
9
8
  class Angle
10
9
  include Comparable
11
-
12
-
13
- attr_accessor :angle #stored in radians
14
- alias :value :angle #Older version of angle used volue rather than angle
15
- alias :value= :angle= #Older version of angle used volue rather than angle
16
-
17
- #angle may be anything that has a to_f and to_radians.
18
- #The Default for angle is degrees, but internally @angle is stored in radians.
19
- #if radians is passed true or :radians, then angle is in radians, not degrees.
20
- def initialize(angle=0, radians=false)
21
- #assumes that we are getting an angle in degrees.
22
- if radians == true || radians == :radians
23
- @angle = angle.to_f #works for String, Fixed, other Angles and for Float.
24
- else
25
- if angle.class == Array
26
- @angle = self.class.decimal_deg(*angle).to_radians #Wild assumption that the array is deg,min,sec.
27
- else
28
- @angle = angle.to_radians #we have a String and Numeric class version of this. Another Angle will work too.
29
- end
30
- end
10
+
11
+ # @return [Float] stored in radians
12
+ attr_accessor :angle
13
+ alias value angle # Older version of angle used volue rather than angle
14
+ alias value= angle= # Older version of angle used volue rather than angle
15
+
16
+ # @param [#to_f,#to_radians] angle may be anything that has a to_f and to_radians.
17
+ # @param [true,false, :radians] radians Angle is in degrees unless radians == true (or set to :radians).
18
+ def initialize(angle = 0, radians = false)
19
+ # assumes that we are getting an angle in degrees.
20
+ @angle = if radians == true || radians == :radians
21
+ angle.to_f # works for String, Fixed, other Angles and for Float.
22
+ elsif angle.instance_of?(Array)
23
+ self.class.decimal_deg(*angle).to_radians
24
+ else
25
+ angle.to_radians # we have a String and Numeric class version of this. Another Angle will work too.
26
+ end
31
27
  end
32
-
33
-
34
- #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
28
+
29
+ # Class level function that converts 4 arguments into decimal degrees.
37
30
  # @return [Float] signed decimal degrees.
38
- def self.decimal_deg(degrees=0, minutes=0, seconds=0, direction='N')
39
- s = { 'N'=>1, 'S'=>-1, 'E'=>1, 'W'=>-1, 'n'=>1, 's'=>-1, 'e'=>1, 'w'=>-1 }
31
+ # @param [Numeric] degrees
32
+ # @param [Numeric] minutes
33
+ # @param [Numeric] seconds
34
+ # @param ['N', 'S', 'E', 'W'] direction Optional, as the direction might be specified by a negative value for degrees
35
+ def self.decimal_deg(degrees = 0, minutes = 0, seconds = 0, direction = 'N')
36
+ s = { 'N' => 1, 'S' => -1, 'E' => 1, 'W' => -1, 'n' => 1, 's' => -1, 'e' => 1, 'w' => -1 }
40
37
  sign = s[direction]
41
- sign = sign == nil ? 1 : sign #Assume 'N' or 'E' if the direction is not set.
42
- #Shouldn't have a negative value for degrees if the direction is specified.
43
- #I am defaulting to the degrees sign if it is set, otherwise the direction given
44
- sign = degrees.sign == -1 || (degrees == 0 && (minutes < 0 || (minutes == 0 && seconds < 0))) ? -1 : sign
45
- sign * (degrees.abs + minutes/60.0 + seconds/3600.0)
38
+ sign = 1 if sign.nil? # Assume 'N' or 'E' if the direction is not set.
39
+ # Shouldn't have a negative value for degrees if the direction is specified.
40
+ # I am defaulting to the degrees sign if it is set, otherwise the direction given
41
+ sign = -1 if degrees.sign == -1 || (degrees == 0 && (minutes < 0 || (minutes == 0 && seconds < 0)))
42
+ return sign * (degrees.abs + (minutes / 60.0) + (seconds / 3600.0))
46
43
  end
47
-
48
- #Class level function that takes an array of [degress,minutes, seconds, direction]
49
- # and returns decimal degrees
44
+
45
+ # Class level function that takes an array of [degress,minutes, seconds, direction] or [degrees,minutes,seconds]
50
46
  # @return [Float] signed decimal degrees.
47
+ # @param [Array] a Array is expanded and passed as degrees,minutes,seconds,direction to Angle#decimal_deg
51
48
  def self.decimal_deg_from_ary(a)
52
- self.decimal_deg(*a)
49
+ return self.decimal_deg(*a)
53
50
  end
54
-
55
- #Class level utility function to return the angle as deg,min,sec
56
- #Assumes decimal degress unless radians == true .
51
+
52
+ # Class level utility function to return the angle as deg,min,sec
53
+ # Assumes decimal degress unless radians == true .
57
54
  # @return [Array] of signed deg, min, sec.
58
- #Nb. * That min will be negative if the angle is negative and deg == 0
55
+ # Nb. * That min will be negative if the angle is negative and deg == 0
59
56
  # * That sec will be negative if the angle is negative and deg == 0 && min == 0
57
+ # @param [#to_f,#to_degrees] angle may be anything that has a to_f and to_radians.
58
+ # @param [true,false, :radians] radians Angle is in degrees unless radians == true (or set to :radians).
60
59
  def self.dms(angle, radians = false)
61
- angle = angle.to_d if radians == true || radians == :radians
60
+ angle = angle.to_f # means Strings, Numeric, and anything accepting a #to_f will work.
61
+ angle = angle.to_degrees if radians == true || radians == :radians
62
62
  v = angle.abs
63
63
  deg = v.floor
64
- min = ((v-deg)*60.0).floor
65
- sec = ((v-deg-min/60.0)*3600.0)
66
-
64
+ min = ((v - deg) * 60.0).floor
65
+ sec = ((v - deg - (min / 60.0)) * 3600.0)
66
+
67
67
  if angle < 0
68
68
  if deg == 0
69
69
  if min == 0
70
70
  sec = -sec
71
71
  else
72
- min = -min
72
+ min = -min
73
73
  end
74
74
  else
75
75
  deg = -deg
76
76
  end
77
77
  end
78
78
 
79
- return deg,min,sec
79
+ return deg, min, sec
80
80
  end
81
-
82
- #Class level function equivalent to Angle.new(r, true)
81
+
82
+ # Class level function equivalent to Angle.new(r, true)
83
83
  # @return [Angle]
84
- def self.radians(r=0) #passed in radians.
85
- 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.
84
+ # @param [#to_f] r Value in radians to create the new Angle class with.
85
+ def self.radians(r = 0)
86
+ return 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
87
  end
87
-
88
- #Class level function equivalent to Angle.new(d, false) or just Angle.new(d)
88
+
89
+ # Class level function equivalent to Angle.new(d, false) or just Angle.new(d)
89
90
  # @return [Angle]
90
- def self.degrees(d=0) #passed in degrees.
91
- self.new(d.to_radians, true)
91
+ # @param [#to_radians] d Angle in degrees, to convert to radians, to create new Angle object from.
92
+ def self.degrees(d = 0)
93
+ return self.new(d.to_radians, true)
92
94
  end
93
-
94
- #Provides test for Module Comparable, giving us <,>,<=,>=,== between angles
95
+
96
+ # Provides test for Module Comparable, giving us <,>,<=,>=,== between angles
95
97
  # @return [true,false]
96
- def <=>(angle)
97
- if angle.class == Angle
98
- @angle <=> angle.angle
99
- else
100
- @angle <=> angle
101
- end
98
+ # @param [Angle,Float] angle Can be another Angle, or a Numeric value to compare @angle with.
99
+ def <=>(other)
100
+ @angle <=> if other.instance_of?(Angle)
101
+ other.angle
102
+ else
103
+ other
104
+ end
102
105
  end
103
106
 
104
- #unary +
105
- # @return [Angle] equivalent to @angle
107
+ # unary +
108
+ # @return [Angle,self] equivalent to @angle
106
109
  def +@
107
- self.class.radians(@angle) #Nb. Not Angle.new, as we want subclasses to return their class, not Angle.
110
+ return self.class.radians(@angle) # Nb. Not Angle.new, as we want subclasses to return their class, not Angle.
108
111
  end
109
-
110
- #Unary -
111
- # @return [Angle] -@angle
112
+
113
+ # Unary -
114
+ # @return [Angle,self] -@angle
112
115
  def -@
113
- self.class.radians(-@angle)
116
+ return self.class.radians(-@angle)
114
117
  end
115
-
118
+
116
119
  # Binary addition operator. Can add angles and numbers, or two angles.
117
- # @return [Angle]
118
- def +(angle)
119
- self.class.radians(@angle + angle)
120
+ # @return [Angle,self]
121
+ # @param [Angle,Numeric] angle
122
+ def +(other)
123
+ return self.class.radians(@angle + other)
120
124
  end
121
-
125
+
122
126
  # Binary subtraction operator. Can add angles and numbers, or two angles.
123
- # @return [Angle]
124
- def -(angle)
125
- self.class.radians(@angle - angle)
127
+ # @return [Angle,self]
128
+ # @param [Angle,Numeric] angle
129
+ def -(other)
130
+ return self.class.radians(@angle - other)
126
131
  end
127
-
132
+
128
133
  # Binary multiply operator. Can add angles and numbers, or two angles.
129
- # @return [Angle]
130
- def *(angle)
131
- self.class.radians(@angle * angle)
134
+ # @return [Angle,self]
135
+ # @param [Angle,Numeric] angle
136
+ def *(other)
137
+ self.class.radians(@angle * other)
132
138
  end
133
-
139
+
134
140
  # Binary power of operator. Can add angles and numbers, or two angles.
135
- # @return [Angle]
136
- def **(angle)
137
- self.class.radians(@angle ** angle)
141
+ # @return [Angle,self]
142
+ # @param [Angle,Numeric] angle
143
+ def **(other)
144
+ self.class.radians(@angle**other)
138
145
  end
139
-
146
+
140
147
  # Binary division operator. Can add angles and numbers, or two angles.
141
- # @return [Angle]
142
- def /(angle)
143
- self.class.radians(@angle / angle)
148
+ # @return [Angle,self]
149
+ # @param [Angle,Numeric] angle
150
+ def /(other)
151
+ self.class.radians(@angle / other)
144
152
  end
145
-
153
+
146
154
  # Binary mod operator. Can add angles and numbers, or two angles.
147
- # @return [Angle]
148
- def %(angle)
149
- self.class.radians(@angle % angle)
155
+ # @return [Angle,self]
156
+ # @param [Angle,Numeric] angle
157
+ def %(other)
158
+ self.class.radians(@angle % other)
150
159
  end
151
-
160
+
152
161
  # @return [Float] angle in degrees
153
162
  def to_degrees
154
163
  @angle.to_degrees
155
164
  end
156
-
165
+
157
166
  # @return [Float] angle in degrees
158
- alias to_d to_degrees
159
-
160
- #Returns: angle in radians
167
+ # alias to_deg to_degrees
168
+ alias to_deg to_degrees
169
+
170
+ # @return [Float] angle in radians
161
171
  def to_radians
162
172
  @angle
163
173
  end
164
174
 
175
+ alias to_rad to_radians
165
176
  alias to_r to_radians
166
-
177
+
167
178
  # Returns @angle as decimal_degrees
168
179
  # @return [Array] of signed Floats: degrees,minutes,seconds
169
- #Nb. * That min will be negative if the angle is negative and deg == 0
180
+ # Nb. * That min will be negative if the angle is negative and deg == 0
170
181
  # * That sec will be negative if the angle is negative and deg == 0 && min == 0
171
- def to_dms
182
+ def to_dms
172
183
  d = to_degrees.abs
173
184
  deg = d.floor
174
- min = ((d-deg)*60).floor
175
- sec = ((d-deg-min/60.0)*3600.0)
176
-
185
+ min = ((d - deg) * 60).floor
186
+ sec = ((d - deg - (min / 60.0)) * 3600.0)
187
+
177
188
  if @angle < 0
178
189
  if deg == 0
179
190
  if min == 0
180
191
  sec = -sec
181
192
  else
182
- min = -min
193
+ min = -min
183
194
  end
184
195
  else
185
196
  deg = -deg
186
197
  end
187
198
  end
188
-
199
+
189
200
  return deg, min, sec
190
201
  end
191
-
202
+
192
203
  # @return [Float] the angle in radians as a float (equivalent to to_radians)
193
204
  alias to_f to_radians
194
-
205
+
195
206
  # @return [Fixnum] the angle truncated to an integer, in radians.
196
207
  def to_i
197
208
  to_radians.to_i
198
209
  end
199
-
210
+
200
211
  # @return [Fixnum] the angle truncated to an integer, in radians.
201
212
  alias to_int to_i
202
-
213
+
203
214
  # @return [Array] the angle parameter as a Float and the @angle parameter from this class.
215
+ # @param [Numeric] angle
204
216
  def coerce(angle)
205
- [Float(angle), @angle]
217
+ [ Float(angle), @angle ]
206
218
  end
207
-
219
+
208
220
  # @return [Fixnum] the sign of the angle. 1 for positive, -1 for negative.
209
221
  def sign
210
222
  @angle.sign
211
223
  end
212
-
224
+
213
225
  # @return [Float] the absolute angle of the angle in radians
214
226
  def abs
215
227
  @angle.abs
216
228
  end
217
-
229
+
218
230
  # @return [Float] angle as compass bearing in radians.
219
- #Compass bearings are clockwise, Math angles are counter clockwise.
231
+ # Compass bearings are clockwise, Math angles are counter clockwise.
220
232
  def to_bearing
221
- self.class.new(Math::PI * 2 - @angle,true)
233
+ self.class.new((Math::PI * 2) - @angle, true)
222
234
  end
223
-
235
+
224
236
  # @return [Float] the reverse angle in radians. i.e. angle + PI (or angle + 180 degrees)
225
237
  def reverse
226
238
  if (angle = @angle + Math::PI) > Math::PI * 2
227
239
  angle -= Math::PI * 2
228
240
  end
229
- return self.class.new(angle,true)
241
+ return self.class.new(angle, true)
230
242
  end
231
-
232
-
243
+
233
244
  # @return [String] angle in radians as a string.
245
+ # @param [String] fmt Optional format string passed to Angle#strf
234
246
  def to_s(fmt = nil)
235
- return to_radians.to_s if(fmt == nil)
247
+ return to_radians.to_s if fmt.nil?
248
+
236
249
  return strf(fmt)
237
250
  end
238
-
239
- #formated output of the angle.
240
- #The default format is a signed deg 0minutes'seconds" with leading 0's in the minutes and seconds and 4 decimal places for seconds.
241
- #formats are:
251
+
252
+ # formated output of the angle.
253
+ # @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.
254
+ # formats are:
242
255
  # * %wd output the degrees as an integer.
243
- # ** where w is 0, 1, 2 or 3 and represents the field width.
256
+ # ** where w is 0, 1, 2 or 3 and represents the field width.
244
257
  # *** 1 is the default, which indicates that at least 1 digit is displayed
245
258
  # *** 2 indicates that at least 2 digits are displayed. 1 to 9 will be displayed as 01 0 to 09 0
246
259
  # *** 3 indicates that at least 4 digits are displayed. 10 to 99 will be displayed as 010 0 to 099 0
@@ -254,8 +267,8 @@ class Angle
254
267
  # * %w.pM outputs minutes as a float .e.g. 01.125'.
255
268
  # * p is the number of decimal places.
256
269
  #
257
- # * %wW outputs secs/60 as a float without the leading '0.'.
258
- # Used with %m like this %2m'%4W , to get minute marker before the decimal places.
270
+ # * %wW outputs secs/60 as a float without the leading '0.'.
271
+ # Used with %m like this %2m'%4W , to get minute marker before the decimal places.
259
272
  # e.g. -37 001'.1167 rather than -37 001.1167'
260
273
  # * p is the number of decimal places.
261
274
  #
@@ -272,133 +285,132 @@ class Angle
272
285
  #
273
286
  # Other strings in the format are printed as is.
274
287
  # @return [String]
275
- def strf(fmt="%d %2m'%2.4s\"")
276
- tokens = fmt.scan(/%[0-9\.]*[%dmsDMNErW]|[^%]*/)
288
+ def strf(fmt = "%d %2m'%2.4s\"")
289
+ tokens = fmt.scan(/%[0-9.]*[%dmsDMNErW]|[^%]*/)
277
290
  have_dir = have_dms = false
278
291
  tokens.collect! do |t|
279
- if t[0,1] == '%' #format
292
+ if t[0, 1] == '%' # format
280
293
  had_dot = false
281
294
  decimals = -1
282
295
  width = -1
283
296
  format = nil
284
297
  t[1..-1].scan(/[0-9]+|\.|[0-9]+|[%dmsDMNErW]/) do |t2|
285
298
  case t2
286
- when /[0-9]+/
287
- if had_dot
288
- decimals = t2.to_i
289
- else
290
- width = t2.to_i
291
- end
292
- when '%'
293
- format = t2
294
- when /[dmsMwW]/
295
- have_dms = true
296
- format = t2
297
- when /[NE]/
298
- have_dir = true
299
- format = t2
300
- when '.'
301
- had_dot = true
302
- when /[Dr]/
303
- format = t2
299
+ when /[0-9]+/
300
+ if had_dot
301
+ decimals = t2.to_i
304
302
  else
305
- raise "unknown format character '#{t2}'" #shouldn't be able to get here.
303
+ width = t2.to_i
304
+ end
305
+ when '%', /[Dr]/
306
+ format = t2
307
+ when /[dmsMwW]/
308
+ have_dms = true
309
+ format = t2
310
+ when /[NE]/
311
+ have_dir = true
312
+ format = t2
313
+ when '.'
314
+ had_dot = true
315
+ else
316
+ raise "unknown format character '#{t2}'" # shouldn't be able to get here.
306
317
  end
307
318
  end
308
- [:format, width, decimals, format]
319
+ [ :format, width, decimals, format ]
309
320
  else
310
- [:filler, t]
321
+ [ :filler, t ]
311
322
  end
312
323
  end
313
324
 
314
- deg,min,sec = to_dms if have_dms
325
+ deg, min, sec = to_dms if have_dms
315
326
 
316
- s = ""
327
+ s = ''
317
328
  tokens.each do |t|
318
- if(t[0] == :format)
329
+ if t[0] == :format
319
330
  case t[3]
320
331
  when '%'
321
332
  s += '%'
322
333
  when 'd'
323
334
  s += s_int(deg, t[1], have_dir)
324
335
  when 'D'
325
- s += s_float(@angle.to_d, t[1], t[2], have_dir)
336
+ s += s_float(@angle.to_deg, t[1], t[2], have_dir)
326
337
  when 'm'
327
338
  s += s_int(min, t[1], have_dir)
328
339
  when 'M'
329
- s += s_float(min + sec/60, t[1], t[2], have_dir)
340
+ s += s_float(min + (sec / 60), t[1], t[2], have_dir)
330
341
  when 'W'
331
- s += s_only_places(sec/60, t[1])
342
+ s += s_only_places(sec / 60, t[1])
332
343
  when 's'
333
344
  s += s_float(sec, t[1], t[2], have_dir)
334
345
  when 'r'
335
346
  s += s_float(@angle, t[1], t[2], have_dir)
336
347
  when 'N'
337
- s += (@angle < 0 ? 'S' : 'N')
348
+ s += (@angle < 0 ? 'S' : 'N')
338
349
  when 'E'
339
350
  s += (@angle < 0 ? 'W' : 'E')
340
351
  end
341
352
  else
342
- s += t[1] #the fillers.
353
+ s += t[1] # the fillers.
343
354
  end
344
355
  end
345
-
356
+
346
357
  return s
347
358
  end
348
-
349
- private
350
- #Output angle_dec as a string to the number of decimal places specified by places.
351
- #Assumes the angle is 0 <= angle_dec < 1
352
- #No leading '0' is output. The string starts with a '.'
353
- #If ploces is -1, then all decimal places are returned.
359
+
360
+ # Output angle_dec as a string to the number of decimal places specified by places.
361
+ # Assumes the angle is 0 <= angle_dec < 1
362
+ # No leading '0' is output. The string starts with a '.' if places is non-zero.
363
+ # If ploces is -1, then all decimal places are returned.
354
364
  # @return [String]
355
- def s_places(angle_dec, places)
356
- if places != -1
357
- places > 0 ? ".%0#{places}d" % (angle_dec * 10 ** places).round : ''
365
+ # @param [Float] angle_dec Angle's fractional part
366
+ # @param [Fixnum] places Number of decimal places to output
367
+ private def s_places(angle_dec, places)
368
+ if places == -1
369
+ angle_dec.to_s[1..-1] # Output all decimal places stripping the leading 0
358
370
  else
359
- angle_dec.to_s[1..-1] #Output all decimal places stripping the leading 0
371
+ places > 0 ? ".%0#{places}d" % (angle_dec * (10**places)).round : ''
360
372
  end
361
373
  end
362
374
 
363
- #return the angle as a string with fixed width decimal portion with leading 0s
364
- #to get at least the width specified
365
- #Prints the number of places after the decimal point rounded to places places.
375
+ # return the angle as a string with fixed width decimal portion with leading 0s
376
+ # to get at least the width specified
377
+ # Prints the number of places after the decimal point rounded to places places.
366
378
  #-1 width means no width format
367
379
  #-1 places means print all decimal places.
368
- #abs means print the absolute value.
380
+ # abs means print the absolute value.
369
381
  # @return [String]
370
- def s_float(angle, width, places, abs)
371
- angle_int, angle_dec = angle.abs.divmod(1)
382
+ # @param [Float] angle In radians
383
+ # @param [Fixnum] width Output field width, padded with leading 0's
384
+ # @param [Fixnum] places Number of decimal places to output
385
+ # @param [true,false] abs Output absolute value.
386
+ private def s_float(angle, width, places, abs)
387
+ _angle_int, angle_dec = angle.abs.divmod(1)
372
388
  f = "%0#{width > 0 ? width : ''}d"
373
- s = (abs == false && angle.sign == -1) ? '-' : '' #catch the case of -0
374
- s += f % angle.abs + s_places(angle_dec, places)
389
+ s = abs == false && angle.sign == -1 ? '-' : '' # catch the case of -0
390
+ return s + (f % angle.abs) + s_places(angle_dec, places)
375
391
  end
376
392
 
377
- #Return the integer part of angle as a string of fixed width
378
- #If abs == true, then return the absolute value.
393
+ # Return the integer part of angle as a string of fixed width
394
+ # If abs == true, then return the absolute value.
379
395
  # @return [Fixnum]
380
- def s_int(angle, width, abs)
396
+ # @param [Float] angle In radians
397
+ # @param [Fixnum] width Output field width, padded with leading 0's
398
+ # @param [true,false] abs Output absolute value.
399
+ private def s_int(angle, width, abs)
381
400
  f = "%0#{width > 0 ? width : ''}d"
382
- s = (abs == false && angle.sign == -1) ? '-' : '' #catch the case of -0
383
- s += f % angle.abs
401
+ s = abs == false && angle.sign == -1 ? '-' : '' # catch the case of -0
402
+ return s + (f % angle.abs)
384
403
  end
385
-
386
- #Return the fractional part of angle as a string,
387
- #to the number of decimal places specified by 'places'.
388
- #No leading '0' is output. The string starts with a '.'
389
- #If ploces is -1, then all decimal places are returned.
404
+
405
+ # Return the fractional part of angle as a string,
406
+ # to the number of decimal places specified by 'places'.
407
+ # No leading '0' is output. The string starts with a '.'
408
+ # If ploces is -1, then all decimal places are returned.
390
409
  # @return [String]
391
- def s_only_places(angle, places)
392
- angle_int, angle_dec = angle.abs.divmod(1)
410
+ # @param [Float] angle In radians
411
+ # @param [Fixnum] places Number of decimal places to output
412
+ private def s_only_places(angle, places)
413
+ _angle_int, angle_dec = angle.abs.divmod(1)
393
414
  s_places(angle_dec, places)
394
415
  end
395
416
  end
396
-
397
-
398
-
399
-
400
-
401
-
402
-
403
-
404
-
data/lib/coordinate.rb CHANGED
@@ -1,35 +1,36 @@
1
+ require_relative 'angle.rb'
1
2
 
2
- require 'angle.rb'
3
-
4
- #Holds the latitude, longitude, and the altitude for the coordinate
3
+ # Holds the latitude, longitude, and the altitude for the coordinate
5
4
  class Coordinate
6
- attr_accessor :latitude, :longitude, :altitude
7
-
8
- #latitude and longitude can be Strings or Numeric, or anything else with to_radians and to_f
9
- #latitude and longitude are in degrees unless radians == true (or set to :radians)
10
- def initialize(latitude=0, longitude=0, altitude=0, radians = false)
11
- @latitude = Latitude.new(latitude,radians)
12
- @longitude = Longitude.new(longitude,radians)
5
+ # @return [Latitude]
6
+ attr_accessor :latitude
7
+ # @return [Longitude]
8
+ attr_accessor :longitude
9
+ # @return [Numeric]
10
+ attr_accessor :altitude
11
+
12
+ # latitude and longitude can be Strings or Numeric, or anything else with to_radians and to_f
13
+ # latitude and longitude are in degrees unless radians == true (or set to :radians)
14
+ def initialize(latitude = 0, longitude = 0, altitude = 0, radians = false)
15
+ @latitude = Latitude.new(latitude, radians)
16
+ @longitude = Longitude.new(longitude, radians)
13
17
  @altitude = altitude.to_f
14
18
  end
15
-
16
- #Returns: Latitude longitude and altitude as a single string.
17
- #Should add an optional format string to this.
19
+
20
+ # @return [String] Latitude longitude and altitude as a single space separated string.
18
21
  def to_s
19
- "#{@latitude.to_s } #{@longitude.to_s} #{@altitude}m"
22
+ "#{@latitude} #{@longitude} #{@altitude}m"
20
23
  end
21
-
22
- #Return coordinate as a 3 member array, with
23
- #members, latitude, longitude and altitude
24
+
25
+ # @return [Latitude, Longitude, Float] with members, latitude, longitude and altitude
24
26
  def to_ary
25
27
  [ @latitude, @longitude, @altitude ]
26
28
  end
27
-
29
+
28
30
  alias to_a to_ary
29
-
30
- #return coordinate a 3 member hash with
31
- #keys :latitude, :longitude, and :altitude
31
+
32
+ # @return [Hash] with keys :latitude, :longitude, and :altitude
32
33
  def to_hash
33
- { :latitude => @latitude, :longitude => @longitude, :altitude => @altitude }
34
+ { latitude: @latitude, longitude: @longitude, altitude: @altitude }
34
35
  end
35
- end
36
+ end