geo_calc 0.5.3 → 0.6.0

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.
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.5.3
4
+ version: 0.6.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-05-22 00:00:00.000000000Z
12
+ date: 2011-05-23 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &2161529760 !ruby/object:Gem::Requirement
16
+ requirement: &2163339360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 2.5.0
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *2161529760
24
+ version_requirements: *2163339360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler
27
- requirement: &2161528940 !ruby/object:Gem::Requirement
27
+ requirement: &2163338880 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '1'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2161528940
35
+ version_requirements: *2163338880
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: jeweler
38
- requirement: &2161528040 !ruby/object:Gem::Requirement
38
+ requirement: &2163338380 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.5.2
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2161528040
46
+ version_requirements: *2163338380
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rcov
49
- requirement: &2161524740 !ruby/object:Gem::Requirement
49
+ requirement: &2163337860 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2161524740
57
+ version_requirements: *2163337860
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &2161524140 !ruby/object:Gem::Requirement
60
+ requirement: &2163337360 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0.9'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2161524140
68
+ version_requirements: *2163337360
69
69
  description: Geo calculations in ruby and javascript
70
70
  email: kmandrup@gmail.com
71
71
  executables: []
@@ -76,6 +76,7 @@ extra_rdoc_files:
76
76
  files:
77
77
  - .document
78
78
  - .rspec
79
+ - Changelog.textile
79
80
  - Gemfile
80
81
  - LICENSE.txt
81
82
  - README.textile
@@ -83,16 +84,27 @@ files:
83
84
  - VERSION
84
85
  - geo_calc.gemspec
85
86
  - lib/geo_calc.rb
86
- - lib/geo_calc/calculations.rb
87
+ - lib/geo_calc/calc.rb
88
+ - lib/geo_calc/calc/bearing.rb
89
+ - lib/geo_calc/calc/destination.rb
90
+ - lib/geo_calc/calc/distance.rb
91
+ - lib/geo_calc/calc/intersection.rb
92
+ - lib/geo_calc/calc/midpoint.rb
93
+ - lib/geo_calc/calc/rhumb.rb
87
94
  - lib/geo_calc/core_ext.rb
88
95
  - lib/geo_calc/geo.rb
89
96
  - lib/geo_calc/geo_point.rb
90
- - lib/geo_calc/js/geo_calc.js
97
+ - lib/geo_calc/pretty_print.rb
91
98
  - spec/geo_calc/calculations_spec.rb
99
+ - spec/geo_calc/core_ext/array_ext_spec.rb
100
+ - spec/geo_calc/core_ext/hash_ext_spec.rb
101
+ - spec/geo_calc/core_ext/numeric_geo_ext_spec.rb
102
+ - spec/geo_calc/core_ext/string_ext_spec.rb
92
103
  - spec/geo_calc/core_ext_spec.rb
93
104
  - spec/geo_calc/geo_point_spec.rb
94
105
  - spec/geo_calc/geo_spec.rb
95
106
  - spec/spec_helper.rb
107
+ - vendor/assets/javascript/geo_calc.js
96
108
  homepage: http://github.com/kristianmandrup/geo_calc
97
109
  licenses:
98
110
  - MIT
@@ -108,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
120
  version: '0'
109
121
  segments:
110
122
  - 0
111
- hash: -3503624259360642159
123
+ hash: 1099117799658716810
112
124
  required_rubygems_version: !ruby/object:Gem::Requirement
113
125
  none: false
114
126
  requirements:
@@ -117,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
129
  version: '0'
118
130
  requirements: []
119
131
  rubyforge_project:
120
- rubygems_version: 1.8.0
132
+ rubygems_version: 1.8.3
121
133
  signing_key:
122
134
  specification_version: 3
123
135
  summary: Geo calculation library
@@ -1,333 +0,0 @@
1
- require 'geo_calc/geo'
2
- require 'geo_calc/core_ext'
3
-
4
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5
- # Latitude/longitude spherical geodesy formulae & scripts (c) Chris Veness 2002-2010
6
- # - www.movable-type.co.uk/scripts/latlong.html
7
- #
8
-
9
- module GeoCalc
10
- # Returns the distance from this point to the supplied point, in km
11
- # (using Haversine formula)
12
- #
13
- # from: Haversine formula - R. W. Sinnott, "Virtues of the Haversine",
14
- # Sky and Telescope, vol 68, no 2, 1984
15
- #
16
- # GeoPoint point: Latitude/longitude of destination point
17
- # - Numeric precision=4: number of significant digits to use for returned value
18
- #
19
- # Returns - Numeric distance in km between this point and destination point
20
-
21
- def distance_to point, precision = 4
22
- # default 4 sig figs reflects typical 0.3% accuracy of spherical model
23
- precision ||= 4
24
-
25
- lat1 = lat.to_rad
26
- lon1 = lon.to_rad
27
-
28
- lat2 = point.lat.to_rad
29
- lon2 = point.lon.to_rad
30
-
31
- dlat = lat2 - lat1
32
- dlon = lon2 - lon1
33
-
34
- a = Math.sin(dlat/2) * Math.sin(dlat/2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dlon/2) * Math.sin(dlon/2)
35
- c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
36
- d = radius * c
37
- d.round(precision)
38
- end
39
-
40
-
41
- # Returns the (initial) bearing from this point to the supplied point, in degrees
42
- # see http:#williams.best.vwh.net/avform.htm#Crs
43
- #
44
- # - Point point: Latitude/longitude of destination point
45
- #
46
- # Returns - Numeric: Initial bearing in degrees from North
47
-
48
- def bearing_to point
49
- lat1 = lat.to_rad
50
- lat2 = point.lat.to_rad
51
- dlon = (point.lon - lon).to_rad
52
-
53
- y = Math.sin(dlon) * Math.cos(lat2)
54
- x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dlon)
55
- bearing = Math.atan2(y, x)
56
-
57
- (bearing.to_deg + 360) % 360
58
- end
59
-
60
-
61
- # Returns final bearing arriving at supplied destination point from this point; the final bearing
62
- # will differ from the initial bearing by varying degrees according to distance and latitude
63
- #
64
- # - GeoPoint point: Latitude/longitude of destination point
65
- #
66
- # Returns Numeric: Final bearing in degrees from North
67
-
68
- def final_bearing_to point
69
- # get initial bearing from supplied point back to this point...
70
- lat1 = point.lat.to_rad
71
- lat2 = lat.to_rad
72
- dlon = (lon - point.lon).to_rad
73
-
74
- y = Math.sin(dlon) * Math.cos(lat2)
75
- x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dlon)
76
- bearing = Math.atan2(y, x)
77
-
78
- # ... & reverse it by adding 180°
79
- (bearing.to_deg+180) % 360
80
- end
81
-
82
-
83
- # Returns the midpoint between this point and the supplied point.
84
- # see http:#mathforum.org/library/drmath/view/51822.html for derivation
85
- #
86
- # - GeoPoint point: Latitude/longitude of destination point
87
- # Returns GeoPoint: Midpoint between this point and the supplied point
88
-
89
- def midpoint_to point
90
- lat1 = lat.to_rad
91
- lon1 = lon.to_rad;
92
- lat2 = point.lat.to_rad
93
- dlon = (point.lon - lon).to_rad
94
-
95
- bx = Math.cos(lat2) * Math.cos(dlon)
96
- by = Math.cos(lat2) * Math.sin(dlon)
97
-
98
- lat3 = Math.atan2(Math.sin(lat1)+Math.sin(lat2), Math.sqrt( (Math.cos(lat1)+bx)*(Math.cos(lat1)+bx) + by*by) )
99
-
100
- lon3 = lon1 + Math.atan2(by, Math.cos(lat1) + bx)
101
-
102
- GeoPoint.new lat3.to_deg, lon3.to_deg
103
- end
104
-
105
-
106
- # Returns the destination point from this point having travelled the given distance (in km) on the
107
- # given initial bearing (bearing may vary before destination is reached)
108
- #
109
- # see http:#williams.best.vwh.net/avform.htm#LL
110
- #
111
- # - Numeric bearing: Initial bearing in degrees
112
- # - Numeric dist: Distance in km
113
- # Returns GeoPoint: Destination point
114
-
115
- def destination_point brng, dist
116
- dist = dist / radius # convert dist to angular distance in radians
117
- brng = brng.to_rad
118
- lat1 = lat.to_rad
119
- lon1 = lon.to_rad
120
-
121
- lat2 = Math.asin( Math.sin(lat1) * Math.cos(dist) + Math.cos(lat1) * Math.sin(dist) * Math.cos(brng) )
122
- lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) * Math.cos(lat1), Math.cos(dist) - Math.sin(lat1) * Math.sin(lat2))
123
-
124
- lon2 = (lon2 + 3*Math::PI) % (2*Math::PI) - Math::PI # normalise to -180...+180
125
-
126
- GeoPoint.new lat2.to_deg, lon2.to_deg
127
- end
128
-
129
-
130
- # Returns the point of intersection of two paths defined by point and bearing
131
- #
132
- # see http:#williams.best.vwh.net/avform.htm#Intersection
133
- #
134
- # @param {LatLon} p1: First point
135
- # @param {Number} brng1: Initial bearing from first point
136
- # @param {LatLon} p2: Second point
137
- # @param {Number} brng2: Initial bearing from second point
138
- # @returns {LatLon} Destination point (null if no unique intersection defined)
139
-
140
- def self.intersection p1, brng1, p2, brng2
141
- lat1 = p1.lat.to_rad
142
- lon1 = p1.lon.to_rad
143
-
144
- lat2 = p2.lat.to_rad
145
- lon2 = p2.lon.to_rad
146
-
147
- brng13 = brng1.to_rad
148
- brng23 = brng2.to_rad
149
-
150
- dlat = lat2-lat1
151
- dlon = lon2-lon1;
152
-
153
- dist12 = 2*Math.asin( Math.sqrt( Math.sin(dlat/2)*Math.sin(dlat/2) + Math.cos(lat1)*Math.cos(lat2)*Math.sin(dlon/2)*Math.sin(dlon/2) ) )
154
- return nil if dist12 == 0
155
-
156
- # initial/final bearings between points
157
- brng_a = begin
158
- Math.acos( ( Math.sin(lat2) - Math.sin(lat1)*Math.cos(dist12) ) / ( Math.sin(dist12)*Math.cos(lat1) ) )
159
- rescue # protect against rounding
160
- 0
161
- end
162
-
163
- brng_b = Math.acos( ( Math.sin(lat1) - Math.sin(lat2)*Math.cos(dist12) ) / ( Math.sin(dist12)*Math.cos(lat2) ) )
164
-
165
- brng12, brng21 = if Math.sin(lon2-lon1) > 0
166
- [brng_a, 2*Math::PI - brng_b]
167
- else
168
- [2*Math::PI - brng_a, brng_b]
169
- end
170
-
171
- alpha1 = (brng13 - brng12 + Math::PI) % (2*Math::PI) - Math::PI # angle 2-1-3
172
- alpha2 = (brng21 - brng23 + Math::PI) % (2*Math::PI) - Math::PI # angle 1-2-3
173
-
174
- return nil if (Math.sin(alpha1)==0 && Math.sin(alpha2)==0) # infinite intersections
175
- return nil if (Math.sin(alpha1)*Math.sin(alpha2) < 0) # ambiguous intersection
176
-
177
- # alpha1 = Math.abs(alpha1);
178
- # alpha2 = Math.abs(alpha2);
179
- # ... Ed Williams takes abs of alpha1/alpha2, but seems to break calculation?
180
-
181
- alpha3 = Math.acos( -Math.cos(alpha1)*Math.cos(alpha2) + Math.sin(alpha1)*Math.sin(alpha2)*Math.cos(dist12) )
182
-
183
- dist13 = Math.atan2( Math.sin(dist12)*Math.sin(alpha1)*Math.sin(alpha2), Math.cos(alpha2)+Math.cos(alpha1)*Math.cos(alpha3) )
184
-
185
- lat3 = Math.asin( Math.sin(lat1)*Math.cos(dist13) + Math.cos(lat1)*Math.sin(dist13)*Math.cos(brng13) )
186
-
187
- dlon13 = Math.atan2( Math.sin(brng13)*Math.sin(dist13)*Math.cos(lat1), Math.cos(dist13)-Math.sin(lat1)*Math.sin(lat3) )
188
-
189
- lon3 = lon1 + dlon13;
190
- lon3 = (lon3 + Math::PI) % (2*Math::PI) - Math::PI # normalise to -180..180º
191
-
192
- GeoPoint.new lat3.to_deg, lon3.to_deg
193
- end
194
-
195
-
196
- # Returns the distance from this point to the supplied point, in km, travelling along a rhumb line
197
- #
198
- # see http:#williams.best.vwh.net/avform.htm#Rhumb
199
- #
200
- # - GeoPoint point: Latitude/longitude of destination point
201
- # Returns Numeric: Distance in km between this point and destination point
202
-
203
- def rhumb_distance_to point
204
- lat1 = lat.to_rad
205
- lat2 = point.lat.to_rad
206
-
207
- dlat = (point.lat-lat).to_rad
208
- dlon = (point.lon-lon).abs.to_rad
209
-
210
- dphi = Math.log(Math.tan(lat2/2 + Math::PI/4) / Math.tan(lat1/2 + Math::PI/4))
211
-
212
- q = begin
213
- dlat / dphi
214
- rescue
215
- Math.cos(lat1) # E-W line gives dPhi=0
216
- end
217
-
218
- # if dlon over 180° take shorter rhumb across 180° meridian:
219
- dlon = 2*Math::PI - dlon if (dlon > Math::PI)
220
-
221
- dist = Math.sqrt(dlat*dlat + q*q*dlon*dlon) * radius;
222
-
223
- dist.round(4) # 4 sig figures reflects typical 0.3% accuracy of spherical model
224
- end
225
-
226
-
227
- # Returns the bearing from this point to the supplied point along a rhumb line, in degrees
228
- #
229
- # - GeoPoint point: Latitude/longitude of destination point
230
- # Returns Numeric: Bearing in degrees from North
231
-
232
- def rhumb_bearing_to point
233
- lat1 = lat.to_rad
234
- lat2 = point.lat.to_rad
235
-
236
- dlon = (point.lon - lon).to_rad
237
-
238
- dphi = Math.log(Math.tan(lat2/2+Math::PI/4) / Math.tan(lat1/2+Math::PI/4))
239
- if dlon.abs > Math::PI
240
- dlon = dlon>0 ? -(2*Math::PI-dlon) : (2*Math::PI+dlon);
241
- end
242
-
243
- brng = Math.atan2(dlon, dphi);
244
-
245
- (brng.to_deg+360) % 360
246
- end
247
-
248
-
249
- # Returns the destination point from this point having travelled the given distance (in km) on the
250
- # given bearing along a rhumb line
251
- #
252
- # @param {Number} brng: Bearing in degrees from North
253
- # @param {Number} dist: Distance in km
254
- # @returns {LatLon} Destination point
255
-
256
- def rhumb_destination_point brng, dist
257
- d = dist / radius # d = angular distance covered on earth's surface
258
- lat1 = lat.to_rad
259
- lon1 = lon.to_rad
260
- brng = brng.to_rad
261
-
262
- lat2 = lat1 + d*Math.cos(brng);
263
- dlat = lat2-lat1;
264
- dphi = Math.log(Math.tan(lat2/2+Math::PI/4)/Math.tan(lat1/2+Math::PI/4))
265
-
266
- q = begin
267
- dlat/dphi
268
- rescue
269
- Math.cos(lat1) # E-W line gives dPhi=0
270
- end
271
-
272
- dlon = d*Math.sin(brng)/q
273
- # check for some daft bugger going past the pole
274
-
275
- if lat2.abs > Math::PI/2
276
- lat2 = lat2>0 ? Math::PI-lat2 : -(Math::PI-lat2)
277
- end
278
- lon2 = (lon1+dlon+3*Math::PI) % (2*Math::PI) - Math::PI
279
-
280
- GeoPoint.new lat2.to_deg, lon2.to_deg
281
- end
282
-
283
-
284
- # Returns the latitude of this point; signed numeric degrees if no format, otherwise format & dp
285
- # as per Geo.to_lat
286
- #
287
- # - String [format]: Return value as 'd', 'dm', 'dms'
288
- # - Numeric [dp=0|2|4]: No of decimal places to display
289
- #
290
- # Returns {Numeric|String}: Numeric degrees if no format specified, otherwise deg/min/sec
291
- #
292
-
293
- def to_lat format = :dms, dp = 0
294
- return lat if !format
295
- Geo.to_lat lat, format, dp
296
- end
297
-
298
-
299
- # Returns the longitude of this point; signed numeric degrees if no format, otherwise format & dp
300
- # as per Geo.toLon()
301
- #
302
- # @param {String} [format]: Return value as 'd', 'dm', 'dms'
303
- # @param {Number} [dp=0|2|4]: No of decimal places to display
304
- # @returns {Number|String} Numeric degrees if no format specified, otherwise deg/min/sec
305
- #
306
- # @requires Geo
307
-
308
- def to_lon format, dp
309
- return lon if !format
310
- Geo.to_lon lon, format, dp
311
- end
312
-
313
-
314
- # Returns a string representation of this point; format and dp as per lat()/lon()
315
- #
316
- # @param {String} [format]: Return value as 'd', 'dm', 'dms'
317
- # @param {Number} [dp=0|2|4]: No of decimal places to display
318
-
319
- # @returns {String} Comma-separated latitude/longitude
320
- #
321
-
322
- def to_s format = :dms, dp = 0
323
- format ||= :dms
324
-
325
- return '-,-' if !lat || !lon
326
-
327
- _lat = Geo.to_lat lat, format, dp
328
- _lon = Geo.to_lon lon, format, dp
329
-
330
- "#{_lat}, #{_lon}"
331
- end
332
- end
333
-