modalh 1.0.5 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.5
1
+ 1.1.1
@@ -69,12 +69,24 @@ module H
69
69
 
70
70
  end
71
71
 
72
- [:number, :integer, :date, :logical, :time, :datetime].each do |prefix|
72
+ [:number, :integer, :date, :logical, :time, :datetime, :dms].each do |prefix|
73
73
  define_method :"#{prefix}_h" do |attr, *options|
74
74
  _h prefix, attr, *options
75
75
  end
76
76
  end
77
77
 
78
+ def longitude_h(attr, *args)
79
+ options = args.extract_options!
80
+ options[:longitude] = true
81
+ _h prefix, attr, *(args<<options)
82
+ end
83
+
84
+ def latitude_h(attr, *args)
85
+ options = args.extract_options!
86
+ options[:latitude] = true
87
+ _h prefix, attr, *(args<<options)
88
+ end
89
+
78
90
  # TODO: support special suffix form of units, e.g. _m2 for m^2, for attribute names
79
91
 
80
92
  def units_h(name, units, options={})
data/lib/h/fields.rb CHANGED
@@ -64,6 +64,7 @@ module H
64
64
  end
65
65
  options[:precision] ||= {'m'=>1, 'mm'=>0, 'cm'=>0, 'km'=>3}[options[:units]] # TODO AppSettings
66
66
  declaration.remove_attributes! :h_precision, :units
67
+ # declaration.replace!(:type=>:float)
67
68
  model.units_h declaration.name, options[:units], options
68
69
  end
69
70
 
@@ -83,6 +84,33 @@ module H
83
84
  model.logical_h declaration.name
84
85
  end
85
86
 
87
+ def declare_dms_field(model, declaration)
88
+ options = declaration.attributes.slice(:precision, :longitude, :latitude)
89
+ if precision = declaration.attributes[:h_precision]
90
+ options[:precision] = precision
91
+ end
92
+ declaration.remove_attributes! :h_precision, :longitude, :latitude
93
+ model.dms_h declaration.name, options
94
+ end
95
+
96
+ def declare_longitude_field(model, declaration)
97
+ options = declaration.attributes.slice(:precision).merge(:longitude=>true)
98
+ if precision = declaration.attributes[:h_precision]
99
+ options[:precision] = precision
100
+ end
101
+ declaration.remove_attributes! :h_precision
102
+ model.dms_h declaration.name, options
103
+ end
104
+
105
+ def declare_latitude_field(model, declaration)
106
+ options = declaration.attributes.slice(:precision).merge(:latitude=>true)
107
+ if precision = declaration.attributes[:h_precision]
108
+ options[:precision] = precision
109
+ end
110
+ declaration.remove_attributes! :h_precision
111
+ model.dms_h declaration.name, options
112
+ end
113
+
86
114
  # This is handy to be used in all_fields to make any field with a :units parameter or a valid units suffix a units_h field
87
115
  # (and make other numberic fields _h too); If a field with a suffix corresponding to valid units should not be a measure,
88
116
  # a :units=>nil parameter should be added.
@@ -92,7 +120,9 @@ module H
92
120
  unless declaration.attributes.has_key?(:units)
93
121
  units = declaration.name.to_s.split('_').last
94
122
  end
95
- if units && H::Units.valid?(units)
123
+ if units && units.to_s=='dms'
124
+ declare_dms_field model, declaration
125
+ elsif units && H::Units.valid?(units)
96
126
  declare_units_field model, declaration, units
97
127
  else
98
128
  raise ArgumentError, "Invalid units #{declaration.attributes[:units]} in declaration of #{model.name}" if declaration.attributes[:units]
data/lib/h/h.rb CHANGED
@@ -48,11 +48,12 @@ module H
48
48
  elsif value.respond_to?(:infinite?) && value.infinite?
49
49
  inf = options[:inf] || '∞'
50
50
  return value<0 ? "-#{inf}" : inf
51
- else
51
+ else
52
52
  value = value.to_i if precision==0
53
53
  value = value.to_s
54
54
  value = value[0...-2] if value.end_with?('.0')
55
- end
55
+ end
56
+ # else: TODO recognize nan/infinite values
56
57
  end
57
58
  if options[:delimiter]
58
59
  txt = value.to_s.tr(' ','').tr('.,',options[:separator]+options[:delimiter]).tr(options[:delimiter],'')
@@ -78,11 +79,7 @@ module H
78
79
 
79
80
  return nil if txt.to_s.strip.empty? || txt==options[:blank]
