geo-distance 0.1.2 → 0.2.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.
Files changed (36) hide show
  1. data/Gemfile +7 -9
  2. data/Gemfile.lock +30 -13
  3. data/README.textile +28 -8
  4. data/VERSION +1 -1
  5. data/geo-distance.gemspec +40 -32
  6. data/lib/geo-distance.rb +14 -132
  7. data/lib/geo-distance/class_methods.rb +71 -0
  8. data/lib/geo-distance/conversion.rb +67 -0
  9. data/lib/geo-distance/conversion/meters.rb +29 -0
  10. data/lib/geo-distance/conversion/radians.rb +36 -0
  11. data/lib/geo-distance/core_ext.rb +12 -23
  12. data/lib/geo-distance/distance.rb +24 -0
  13. data/lib/geo-distance/formula.rb +53 -7
  14. data/lib/geo-distance/formula/flat.rb +21 -0
  15. data/lib/geo-distance/{haversine.rb → formula/haversine.rb} +18 -14
  16. data/lib/geo-distance/formula/n_vector.rb +30 -0
  17. data/lib/geo-distance/formula/spherical.rb +44 -0
  18. data/lib/geo-distance/formula/vincenty.rb +80 -0
  19. data/lib/geo-distance/scale.rb +18 -0
  20. data/spec/geo_distance/class_methods_spec.rb +70 -0
  21. data/spec/geo_distance/core_ext_spec.rb +65 -0
  22. data/spec/geo_distance/distance_spec.rb +74 -0
  23. data/spec/geo_distance/formula/flat_spec.rb +31 -0
  24. data/spec/geo_distance/formula/haversine_spec.rb +33 -0
  25. data/spec/geo_distance/formula/n_vector.rb +33 -0
  26. data/spec/geo_distance/formula/spherical_spec.rb +33 -0
  27. data/spec/geo_distance/formula/vincenty_spec.rb +33 -0
  28. data/spec/spec_helper.rb +0 -10
  29. metadata +97 -96
  30. data/lib/geo-distance/spherical.rb +0 -24
  31. data/lib/geo-distance/vincenty.rb +0 -79
  32. data/spec/core_ext_spec.rb +0 -9
  33. data/spec/dist_default_spec.rb +0 -23
  34. data/spec/dist_haversine_spec.rb +0 -21
  35. data/spec/dist_spherical_spec.rb +0 -21
  36. data/spec/dist_vincenty_spec.rb +0 -21
@@ -1,24 +0,0 @@
1
- require 'geo-distance/core_ext'
2
- require 'geo-distance/formula'
3
-
4
- module GeoDistance
5
- class Spherical < DistanceFormula
6
- def self.distance( lat1, lon1, lat2, lon2)
7
- from_longitude = lon1.to_radians
8
- from_latitude = lat1.to_radians
9
- to_longitude = lon2.to_radians
10
- to_latitude = lat2.to_radians
11
-
12
- c = Math.acos(
13
- Math.sin(from_latitude) *
14
- Math.sin(to_latitude) +
15
-
16
- Math.cos(from_latitude) *
17
- Math.cos(to_latitude) *
18
- Math.cos(to_longitude - from_longitude)
19
- ) #* EARTH_RADIUS[units.to_sym]
20
-
21
- GeoDistance::Distance.new c
22
- end
23
- end
24
- end
@@ -1,79 +0,0 @@
1
- require 'geo-distance/core_ext'
2
- require 'geo-distance/formula'
3
-
4
- module GeoDistance
5
- class Vincenty < DistanceFormula
6
-
7
- # Calculate the distance between two Locations using the Vincenty formula
8
- #
9
- # Graticule::Distance::Vincenty.distance(
10
- # Graticule::Location.new(:latitude => 42.7654, :longitude => -86.1085),
11
- # Graticule::Location.new(:latitude => 41.849838, :longitude => -87.648193)
12
- # )
13
- # #=> 101.070118000159
14
- #
15
- def self.distance(lat1, lon1, lat2, lon2)
16
- from_longitude = lon1.to_radians
17
- from_latitude = lat1.to_radians
18
- to_longitude = lon2.to_radians
19
- to_latitude = lat2.to_radians
20
-
21
- earth_major_axis_radius = EARTH_MAJOR_AXIS_RADIUS[:kilometers]
22
- earth_minor_axis_radius = EARTH_MINOR_AXIS_RADIUS[:kilometers]
23
-
24
- f = (earth_major_axis_radius - earth_minor_axis_radius) / earth_major_axis_radius
25
-
26
- l = to_longitude - from_longitude
27
- u1 = atan((1-f) * tan(from_latitude))
28
- u2 = atan((1-f) * tan(to_latitude))
29
- sin_u1 = sin(u1)
30
- cos_u1 = cos(u1)
31
- sin_u2 = sin(u2)
32
- cos_u2 = cos(u2)
33
-
34
- lambda = l
35
- lambda_p = 2 * PI
36
- iteration_limit = 20
37
- while (lambda-lambda_p).abs > 1e-12 && (iteration_limit -= 1) > 0
38
- sin_lambda = sin(lambda)
39
- cos_lambda = cos(lambda)
40
- sin_sigma = sqrt((cos_u2*sin_lambda) * (cos_u2*sin_lambda) +
41
- (cos_u1*sin_u2-sin_u1*cos_u2*cos_lambda) * (cos_u1*sin_u2-sin_u1*cos_u2*cos_lambda))
42
- return 0 if sin_sigma == 0 # co-incident points
43
- cos_sigma = sin_u1*sin_u2 + cos_u1*cos_u2*cos_lambda
44
- sigma = atan2(sin_sigma, cos_sigma)
45
- sin_alpha = cos_u1 * cos_u2 * sin_lambda / sin_sigma
46
- cosSqAlpha = 1 - sin_alpha*sin_alpha
47
- cos2SigmaM = cos_sigma - 2*sin_u1*sin_u2/cosSqAlpha
48
-
49
- cos2SigmaM = 0 if cos2SigmaM.nan? # equatorial line: cosSqAlpha=0 (§6)
50
-
51
- c = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha))
52
- lambda_p = lambda
53
- lambda = l + (1-c) * f * sin_alpha *
54
- (sigma + c*sin_sigma*(cos2SigmaM+c*cos_sigma*(-1+2*cos2SigmaM*cos2SigmaM)))
55
- end
56
- # formula failed to converge (happens on antipodal points)
57
- # We'll call Haversine formula instead.
58
- return Haversine.distance(from, to, units) if iteration_limit == 0
59
-
60
- uSq = cosSqAlpha * (earth_major_axis_radius**2 - earth_minor_axis_radius**2) / (earth_minor_axis_radius**2)
61
- a = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)))
62
- b = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)))
63
- delta_sigma = b*sin_sigma*(cos2SigmaM+b/4*(cos_sigma*(-1+2*cos2SigmaM*cos2SigmaM)-
64
- b/6*cos2SigmaM*(-3+4*sin_sigma*sin_sigma)*(-3+4*cos2SigmaM*cos2SigmaM)))
65
-
66
- c = earth_minor_axis_radius * a * (sigma-delta_sigma)
67
-
68
- GeoDistance::Distance.new(c / unkilometer)
69
- end
70
-
71
- private
72
-
73
- def self.unkilometer
74
- 6378.135
75
- end
76
-
77
-
78
- end
79
- end
@@ -1,9 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "GeoDistance core extensions" do
4
- it "should work" do
5
- 5.km.should be_kind_of GeoDistance::Distance
6
- 5.km.distance.should == 5
7
- 5.km.unit.should == :km
8
- end
9
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "GeoDistance default" do
4
- it "should work" do
5
- lon1 = -104.88544
6
- lat1 = 39.06546
7
-
8
- lon2 = -104.80
9
- lat2 = lat1
10
-
11
- GeoDistance.default_algorithm = :haversine
12
-
13
- dist = GeoDistance.distance( lat1, lon1, lat2, lon2 )
14
-
15
- puts "the distance from #{lat1}, #{lon1} to #{lat2}, #{lon2} is: #{dist[:meters].number} meters"
16
-
17
- puts "#{dist[:feet]}"
18
- puts "#{dist.meters}"
19
- puts "#{dist[:km]}"
20
- puts "#{dist[:miles]}"
21
- dist[:km].to_s.should match(/7\.376*/)
22
- end
23
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "GeoDistance::Haversine" do
4
- it "should work" do
5
- lon1 = -104.88544
6
- lat1 = 39.06546
7
-
8
- lon2 = -104.80
9
- lat2 = lat1
10
-
11
- dist = GeoDistance::Haversine.distance( lat1, lon1, lat2, lon2 )
12
-
13
- puts "the distance from #{lat1}, #{lon1} to #{lat2}, #{lon2} is: #{dist[:meters].number} meters"
14
-
15
- puts "#{dist[:feet]}"
16
- puts "#{dist.meters}"
17
- puts "#{dist[:km]}"
18
- puts "#{dist[:miles]}"
19
- dist[:km].to_s.should match(/7\.376*/)
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "GeoDistance::Spherical" do
4
- it "should work" do
5
- lon1 = -104.88544
6
- lat1 = 39.06546
7
-
8
- lon2 = -104.80
9
- lat2 = lat1
10
-
11
- dist = GeoDistance::Spherical.distance( lat1, lon1, lat2, lon2 )
12
-
13
- puts "the distance from #{lat1}, #{lon1} to #{lat2}, #{lon2} is: #{dist[:meters].number} meters"
14
-
15
- puts "#{dist[:feet]}"
16
- puts "#{dist.meters}"
17
- puts "#{dist[:km]}"
18
- puts "#{dist[:miles]}"
19
- dist[:km].to_s.should match(/7\.376*/)
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "GeoDistance::Vincenty" do
4
- it "should work" do
5
- lon1 = -104.88544
6
- lat1 = 39.06546
7
-
8
- lon2 = -104.80
9
- lat2 = lat1
10
-
11
- dist = GeoDistance::Vincenty.distance( lat1, lon1, lat2, lon2 )
12
-
13
- puts "the distance from #{lat1}, #{lon1} to #{lat2}, #{lon2} is: #{dist[:meters].number} meters"
14
-
15
- puts "#{dist[:feet]}"
16
- puts "#{dist.meters}"
17
- puts "#{dist[:km]}"
18
- puts "#{dist[:miles]}"
19
- dist[:km].to_s.should match(/7\.38*/)
20
- end
21
- end