geo_calc 0.6.1 → 0.7.1
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.
- data/Gemfile +3 -0
- data/README.textile +12 -0
- data/VERSION +1 -1
- data/geo_calc.gemspec +29 -6
- data/lib/geo_calc/calc/destination.rb +1 -1
- data/lib/geo_calc/calc/distance.rb +1 -1
- data/lib/geo_calc/calc/rhumb.rb +2 -2
- data/lib/geo_calc/calc.rb +20 -21
- data/lib/geo_calc/dms/converter.rb +106 -0
- data/lib/geo_calc/dms.rb +5 -0
- data/lib/geo_calc/extensions/array.rb +26 -0
- data/lib/geo_calc/extensions/hash.rb +23 -0
- data/lib/geo_calc/extensions/math.rb +6 -0
- data/lib/geo_calc/extensions/numeric.rb +24 -0
- data/lib/geo_calc/extensions/string.rb +44 -0
- data/lib/geo_calc/extensions/symbol.rb +9 -0
- data/lib/geo_calc/extensions.rb +4 -0
- data/lib/geo_calc/geo_point/class_methods.rb +15 -0
- data/lib/geo_calc/geo_point/core_extension.rb +11 -0
- data/lib/geo_calc/geo_point/shared.rb +29 -0
- data/lib/geo_calc/geo_point.rb +42 -40
- data/lib/geo_calc/pretty_print.rb +2 -2
- data/lib/geo_calc.rb +5 -0
- data/lib/geo_units/converter.rb +123 -0
- data/lib/geo_units/numeric_ext.rb +117 -0
- data/lib/geo_units.rb +21 -0
- data/spec/geo_calc/core_ext/numeric_geo_ext_spec.rb +48 -50
- data/spec/geo_calc/core_ext_spec.rb +49 -51
- data/spec/geo_calc/dms/converter_spec.rb +60 -0
- data/spec/geo_calc/geo_point/class_methods_spec.rb +31 -0
- data/spec/geo_calc/geo_point/initializer_spec.rb +148 -0
- data/spec/geo_calc/geo_point/lat_lon.rb +115 -0
- data/spec/geo_calc/geo_point_spec.rb +4 -274
- data/spec/geo_units/converter_spec.rb +57 -0
- metadata +56 -17
- data/lib/geo_calc/core_ext.rb +0 -318
- data/lib/geo_calc/geo.rb +0 -171
- data/spec/geo_calc/geo_spec.rb +0 -99
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geo_calc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,33 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-06-11 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: require_all
|
16
|
+
requirement: &2158917420 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.2.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2158917420
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: sugar-high
|
27
|
+
requirement: &2158916800 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.4.5.2
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2158916800
|
14
36
|
- !ruby/object:Gem::Dependency
|
15
37
|
name: rspec
|
16
|
-
requirement: &
|
38
|
+
requirement: &2158916220 !ruby/object:Gem::Requirement
|
17
39
|
none: false
|
18
40
|
requirements:
|
19
41
|
- - ! '>='
|
@@ -21,10 +43,10 @@ dependencies:
|
|
21
43
|
version: 2.5.0
|
22
44
|
type: :development
|
23
45
|
prerelease: false
|
24
|
-
version_requirements: *
|
46
|
+
version_requirements: *2158916220
|
25
47
|
- !ruby/object:Gem::Dependency
|
26
48
|
name: bundler
|
27
|
-
requirement: &
|
49
|
+
requirement: &2158915520 !ruby/object:Gem::Requirement
|
28
50
|
none: false
|
29
51
|
requirements:
|
30
52
|
- - ! '>='
|
@@ -32,10 +54,10 @@ dependencies:
|
|
32
54
|
version: '1'
|
33
55
|
type: :development
|
34
56
|
prerelease: false
|
35
|
-
version_requirements: *
|
57
|
+
version_requirements: *2158915520
|
36
58
|
- !ruby/object:Gem::Dependency
|
37
59
|
name: jeweler
|
38
|
-
requirement: &
|
60
|
+
requirement: &2158914860 !ruby/object:Gem::Requirement
|
39
61
|
none: false
|
40
62
|
requirements:
|
41
63
|
- - ! '>='
|
@@ -43,10 +65,10 @@ dependencies:
|
|
43
65
|
version: 1.5.2
|
44
66
|
type: :development
|
45
67
|
prerelease: false
|
46
|
-
version_requirements: *
|
68
|
+
version_requirements: *2158914860
|
47
69
|
- !ruby/object:Gem::Dependency
|
48
70
|
name: rcov
|
49
|
-
requirement: &
|
71
|
+
requirement: &2158914180 !ruby/object:Gem::Requirement
|
50
72
|
none: false
|
51
73
|
requirements:
|
52
74
|
- - ! '>='
|
@@ -54,10 +76,10 @@ dependencies:
|
|
54
76
|
version: '0'
|
55
77
|
type: :development
|
56
78
|
prerelease: false
|
57
|
-
version_requirements: *
|
79
|
+
version_requirements: *2158914180
|
58
80
|
- !ruby/object:Gem::Dependency
|
59
81
|
name: rake
|
60
|
-
requirement: &
|
82
|
+
requirement: &2158913340 !ruby/object:Gem::Requirement
|
61
83
|
none: false
|
62
84
|
requirements:
|
63
85
|
- - ! '>='
|
@@ -65,7 +87,7 @@ dependencies:
|
|
65
87
|
version: '0.9'
|
66
88
|
type: :development
|
67
89
|
prerelease: false
|
68
|
-
version_requirements: *
|
90
|
+
version_requirements: *2158913340
|
69
91
|
description: Geo calculations in ruby and javascript
|
70
92
|
email: kmandrup@gmail.com
|
71
93
|
executables: []
|
@@ -91,18 +113,35 @@ files:
|
|
91
113
|
- lib/geo_calc/calc/intersection.rb
|
92
114
|
- lib/geo_calc/calc/midpoint.rb
|
93
115
|
- lib/geo_calc/calc/rhumb.rb
|
94
|
-
- lib/geo_calc/
|
95
|
-
- lib/geo_calc/
|
116
|
+
- lib/geo_calc/dms.rb
|
117
|
+
- lib/geo_calc/dms/converter.rb
|
118
|
+
- lib/geo_calc/extensions.rb
|
119
|
+
- lib/geo_calc/extensions/array.rb
|
120
|
+
- lib/geo_calc/extensions/hash.rb
|
121
|
+
- lib/geo_calc/extensions/math.rb
|
122
|
+
- lib/geo_calc/extensions/numeric.rb
|
123
|
+
- lib/geo_calc/extensions/string.rb
|
124
|
+
- lib/geo_calc/extensions/symbol.rb
|
96
125
|
- lib/geo_calc/geo_point.rb
|
126
|
+
- lib/geo_calc/geo_point/class_methods.rb
|
127
|
+
- lib/geo_calc/geo_point/core_extension.rb
|
128
|
+
- lib/geo_calc/geo_point/shared.rb
|
97
129
|
- lib/geo_calc/pretty_print.rb
|
130
|
+
- lib/geo_units.rb
|
131
|
+
- lib/geo_units/converter.rb
|
132
|
+
- lib/geo_units/numeric_ext.rb
|
98
133
|
- spec/geo_calc/calculations_spec.rb
|
99
134
|
- spec/geo_calc/core_ext/array_ext_spec.rb
|
100
135
|
- spec/geo_calc/core_ext/hash_ext_spec.rb
|
101
136
|
- spec/geo_calc/core_ext/numeric_geo_ext_spec.rb
|
102
137
|
- spec/geo_calc/core_ext/string_ext_spec.rb
|
103
138
|
- spec/geo_calc/core_ext_spec.rb
|
139
|
+
- spec/geo_calc/dms/converter_spec.rb
|
140
|
+
- spec/geo_calc/geo_point/class_methods_spec.rb
|
141
|
+
- spec/geo_calc/geo_point/initializer_spec.rb
|
142
|
+
- spec/geo_calc/geo_point/lat_lon.rb
|
104
143
|
- spec/geo_calc/geo_point_spec.rb
|
105
|
-
- spec/
|
144
|
+
- spec/geo_units/converter_spec.rb
|
106
145
|
- spec/spec_helper.rb
|
107
146
|
- vendor/assets/javascript/geo_calc.js
|
108
147
|
homepage: http://github.com/kristianmandrup/geo_calc
|
@@ -120,7 +159,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
120
159
|
version: '0'
|
121
160
|
segments:
|
122
161
|
- 0
|
123
|
-
hash: -
|
162
|
+
hash: -4137681882050840880
|
124
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
164
|
none: false
|
126
165
|
requirements:
|
@@ -129,7 +168,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
168
|
version: '0'
|
130
169
|
requirements: []
|
131
170
|
rubyforge_project:
|
132
|
-
rubygems_version: 1.8.
|
171
|
+
rubygems_version: 1.8.5
|
133
172
|
signing_key:
|
134
173
|
specification_version: 3
|
135
174
|
summary: Geo calculation library
|
data/lib/geo_calc/core_ext.rb
DELETED
@@ -1,318 +0,0 @@
|
|
1
|
-
module NumericCheckExt
|
2
|
-
def is_numeric? arg
|
3
|
-
arg.is_a? Numeric
|
4
|
-
end
|
5
|
-
|
6
|
-
alias_method :is_num?, :is_numeric?
|
7
|
-
|
8
|
-
def check_numeric! arg
|
9
|
-
raise ArgumentError, "Argument must be Numeric" if !is_numeric? arg
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
module GeoUnits
|
14
|
-
module Converter
|
15
|
-
# Converts numeric degrees to radians
|
16
|
-
def to_rad degrees
|
17
|
-
degrees * Math::PI / 180
|
18
|
-
end
|
19
|
-
alias_method :to_radians, :to_rad
|
20
|
-
alias_method :as_rad, :to_rad
|
21
|
-
alias_method :as_radians, :to_rad
|
22
|
-
alias_method :in_rad, :to_rad
|
23
|
-
alias_method :in_radians, :to_rad
|
24
|
-
|
25
|
-
|
26
|
-
# Converts radians to numeric (signed) degrees
|
27
|
-
# latitude (north to south) from equator +90 up then -90 down (equator again) = 180 then 180 for south = 360 total
|
28
|
-
# longitude (west to east) east +180, west -180 = 360 total
|
29
|
-
def to_deg radians
|
30
|
-
radians * 180 / Math::PI
|
31
|
-
end
|
32
|
-
|
33
|
-
alias_method :to_degrees, :to_deg
|
34
|
-
alias_method :as_deg, :to_deg
|
35
|
-
alias_method :as_degrees, :to_deg
|
36
|
-
alias_method :in_deg, :to_deg
|
37
|
-
alias_method :in_degrees, :to_deg
|
38
|
-
end
|
39
|
-
|
40
|
-
# all degrees between -180 and 180
|
41
|
-
def normalize_lng deg
|
42
|
-
case deg
|
43
|
-
when -360..-180
|
44
|
-
deg % 180
|
45
|
-
when -180..0
|
46
|
-
-180 + (deg % 180)
|
47
|
-
when 0..180
|
48
|
-
deg
|
49
|
-
when 180..360
|
50
|
-
deg % 180
|
51
|
-
else
|
52
|
-
raise ArgumentError, "Degrees #{deg} out of range, must be between -360 to 360"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# all degrees between -90 and 90
|
57
|
-
def normalize_lat deg
|
58
|
-
case deg
|
59
|
-
when -360..-270
|
60
|
-
deg % 90
|
61
|
-
when -270..-180
|
62
|
-
90 - (deg % 90)
|
63
|
-
when -180..-90
|
64
|
-
- (deg % 90)
|
65
|
-
when -90..0
|
66
|
-
-90 + (deg % 90)
|
67
|
-
when 0..90
|
68
|
-
deg
|
69
|
-
when 90..180
|
70
|
-
deg % 90
|
71
|
-
when 180..270
|
72
|
-
- (deg % 90)
|
73
|
-
when 270..360
|
74
|
-
- 90 + (deg % 90)
|
75
|
-
else
|
76
|
-
raise ArgumentError, "Degrees #{deg} out of range, must be between -360 to 360"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def normalize_deg degrees, shift = 0
|
81
|
-
(degrees + shift) % 360
|
82
|
-
end
|
83
|
-
alias_method :normalize_degrees, :normalize_deg
|
84
|
-
end
|
85
|
-
|
86
|
-
module NumericGeoExt
|
87
|
-
def to_dms format = :dms, dp = nil
|
88
|
-
Geo.to_dms self, format, dp
|
89
|
-
end
|
90
|
-
|
91
|
-
def to_lat_dms format = :dms, dp = nil
|
92
|
-
Geo.to_lat self, format, dp
|
93
|
-
end
|
94
|
-
|
95
|
-
def to_lon_dms format = :dms, dp = nil
|
96
|
-
Geo.to_lon self, format, dp
|
97
|
-
end
|
98
|
-
|
99
|
-
# Converts numeric degrees to radians
|
100
|
-
def to_rad
|
101
|
-
self * Math::PI / 180
|
102
|
-
end
|
103
|
-
alias_method :to_radians, :to_rad
|
104
|
-
alias_method :as_rad, :to_rad
|
105
|
-
alias_method :as_radians, :to_rad
|
106
|
-
alias_method :in_rad, :to_rad
|
107
|
-
alias_method :in_radians, :to_rad
|
108
|
-
|
109
|
-
|
110
|
-
# Converts radians to numeric (signed) degrees
|
111
|
-
# latitude (north to south) from equator +90 up then -90 down (equator again) = 180 then 180 for south = 360 total
|
112
|
-
# longitude (west to east) east +180, west -180 = 360 total
|
113
|
-
def to_deg
|
114
|
-
self * 180 / Math::PI
|
115
|
-
end
|
116
|
-
|
117
|
-
alias_method :to_degrees, :to_deg
|
118
|
-
alias_method :as_deg, :to_deg
|
119
|
-
alias_method :as_degrees, :to_deg
|
120
|
-
alias_method :in_deg, :to_deg
|
121
|
-
alias_method :in_degrees, :to_deg
|
122
|
-
|
123
|
-
|
124
|
-
# Formats the significant digits of a number, using only fixed-point notation (no exponential)
|
125
|
-
#
|
126
|
-
# @param {Number} precision: Number of significant digits to appear in the returned string
|
127
|
-
# @returns {String} A string representation of number which contains precision significant digits
|
128
|
-
def to_precision precision
|
129
|
-
self.round(precision).to_s
|
130
|
-
end
|
131
|
-
alias_method :to_fixed, :to_precision
|
132
|
-
|
133
|
-
# all degrees between -180 and 180
|
134
|
-
def normalize_lng
|
135
|
-
case self
|
136
|
-
when -360, 0, 360
|
137
|
-
0
|
138
|
-
when -360..-180
|
139
|
-
self % 180
|
140
|
-
when -180..0
|
141
|
-
-180 + (self % 180)
|
142
|
-
when 0..180
|
143
|
-
self
|
144
|
-
when 180..360
|
145
|
-
self % 180
|
146
|
-
else
|
147
|
-
return (self % 360).normalize_lng if self > 360
|
148
|
-
return (360 - (self % 360)).normalize_lng if self < -360
|
149
|
-
raise ArgumentError, "Degrees #{self} out of range"
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
# all degrees between -90 and 90
|
154
|
-
def normalize_lat
|
155
|
-
case self
|
156
|
-
when -360, 0, 360
|
157
|
-
0
|
158
|
-
when -180, 180
|
159
|
-
0
|
160
|
-
when -360..-270
|
161
|
-
self % 90
|
162
|
-
when -270..-180
|
163
|
-
90 - (self % 90)
|
164
|
-
when -180..-90
|
165
|
-
- (self % 90)
|
166
|
-
when -90..0
|
167
|
-
-90 + (self % 90)
|
168
|
-
when 0..90
|
169
|
-
self
|
170
|
-
when 90..180
|
171
|
-
self % 90
|
172
|
-
when 180..270
|
173
|
-
- (self % 90)
|
174
|
-
when 270..360
|
175
|
-
- 90 + (self % 90)
|
176
|
-
else
|
177
|
-
return (self % 360).normalize_lat if self > 360
|
178
|
-
return (360 - (self % 360)).normalize_lat if self < -360
|
179
|
-
raise ArgumentError, "Degrees #{self} out of range"
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
def normalize_deg shift = 0
|
184
|
-
(self + shift) % 360
|
185
|
-
end
|
186
|
-
alias_method :normalize_degrees, :normalize_deg
|
187
|
-
end
|
188
|
-
|
189
|
-
module Math
|
190
|
-
def self.log10e
|
191
|
-
0.4342944819032518
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
module NumericLatLngExt
|
196
|
-
def to_lat
|
197
|
-
normalize_lat
|
198
|
-
end
|
199
|
-
|
200
|
-
def to_lng
|
201
|
-
normalize_lng
|
202
|
-
end
|
203
|
-
|
204
|
-
def is_between? lower, upper
|
205
|
-
(lower..upper).cover? self
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
class Array
|
210
|
-
def geo_point
|
211
|
-
GeoPoint.new to_lat_lng
|
212
|
-
end
|
213
|
-
|
214
|
-
def to_lat_lng
|
215
|
-
raise "Array must contain at least two elements to be converted to latitude and longitude" if !(size >= 2)
|
216
|
-
[to_lat, to_lng]
|
217
|
-
end
|
218
|
-
|
219
|
-
def to_lat
|
220
|
-
raise "Array must contain at least one element to return the latitude" if empty?
|
221
|
-
first.to_lat
|
222
|
-
end
|
223
|
-
|
224
|
-
def to_lng
|
225
|
-
raise "Array must contain at least two elements to return the longitude" if !self[1]
|
226
|
-
self[1].to_lng
|
227
|
-
end
|
228
|
-
|
229
|
-
def trim
|
230
|
-
join.trim
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
class Symbol
|
235
|
-
def self.lng_symbols
|
236
|
-
[:lon, :long, :lng, :longitude]
|
237
|
-
end
|
238
|
-
|
239
|
-
def self.lat_symbols
|
240
|
-
[:lat, :latitude]
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
class Hash
|
245
|
-
def to_lat_lng
|
246
|
-
[to_lat, to_lng]
|
247
|
-
end
|
248
|
-
|
249
|
-
def to_lat
|
250
|
-
v = Symbol.lat_symbols.select {|key| self[key] }
|
251
|
-
return self[v.first].to_lat if !v.empty?
|
252
|
-
raise "Hash must contain either of the keys: [:lat, :latitude] to be converted to a latitude"
|
253
|
-
end
|
254
|
-
|
255
|
-
def to_lng
|
256
|
-
v = Symbol.lng_symbols.select {|key| self[key] }
|
257
|
-
return self[v.first].to_lng if !v.empty?
|
258
|
-
raise "Hash must contain either of the keys: [:lon, :long, :lng, :longitude] to be converted to a longitude"
|
259
|
-
end
|
260
|
-
|
261
|
-
def geo_point
|
262
|
-
GeoPoint.new to_lat_lng
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
class String
|
267
|
-
def concat *args
|
268
|
-
args.inject(self) do |res, arg|
|
269
|
-
res << arg.to_s
|
270
|
-
res
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
def parse_dms
|
275
|
-
Geo.parse_dms self
|
276
|
-
end
|
277
|
-
|
278
|
-
def to_rad
|
279
|
-
parse_dms.to_rad
|
280
|
-
end
|
281
|
-
|
282
|
-
def trim
|
283
|
-
strip
|
284
|
-
end
|
285
|
-
|
286
|
-
def geo_clean
|
287
|
-
self.gsub(/^\(/, '').gsub(/\)$/, '').trim
|
288
|
-
end
|
289
|
-
|
290
|
-
def geo_point
|
291
|
-
GeoPoint.new to_lat_lng
|
292
|
-
end
|
293
|
-
|
294
|
-
def to_lat_lng
|
295
|
-
geo_clean.split(',').to_lat_lng
|
296
|
-
end
|
297
|
-
|
298
|
-
def to_lat
|
299
|
-
raise "An empty String has no latitude" if empty?
|
300
|
-
geo_clean.parse_dms.to_f.to_lat
|
301
|
-
end
|
302
|
-
|
303
|
-
def to_lng
|
304
|
-
raise "An empty String has no latitude" if empty?
|
305
|
-
geo_clean.parse_dms.to_f.to_lng
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
class Fixnum
|
310
|
-
include NumericGeoExt
|
311
|
-
include NumericLatLngExt
|
312
|
-
end
|
313
|
-
|
314
|
-
class Float
|
315
|
-
include NumericGeoExt
|
316
|
-
include NumericLatLngExt
|
317
|
-
end
|
318
|
-
|
data/lib/geo_calc/geo.rb
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
require 'geo_calc/core_ext'
|
2
|
-
|
3
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
4
|
-
# Geodesy representation conversion functions (c) Chris Veness 2002-2010
|
5
|
-
# - www.movable-type.co.uk/scripts/latlong.html
|
6
|
-
#
|
7
|
-
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
8
|
-
|
9
|
-
# Parses string representing degrees/minutes/seconds into numeric degrees
|
10
|
-
#
|
11
|
-
# This is very flexible on formats, allowing signed decimal degrees, or deg-min-sec optionally
|
12
|
-
# suffixed by compass direction (NSEW). A variety of separators are accepted (eg 3º 37' 09"W)
|
13
|
-
# or fixed-width format without separators (eg 0033709W). Seconds and minutes may be omitted.
|
14
|
-
# (Note minimal validation is done).
|
15
|
-
#
|
16
|
-
# @param {String|Number} dmsStr: Degrees or deg/min/sec in variety of formats
|
17
|
-
# @returns {Number} Degrees as decimal number
|
18
|
-
# @throws ArgumentError
|
19
|
-
|
20
|
-
module Geo
|
21
|
-
extend self
|
22
|
-
extend ::NumericCheckExt
|
23
|
-
include ::NumericCheckExt
|
24
|
-
|
25
|
-
def parse_dms dms_str
|
26
|
-
# check for signed decimal degrees without NSEW, if so return it directly
|
27
|
-
return dms_str if is_numeric?(dms_str)
|
28
|
-
|
29
|
-
# strip off any sign or compass dir'n & split out separate d/m/s
|
30
|
-
dms = dms_str.trim.gsub(/^-/,'').gsub(/[NSEW]$/i,'').split(/[^0-9.,]+/).map(&:trim).map(&:to_f)
|
31
|
-
return nil if dms.empty?
|
32
|
-
|
33
|
-
# and convert to decimal degrees...
|
34
|
-
deg = case dms.length
|
35
|
-
when 3 # interpret 3-part result as d/m/s
|
36
|
-
dms[0]/1 + dms[1]/60 + dms[2]/3600
|
37
|
-
when 2 # interpret 2-part result as d/m
|
38
|
-
dms[0]/1 + dms[1]/60
|
39
|
-
when 1 # just d (possibly decimal) or non-separated dddmmss
|
40
|
-
d = dms[0];
|
41
|
-
# check for fixed-width unseparated format eg 0033709W
|
42
|
-
d = "0#{d}" if (/[NS]/i.match(dms_str)) # - normalise N/S to 3-digit degrees
|
43
|
-
d = "#{d.slice(0,3)/1}#{deg.slice(3,5)/60}#{deg.slice(5)/3600}" if (/[0-9]{7}/.match(deg))
|
44
|
-
d
|
45
|
-
else
|
46
|
-
nil
|
47
|
-
end
|
48
|
-
return nil if !deg
|
49
|
-
deg = (deg * -1) if (/^-|[WS]$/i.match(dms_str.trim)) # take '-', west and south as -ve
|
50
|
-
deg.to_f
|
51
|
-
end
|
52
|
-
|
53
|
-
# Convert decimal degrees to deg/min/sec format
|
54
|
-
# - degree, prime, double-prime symbols are added, but sign is discarded, though no compass
|
55
|
-
# direction is added
|
56
|
-
#
|
57
|
-
#
|
58
|
-
# @param {Number} deg: Degrees
|
59
|
-
# @param {String} [format=dms]: Return value as 'd', 'dm', 'dms'
|
60
|
-
# @param {Number} [dp=0|2|4]: No of decimal places to use - default 0 for dms, 2 for dm, 4 for d
|
61
|
-
# @returns {String} deg formatted as deg/min/secs according to specified format
|
62
|
-
# @throws {TypeError} deg is an object, perhaps DOM object without .value?
|
63
|
-
|
64
|
-
def to_dms deg, format = :dms, dp = nil
|
65
|
-
deg = begin
|
66
|
-
deg.to_f
|
67
|
-
rescue
|
68
|
-
nil
|
69
|
-
end
|
70
|
-
return nil if !deg # give up here if we can't make a number from deg
|
71
|
-
|
72
|
-
# default values
|
73
|
-
format ||= :dms
|
74
|
-
dp = if dp.nil?
|
75
|
-
case format.to_sym
|
76
|
-
when :d
|
77
|
-
4
|
78
|
-
when :dm
|
79
|
-
2
|
80
|
-
else
|
81
|
-
0 # default
|
82
|
-
end
|
83
|
-
end
|
84
|
-
dp ||= 0
|
85
|
-
|
86
|
-
deg = deg.abs # (unsigned result ready for appending compass dir'n)
|
87
|
-
|
88
|
-
case format
|
89
|
-
when :d
|
90
|
-
d = deg.round(dp) # round degrees
|
91
|
-
ds = "0#{d}" if (d <100) # pad with leading zeros
|
92
|
-
ds = "0#{ds}" if (d <10)
|
93
|
-
dms = ds.to_s.concat("\u00B0") # add º symbol
|
94
|
-
when :dm
|
95
|
-
min = (deg*60).round(dp) # convert degrees to minutes & round
|
96
|
-
d = d.to_i
|
97
|
-
d = (min / 60).floor # get component deg/min
|
98
|
-
m = (min % 60).round(dp) # pad with trailing zeros
|
99
|
-
ds = d
|
100
|
-
ms = m
|
101
|
-
ds = "0#{d}" if (d<100) # pad with leading zeros
|
102
|
-
ds = "0#{d}" if (d<10)
|
103
|
-
ms = "0#{m}" if (m<10)
|
104
|
-
dms = ds.to_s.concat("\u00B0", ms, "\u2032") # add º, ' symbols
|
105
|
-
when :dms
|
106
|
-
sec = (deg * 3600).round # convert degrees to seconds & round
|
107
|
-
d = (sec / 3600).floor # get component deg/min/sec
|
108
|
-
m = ((sec / 60) % 60).floor
|
109
|
-
s = (sec % 60).round(dp) # pad with trailing zeros
|
110
|
-
ds = d
|
111
|
-
ms = m
|
112
|
-
ss = s
|
113
|
-
ds = "0#{d}" if (d < 100) # pad with leading zeros
|
114
|
-
ds = "0#{ds}" if (d < 10)
|
115
|
-
ms = "0#{m}" if (m < 10)
|
116
|
-
ss = "0#{s}" if (s < 10)
|
117
|
-
dms = ds.to_s.concat("\u00B0", ms, "\u2032", ss, "\u2033") # add º, ', " symbols
|
118
|
-
end
|
119
|
-
return dms
|
120
|
-
end
|
121
|
-
|
122
|
-
|
123
|
-
# Convert numeric degrees to deg/min/sec latitude (suffixed with N/S)
|
124
|
-
#
|
125
|
-
# @param {Number} deg: Degrees
|
126
|
-
# @param {String} [format=dms]: Return value as 'd', 'dm', 'dms'
|
127
|
-
# @param {Number} [dp=0|2|4]: No of decimal places to use - default 0 for dms, 2 for dm, 4 for d
|
128
|
-
# @returns {String} Deg/min/seconds
|
129
|
-
|
130
|
-
def to_lat deg, format = :dms, dp = 0
|
131
|
-
deg = deg.normalize_lat
|
132
|
-
_lat = to_dms deg, format, dp
|
133
|
-
_lat == '' ? '' : _lat[1..-1] + (deg<0 ? 'S' : 'N') # knock off initial '0' for lat!
|
134
|
-
end
|
135
|
-
|
136
|
-
|
137
|
-
# Convert numeric degrees to deg/min/sec longitude (suffixed with E/W)
|
138
|
-
#
|
139
|
-
# @param {Number} deg: Degrees
|
140
|
-
# @param {String} [format=dms]: Return value as 'd', 'dm', 'dms'
|
141
|
-
# @param {Number} [dp=0|2|4]: No of decimal places to use - default 0 for dms, 2 for dm, 4 for d
|
142
|
-
# @returns {String} Deg/min/seconds
|
143
|
-
|
144
|
-
def to_lon deg, format = :dms, dp = 0
|
145
|
-
deg = deg.normalize_lng
|
146
|
-
lon = to_dms deg, format, dp
|
147
|
-
lon == '' ? '' : lon + (deg<0 ? 'W' : 'E')
|
148
|
-
end
|
149
|
-
|
150
|
-
|
151
|
-
# Convert numeric degrees to deg/min/sec as a bearing (0º..360º)
|
152
|
-
#
|
153
|
-
# @param {Number} deg: Degrees
|
154
|
-
# @param {String} [format=dms]: Return value as 'd', 'dm', 'dms'
|
155
|
-
# @param {Number} [dp=0|2|4]: No of decimal places to use - default 0 for dms, 2 for dm, 4 for d
|
156
|
-
# @returns {String} Deg/min/seconds
|
157
|
-
|
158
|
-
def to_brng deg, format = :dms, dp = 0
|
159
|
-
deg = (deg.to_f + 360) % 360 # normalise -ve values to 180º..360º
|
160
|
-
brng = to_dms deg, format, dp
|
161
|
-
brng.gsub /360/, '0' # just in case rounding took us up to 360º!
|
162
|
-
end
|
163
|
-
|
164
|
-
protected
|
165
|
-
|
166
|
-
include NumericCheckExt
|
167
|
-
end
|
168
|
-
|
169
|
-
# class String
|
170
|
-
# include ::Geo
|
171
|
-
# end
|