80
81
 
81
- if options[:delimiter]
82
- txt = txt.tr(' ','').tr(options[:delimiter]+options[:separator], ',.').tr(',','')
83
- else
84
- txt = txt.tr(' ','').tr(options[:separator], '.')
85
- end
82
+ txt = numbers_to_ruby(txt.tr(' ',''), options)
86
83
  raise ArgumentError, "Invalid number #{txt}" unless /\A[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?\Z/.match(txt)
87
84
  if type==Float
88
85
  txt.to_f
@@ -169,11 +166,160 @@ module H
169
166
  trues.include?(txt) ? true : falses.include?(txt) ? false : nil
170
167
  end
171
168
 
169
+ def dms_from(txt, options={})
170
+ original_txt = txt
171
+ options = dms_format_options(options).merge(options)
172
+
173
+ return nil if txt.to_s.strip.empty? || txt==options[:blank]
174
+
175
+ neg_signs = [options[:south], options[:west]] << '-'
176
+ pos_signs = [options[:north], options[:east]] << '+'
177
+ neg_signs, pos_signs = [neg_signs, pos_signs].map {|signs|
178
+ (signs.map{|s| s.mb_chars.upcase.to_s} + signs.map{|s| s.mb_chars.downcase.to_s}).uniq
179
+ }
180
+ signs = neg_signs + pos_signs
181
+ seps = Array(options[:deg_seps]) + Array(options[:min_seps]) + Array(options[:sec_seps])
182
+
183
+ neg = false
184
+
185
+ txt = txt.to_s.strip
186
+ neg_signs.each do |sign|
187
+ if txt.start_with?(sign)
188
+ txt = txt[sign.size..-1]
189
+ neg = true
190
+ break
191
+ end
192
+ if txt.end_with?(sign)
193
+ txt = txt[0...-sign.size]
194
+ neg = true
195
+ break
196
+ end
197
+ end
198
+ unless neg
199
+ pos_signs.each do |sign|
200
+ if txt.start_with?(sign)
201
+ txt = txt[sign.size..-1]
202
+ break
203
+ end
204
+ if txt.end_with?(sign)
205
+ txt = txt[0...-sign.size]
206
+ break
207
+ end
208
+ end
209
+ end
210
+
211
+ num_options = number_format_options(options).except(:precision).merge(options)
212
+ txt = numbers_to_ruby(txt.strip, num_options)
213
+
214
+ default_units = 0
215
+
216
+ v = 0
217
+ seps = (seps.map{|s| Regexp.escape(s)}<<"\\s+")*"|"
218
+ scanned_txt = ""
219
+ txt.scan(/((\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)(#{seps})?\s*)/) do |match|
220
+ scanned_txt << match[0]
221
+ number = match[1]
222
+ sep = match[2]
223
+ if Array(options[:deg_seps]).include?(sep)
224
+ units = :deg
225
+ elsif Array(options[:min_seps]).include?(sep)
226
+ units = :min
227
+ elsif Array(options[:sec_seps]).include?(sep)
228
+ units = :sec
229
+ else
230
+ units = DMS_UNITS[default_units]
231
+ end
232
+ raise ArgumentError, "Invalid degrees-minutes-seconds value #{original_txt}" unless units
233
+ default_units = DMS_UNITS.index(units) + 1
234
+ x = number.to_f
235
+ x *= DMS_FACTORS[units]
236
+ v += x
237
+ end
238
+ raise ArgumentError, "Invalid degrees-minutes-seconds value #{original_txt} [#{txt}] [#{scanned_txt}]" unless txt==scanned_txt
239
+ v = -v if neg
240
+ v
241
+ end
242
+
243
+ def longitude_to(value, options={})
244
+ dms_to value, options.merge(:longitude=>true)
245
+ end
246
+
247
+ def latitude_to(value, options={})
248
+ dms_to value, options.merge(:latitude=>true)
249
+ end
250
+
251
+ def dms_to(value, options={})
252
+ longitude = options[:longitude]
253
+ latitude = options[:latitude]
254
+ latitude = true if longitude==false && !options.has_key?(:latitude)
255
+ longitude = true if latitude==false && !options.has_key?(:longitude)
256
+ options = dms_format_options(options).except(:precision).merge(options)
257
+ precision = options[:precision]
258
+
259
+ return options[:blank] || '' if value.nil?
260
+
261
+ if value.kind_of?(String)
262
+ # TODO: recognize nan/infinite values
263
+ value = value.to_f
264
+ else
265
+ if value.respond_to?(:nan?) && value.nan?
266
+ return options[:nan] || "--"
267
+ elsif value.respond_to?(:infinite?) && value.infinite?
268
+ inf = options[:inf] || '∞'
269
+ return value<0 ? "-#{inf}" : inf
270
+ end
271
+ end
272
+ if value.to_s.start_with?('-') # value<0 # we use to_s to handle negative zero
273
+ value = -value
274
+ neg = true
275
+ end
276
+
277
+ deg = value.floor
278
+ value -= deg
279
+ value *= 60
280
+ min = value.floor
281
+ value -= min
282
+ value *= 60
283
+ sec = value.round(SEC_PRECISION)
284
+
285
+ txt = []
286
+
287
+ txt << integer_to(deg, options.except(:precision)) + Array(options[:deg_seps]).first
288
+ if min>0 || sec>0
289
+ txt << integer_to(min, options.except(:precision)) + Array(options[:min_seps]).first
290
+ if sec>0
291
+ txt << number_to(sec, options) + Array(options[:sec_seps]).first
292
+ end
293
+ end
294
+
295
+ txt = txt*" "
296
+
297
+ if longitude || latitude
298
+ if longitude
299
+ letter = neg ? options[:west] : options[:east]
300
+ else
301
+ letter = neg ? options[:south] : options[:north]
302
+ end
303
+ txt = options[:prefix] ? "#{letter} #{txt}" : "#{txt} #{letter}"
304
+ else
305
+ txt = "-#{txt}" if neg
306
+ end
307
+
308
+ txt
309
+ end
310
+
172
311
  # TODO: currency, money, bank accounts, credit card numbers, ...
173
312
 
174
313
  private
175
314
  # include ActionView::Helpers::NumberHelper
176
315
 
316
+ DMS_UNITS = [:deg, :min, :sec]
317
+ DMS_FACTORS = {
318
+ :deg=>1, :min=>1.0/60.0, :sec=>1.0/3600.0
319
+ }
320
+ SEC_EPSILON = 1E-10
321
+ SEC_PRECISION = 10
322
+
177
323
  def number_format_options(options)
178
324
  opt = I18n.translate(:'number.format', :locale => options[:locale])
179
325
  opt.kind_of?(Hash) ? opt : {:separator=>'.'}
@@ -184,6 +330,20 @@ module H
184
330
  opt.kind_of?(Hash) ? opt : {:separator=>'.'}
185
331
  end
186
332
 
333
+ def dms_format_options(options)
334
+ opt = I18n.translate(:'number.dms.format', :locale => options[:locale])
335
+ opt.kind_of?(Hash) ? opt : {
336
+ :deg_seps => ['°', 'º'],
337
+ :min_seps => "'",
338
+ :sec_seps => '"',
339
+ :north => 'N',
340
+ :south => 'S',
341
+ :east => 'E',
342
+ :west => 'W',
343
+ :prefix => false
344
+ }
345
+ end
346
+
187
347
  def round(v, ndec)
188
348
  return v if (v.respond_to?(:nan?) && v.nan?) || (v.respond_to?(:infinite?) && v.infinite?)
189
349
  if ndec
@@ -263,6 +423,15 @@ module H
263
423
  type
264
424
  end
265
425
 
426
+ def numbers_to_ruby(txt, options)
427
+ if options[:delimiter]
428
+ txt = txt.tr(options[:delimiter]+options[:separator], ',.').tr(',','')
429
+ else
430
+ txt = txt.tr(options[:separator], '.')
431
+ end
432
+ txt
433
+ end
434
+
266
435
 
267
436
  end
268
437
 
data/lib/h/helpers.rb CHANGED
@@ -3,7 +3,7 @@ module H
3
3
  # Define methods to_h for H.to, from_h from H.from, xxx_to_h from H.xxx_to, xxx_from_h from H.xxx_from
4
4
  module Helpers
5
5
 
6
- (%w{date number integer logical magnitude}<<nil).each do |type|
6
+ (%w{date number integer logical magnitude dms}<<nil).each do |type|
7
7
  %w{from to}.each do |kind|
8
8
  name = [type,kind].compact*'_'
9
9
  define_method "#{name}_h" do |*args|
data/modalh.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "modalh"
8
- s.version = "1.0.5"
8
+ s.version = "1.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Javier Goizueta"]
12
- s.date = "2012-05-08"
12
+ s.date = "2012-05-10"
13
13
  s.description = "Rails plugin for localization & delocalization of data values"
14
14
  s.email = "jgoizueta@gmail.com"
15
15
  s.extra_rdoc_files = [
data/test/helper.rb CHANGED
@@ -12,6 +12,7 @@ require 'shoulda'
12
12
 
13
13
  require 'i18n'
14
14
  require 'active_support'
15
+ require 'active_support/core_ext/string'
15
16
  require 'bigdecimal'
16
17
 
17
18
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
data/test/test_modalh.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  require 'helper'
2
3
 
3
4
  class TestModalh < Test::Unit::TestCase
@@ -80,4 +81,282 @@ class TestModalh < Test::Unit::TestCase
80
81
  assert_equal -1234.567, H.from("-1,234.567", :delimiter=>',')
81
82
  end
82
83
 
84
+ should "parse dms" do
85
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028\" N")
86
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028\"")
87
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028\"N")
88
+ assert_equal 41.508473, H.dms_from("N 41° 30' 30.5028\"")
89
+ assert_equal 41.508473, H.dms_from("N41° 30' 30.5028\"")
90
+ assert_equal -41.508473, H.dms_from("41° 30' 30.5028\" S")
91
+ assert_equal -41.508473, H.dms_from("-41° 30' 30.5028\"")
92
+ assert_equal -41.508473, H.dms_from("41° 30' 30.5028\"S")
93
+ assert_equal -41.508473, H.dms_from("S 41° 30' 30.5028\"")
94
+ assert_equal -41.508473, H.dms_from("S41° 30' 30.5028\"")
95
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028\" E")
96
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028\"")
97
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028\"E")
98
+ assert_equal 41.508473, H.dms_from("E 41° 30' 30.5028\"")
99
+ assert_equal 41.508473, H.dms_from("E41° 30' 30.5028\"")
100
+ assert_equal -41.508473, H.dms_from("41° 30' 30.5028\" W")
101
+ assert_equal -41.508473, H.dms_from("-41° 30' 30.5028\"")
102
+ assert_equal -41.508473, H.dms_from("41° 30' 30.5028\"W")
103
+ assert_equal -41.508473, H.dms_from("W 41° 30' 30.5028\"")
104
+ assert_equal -41.508473, H.dms_from("W41° 30' 30.5028\"")
105
+
106
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028 N")
107
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028")
108
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028N")
109
+ assert_equal 41.508473, H.dms_from("N 41° 30' 30.5028")
110
+ assert_equal 41.508473, H.dms_from("N41° 30' 30.5028")
111
+ assert_equal -41.508473, H.dms_from("41° 30' 30.5028 S")
112
+ assert_equal -41.508473, H.dms_from("-41° 30' 30.5028")
113
+ assert_equal -41.508473, H.dms_from("41° 30' 30.5028S")
114
+ assert_equal -41.508473, H.dms_from("S 41° 30' 30.5028")
115
+ assert_equal -41.508473, H.dms_from("S41° 30' 30.5028")
116
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028 E")
117
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028")
118
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028E")
119
+ assert_equal 41.508473, H.dms_from("E 41° 30' 30.5028")
120
+ assert_equal 41.508473, H.dms_from("E41° 30' 30.5028")
121
+ assert_equal -41.508473, H.dms_from("41° 30' 30.5028 W")
122
+ assert_equal -41.508473, H.dms_from("-41° 30' 30.5028")
123
+ assert_equal -41.508473, H.dms_from("41° 30' 30.5028W")
124
+ assert_equal -41.508473, H.dms_from("W 41° 30' 30.5028")
125
+ assert_equal -41.508473, H.dms_from("W41° 30' 30.5028")
126
+
127
+ assert_equal 41.508473, H.dms_from("41 30' 30.5028\" N")
128
+ assert_equal 41.508473, H.dms_from("41 30' 30.5028\"")
129
+ assert_equal 41.508473, H.dms_from("41 30' 30.5028\"N")
130
+ assert_equal 41.508473, H.dms_from("N 41 30' 30.5028\"")
131
+ assert_equal 41.508473, H.dms_from("N41 30' 30.5028\"")
132
+ assert_equal -41.508473, H.dms_from("41 30' 30.5028\" S")
133
+ assert_equal -41.508473, H.dms_from("-41 30' 30.5028\"")
134
+ assert_equal -41.508473, H.dms_from("41 30' 30.5028\"S")
135
+ assert_equal -41.508473, H.dms_from("S 41 30' 30.5028\"")
136
+ assert_equal -41.508473, H.dms_from("S41 30' 30.5028\"")
137
+ assert_equal 41.508473, H.dms_from("41 30' 30.5028\" E")
138
+ assert_equal 41.508473, H.dms_from("41 30' 30.5028\"")
139
+ assert_equal 41.508473, H.dms_from("41 30' 30.5028\"E")
140
+ assert_equal 41.508473, H.dms_from("E 41 30' 30.5028\"")
141
+ assert_equal 41.508473, H.dms_from("E41 30' 30.5028\"")
142
+ assert_equal -41.508473, H.dms_from("41 30' 30.5028\" W")
143
+ assert_equal -41.508473, H.dms_from("-41 30' 30.5028\"")
144
+ assert_equal -41.508473, H.dms_from("41 30' 30.5028\"W")
145
+ assert_equal -41.508473, H.dms_from("W 41 30' 30.5028\"")
146
+ assert_equal -41.508473, H.dms_from("W41 30' 30.5028\"")
147
+
148
+ assert_equal 41.775, H.dms_from("41° 46.5'")
149
+ assert_equal 41.775, H.dms_from("41° 46.5' N")
150
+ assert_equal 41.775, H.dms_from("41° 46.5'N")
151
+ assert_equal 41.775, H.dms_from("N41° 46.5'")
152
+ assert_equal 41.775, H.dms_from("N 41° 46.5'")
153
+ assert_equal -41.775, H.dms_from("-41° 46.5'")
154
+ assert_equal -41.775, H.dms_from("41° 46.5' S")
155
+ assert_equal -41.775, H.dms_from("41° 46.5'S")
156
+ assert_equal -41.775, H.dms_from("S41° 46.5'")
157
+ assert_equal -41.775, H.dms_from("S 41° 46.5'")
158
+
159
+ assert_equal 41.775, H.dms_from("41 46.5'")
160
+ assert_equal 41.775, H.dms_from("41 46.5' N")
161
+ assert_equal 41.775, H.dms_from("41 46.5'N")
162
+ assert_equal 41.775, H.dms_from("N41 46.5'")
163
+ assert_equal 41.775, H.dms_from("N 41 46.5'")
164
+ assert_equal -41.775, H.dms_from("-41 46.5'")
165
+ assert_equal -41.775, H.dms_from("41 46.5' S")
166
+ assert_equal -41.775, H.dms_from("41 46.5'S")
167
+ assert_equal -41.775, H.dms_from("S41 46.5'")
168
+ assert_equal -41.775, H.dms_from("S 41 46.5'")
169
+
170
+ assert_equal 41.775, H.dms_from("41° 46.5")
171
+ assert_equal 41.775, H.dms_from("41° 46.5 N")
172
+ assert_equal 41.775, H.dms_from("41° 46.5N")
173
+ assert_equal 41.775, H.dms_from("N41° 46.5")
174
+ assert_equal 41.775, H.dms_from("N 41° 46.5")
175
+ assert_equal -41.775, H.dms_from("-41° 46.5")
176
+ assert_equal -41.775, H.dms_from("41° 46.5 S")
177
+ assert_equal -41.775, H.dms_from("41° 46.5S")
178
+ assert_equal -41.775, H.dms_from("S41° 46.5")
179
+ assert_equal -41.775, H.dms_from("S 41° 46.5")
180
+
181
+ assert_equal 41.775, H.dms_from("41.775°")
182
+ assert_equal 41.775, H.dms_from("41.775° N")
183
+ assert_equal 41.775, H.dms_from("41.775°N")
184
+ assert_equal 41.775, H.dms_from("N41.775°")
185
+ assert_equal 41.775, H.dms_from("N 41.775°")
186
+ assert_equal -41.775, H.dms_from("-41.775°")
187
+ assert_equal -41.775, H.dms_from("41.775° S")
188
+ assert_equal -41.775, H.dms_from("41.775°S")
189
+ assert_equal -41.775, H.dms_from("S41.775°")
190
+ assert_equal -41.775, H.dms_from("S 41.775°")
191
+
192
+ assert_equal 41.775, H.dms_from("41.775")
193
+ assert_equal 41.775, H.dms_from("41.775 N")
194
+ assert_equal 41.775, H.dms_from("41.775N")
195
+ assert_equal 41.775, H.dms_from("N41.775")
196
+ assert_equal 41.775, H.dms_from("N 41.775")
197
+ assert_equal -41.775, H.dms_from("-41.775")
198
+ assert_equal -41.775, H.dms_from("41.775 S")
199
+ assert_equal -41.775, H.dms_from("41.775S")
200
+ assert_equal -41.775, H.dms_from("S41.775")
201
+ assert_equal -41.775, H.dms_from("S 41.775")
202
+
203
+ assert_equal 0.508473, H.dms_from("0° 30' 30.5028\" N")
204
+ assert_equal 0.508473, H.dms_from("0° 30' 30.5028\"")
205
+ assert_equal 0.508473, H.dms_from("0° 30' 30.5028\"N")
206
+ assert_equal 0.508473, H.dms_from("N 0° 30' 30.5028\"")
207
+ assert_equal 0.508473, H.dms_from("N0° 30' 30.5028\"")
208
+ assert_equal -0.508473, H.dms_from("0° 30' 30.5028\" S")
209
+ assert_equal -0.508473, H.dms_from("-0° 30' 30.5028\"")
210
+ assert_equal -0.508473, H.dms_from("0° 30' 30.5028\"S")
211
+ assert_equal -0.508473, H.dms_from("S 0° 30' 30.5028\"")
212
+ assert_equal -0.508473, H.dms_from("S0° 30' 30.5028\"")
213
+ assert_equal 0.508473, H.dms_from("0° 30' 30.5028\" E")
214
+ assert_equal 0.508473, H.dms_from("0° 30' 30.5028\"")
215
+ assert_equal 0.508473, H.dms_from("0° 30' 30.5028\"E")
216
+ assert_equal 0.508473, H.dms_from("E 0° 30' 30.5028\"")
217
+ assert_equal 0.508473, H.dms_from("E0° 30' 30.5028\"")
218
+ assert_equal -0.508473, H.dms_from("0° 30' 30.5028\" W")
219
+ assert_equal -0.508473, H.dms_from("-0° 30' 30.5028\"")
220
+ assert_equal -0.508473, H.dms_from("0° 30' 30.5028\"W")
221
+ assert_equal -0.508473, H.dms_from("W 0° 30' 30.5028\"")
222
+ assert_equal -0.508473, H.dms_from("W0° 30' 30.5028\"")
223
+
224
+ assert_equal 0.508473, H.dms_from("0 30' 30.5028\" N")
225
+ assert_equal 0.508473, H.dms_from("0 30' 30.5028\"")
226
+ assert_equal 0.508473, H.dms_from("0 30' 30.5028\"N")
227
+ assert_equal 0.508473, H.dms_from("N 0 30' 30.5028\"")
228
+ assert_equal 0.508473, H.dms_from("N0 30' 30.5028\"")
229
+ assert_equal -0.508473, H.dms_from("0 30' 30.5028\" S")
230
+ assert_equal -0.508473, H.dms_from("-0 30' 30.5028\"")
231
+ assert_equal -0.508473, H.dms_from("0 30' 30.5028\"S")
232
+ assert_equal -0.508473, H.dms_from("S 0 30' 30.5028\"")
233
+ assert_equal -0.508473, H.dms_from("S0 30' 30.5028\"")
234
+ assert_equal 0.508473, H.dms_from("0 30' 30.5028\" E")
235
+ assert_equal 0.508473, H.dms_from("0 30' 30.5028\"")
236
+ assert_equal 0.508473, H.dms_from("0 30' 30.5028\"E")
237
+ assert_equal 0.508473, H.dms_from("E 0 30' 30.5028\"")
238
+ assert_equal 0.508473, H.dms_from("E0 30' 30.5028\"")
239
+ assert_equal -0.508473, H.dms_from("0 30' 30.5028\" W")
240
+ assert_equal -0.508473, H.dms_from("-0 30' 30.5028\"")
241
+ assert_equal -0.508473, H.dms_from("0 30' 30.5028\"W")
242
+ assert_equal -0.508473, H.dms_from("W 0 30' 30.5028\"")
243
+ assert_equal -0.508473, H.dms_from("W0 30' 30.5028\"")
244
+
245
+ assert_equal 0.508473, H.dms_from("30' 30.5028\" N")
246
+ assert_equal 0.508473, H.dms_from("30' 30.5028\"")
247
+ assert_equal 0.508473, H.dms_from("30' 30.5028\"N")
248
+ assert_equal 0.508473, H.dms_from("N 30' 30.5028\"")
249
+ assert_equal 0.508473, H.dms_from("N30' 30.5028\"")
250
+ assert_equal -0.508473, H.dms_from("30' 30.5028\" S")
251
+ assert_equal -0.508473, H.dms_from("-30' 30.5028\"")
252
+ assert_equal -0.508473, H.dms_from("30' 30.5028\"S")
253
+ assert_equal -0.508473, H.dms_from("S30' 30.5028\"")
254
+ assert_equal -0.508473, H.dms_from("S 30' 30.5028\"")
255
+ assert_equal 0.508473, H.dms_from("30' 30.5028\" E")
256
+ assert_equal 0.508473, H.dms_from("30' 30.5028\"")
257
+ assert_equal 0.508473, H.dms_from("30' 30.5028\"E")
258
+ assert_equal 0.508473, H.dms_from("E 30' 30.5028\"")
259
+ assert_equal 0.508473, H.dms_from("E30' 30.5028\"")
260
+ assert_equal -0.508473, H.dms_from("30' 30.5028\"W")
261
+ assert_equal -0.508473, H.dms_from("W 30' 30.5028\"")
262
+ assert_equal -0.508473, H.dms_from("W30' 30.5028\"")
263
+
264
+ assert_equal 0.5, H.dms_from("30' N")
265
+ assert_equal 0.5, H.dms_from("30'")
266
+ assert_equal 0.5, H.dms_from("30'N")
267
+ assert_equal 0.5, H.dms_from("N 30'")
268
+ assert_equal 0.5, H.dms_from("N30'")
269
+ assert_equal -0.5, H.dms_from("30' S")
270
+ assert_equal -0.5, H.dms_from("-30'")
271
+ assert_equal -0.5, H.dms_from("30'S")
272
+ assert_equal -0.5, H.dms_from("S30'")
273
+ assert_equal -0.5, H.dms_from("S 30'")
274
+ assert_equal 0.5, H.dms_from("30' E")
275
+ assert_equal 0.5, H.dms_from("30'E")
276
+ assert_equal 0.5, H.dms_from("E 30'")
277
+ assert_equal 0.5, H.dms_from("E30'")
278
+ assert_equal -0.5, H.dms_from("30'W")
279
+ assert_equal -0.5, H.dms_from("W 30'")
280
+ assert_equal -0.5, H.dms_from("W30'")
281
+
282
+ assert_equal 0.01235, H.dms_from("44.46\"N")
283
+ assert_equal 0.01235, H.dms_from("44.46\"")
284
+ assert_equal -0.01235, H.dms_from("-44.46\"")
285
+
286
+ assert_equal 0.0, H.dms_from("0° 0' 0\"N")
287
+ assert_equal 0.0, H.dms_from("0° 0' 0.00\"N")
288
+ assert_equal 0.0, H.dms_from("0° 0' 0\"")
289
+ assert_equal 0.0, H.dms_from("0° 0' 0.00\"")
290
+ assert_equal 0.0, H.dms_from("-0° 0' 0\"")
291
+ assert_equal 0.0, H.dms_from("0° 0' 0\"S")
292
+ assert_equal 0.0, H.dms_from("0° 0' 0.00\"S")
293
+ assert_equal 0.0, H.dms_from("S0° 0' 0\"")
294
+ assert_equal 0.0, H.dms_from("S0° 0' 0.00\"")
295
+ assert_equal 0.0, H.dms_from("S 0° 0' 0\"")
296
+ assert_equal 0.0, H.dms_from("S 0° 0' 0.00\"")
297
+ assert_equal 0.0, H.dms_from("0 0' 0\"")
298
+ assert_equal 0.0, H.dms_from("0 0' 0.00\"")
299
+ assert_equal 0.0, H.dms_from("0 0' 0\"N")
300
+ assert_equal 0.0, H.dms_from("0° 0'N")
301
+ assert_equal 0.0, H.dms_from("0° 0.00'N")
302
+ assert_equal 0.0, H.dms_from("0° 0'")
303
+ assert_equal 0.0, H.dms_from("0° 0.00'")
304
+ assert_equal 0.0, H.dms_from("0° 0'S")
305
+ assert_equal 0.0, H.dms_from("0° 0.00' S")
306
+ assert_equal 0.0, H.dms_from("0 0'")
307
+ assert_equal 0.0, H.dms_from("-0° 0'")
308
+ assert_equal 0.0, H.dms_from("-0 0'")
309
+ assert_equal 0.0, H.dms_from("0°")
310
+ assert_equal 0.0, H.dms_from("0°N")
311
+ assert_equal 0.0, H.dms_from("0.00°")
312
+ assert_equal 0.0, H.dms_from("0")
313
+ assert_equal 0.0, H.dms_from("0.0")
314
+ assert_equal 0.0, H.dms_from("0.0N")
315
+ assert_equal 0.0, H.dms_from("0.0S")
316
+ assert_equal 0.0, H.dms_from("0'")
317
+ assert_equal 0.0, H.dms_from("-0.00'")
318
+ assert_equal 0.0, H.dms_from("-0.00\"")
319
+ assert_equal 0.0, H.dms_from("0.00\"")
320
+
321
+ assert_raise(ArgumentError){H.dms_from("zdfseer")}
322
+ assert_raise(ArgumentError){H.dms_from("++0.3")}
323
+ assert_raise(ArgumentError){H.dms_from("+-0.3")}
324
+
325
+ assert_equal 41.508473, H.dms_from("41° 30min 30.5028\" N", :min_seps=>'min')
326
+ assert_equal 41.508473, H.dms_from("41° 30' 30.5028sec N", :sec_seps=>'sec')
327
+ assert_equal -41.508473, H.dms_from("41d 30m 30.5028s S", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d')
328
+ assert_equal -41.508473, H.dms_from("41d 30m 30.5028sS", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d')
329
+ assert_equal -41.508473, H.dms_from("S41d 30m 30.5028s", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d')
330
+ assert_equal 41.508473, H.dms_from("41d 30m 30.5028s N", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d')
331
+ assert_equal 41.508473, H.dms_from("41d 30m 30.5028sN", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d')
332
+ assert_equal -41.508473, H.dms_from("-41d 30m 30.5028s", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d')
333
+ assert_equal -41.508473, H.dms_from("41d 30m 30.5028sX", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d', :south=>'X')
334
+ assert_equal -41.508473, H.dms_from("41d 30m 30.5028s X", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d', :south=>'X')
335
+ assert_equal -41.508473, H.dms_from("41 30m 30.5028s X", :sec_seps=>'s', :min_seps=>'m', :deg_seps=>'d', :south=>'X')
336
+
337
+ end
338
+
339
+ should "format as dms" do
340
+ assert_equal "41° 30' 30.5028\"", H.dms_to(41.508473, :prefix=>false)
341
+ assert_equal "41° 30' 30.5028\"", H.dms_to(41.508473, :prefix=>true)
342
+ assert_equal "-41° 30' 30.5028\"", H.dms_to(-41.508473, :prefix=>false)
343
+ assert_equal "-41° 30' 30.5028\"", H.dms_to(-41.508473, :prefix=>true)
344
+ assert_equal "41° 30' 30.5028\" N", H.dms_to(41.508473, :prefix=>false, :latitude=>true)
345
+ assert_equal "N 41° 30' 30.5028\"", H.dms_to(41.508473, :prefix=>true, :latitude=>true)
346
+ assert_equal "41° 30' 30.5028\" S", H.dms_to(-41.508473, :prefix=>false, :latitude=>true)
347
+ assert_equal "S 41° 30' 30.5028\"", H.dms_to(-41.508473, :prefix=>true, :latitude=>true)
348
+ assert_equal "41° 30' 30.5028\" E", H.dms_to(41.508473, :prefix=>false, :longitude=>true)
349
+ assert_equal "E 41° 30' 30.5028\"", H.dms_to(41.508473, :prefix=>true, :longitude=>true)
350
+ assert_equal "41° 30' 30.5028\" W", H.dms_to(-41.508473, :prefix=>false, :longitude=>true)
351
+ assert_equal "W 41° 30' 30.5028\"", H.dms_to(-41.508473, :prefix=>true, :longitude=>true)
352
+ assert_equal "41° 30' N", H.dms_to(41.5, :prefix=>false, :latitude=>true)
353
+ assert_equal "41° N", H.dms_to(41.0, :prefix=>false, :latitude=>true)
354
+ assert_equal "41° N", H.dms_to(41, :prefix=>false, :latitude=>true)
355
+
356
+ assert_equal "41° 30' 30.50\"", H.dms_to(41.508473, :prefix=>false, :precision=>2)
357
+ assert_equal "41° 30' 30.503\"", H.dms_to(41.508473, :prefix=>false, :precision=>3)
358
+
359
+ end
360
+
361
+
83
362
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modalh
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.1
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-05-08 00:00:00.000000000 Z
12
+ date: 2012-05-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: units-system
@@ -162,7 +162,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
162
  version: '0'
163
163
  segments:
164
164
  - 0
165
- hash: -230677022647937802
165
+ hash: -1742349848663810765
166
166
  required_rubygems_version: !ruby/object:Gem::Requirement
167
167
  none: false
168
168
  requirements: