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.
- data/Gemfile +7 -9
- data/Gemfile.lock +30 -13
- data/README.textile +28 -8
- data/VERSION +1 -1
- data/geo-distance.gemspec +40 -32
- data/lib/geo-distance.rb +14 -132
- data/lib/geo-distance/class_methods.rb +71 -0
- data/lib/geo-distance/conversion.rb +67 -0
- data/lib/geo-distance/conversion/meters.rb +29 -0
- data/lib/geo-distance/conversion/radians.rb +36 -0
- data/lib/geo-distance/core_ext.rb +12 -23
- data/lib/geo-distance/distance.rb +24 -0
- data/lib/geo-distance/formula.rb +53 -7
- data/lib/geo-distance/formula/flat.rb +21 -0
- data/lib/geo-distance/{haversine.rb → formula/haversine.rb} +18 -14
- data/lib/geo-distance/formula/n_vector.rb +30 -0
- data/lib/geo-distance/formula/spherical.rb +44 -0
- data/lib/geo-distance/formula/vincenty.rb +80 -0
- data/lib/geo-distance/scale.rb +18 -0
- data/spec/geo_distance/class_methods_spec.rb +70 -0
- data/spec/geo_distance/core_ext_spec.rb +65 -0
- data/spec/geo_distance/distance_spec.rb +74 -0
- data/spec/geo_distance/formula/flat_spec.rb +31 -0
- data/spec/geo_distance/formula/haversine_spec.rb +33 -0
- data/spec/geo_distance/formula/n_vector.rb +33 -0
- data/spec/geo_distance/formula/spherical_spec.rb +33 -0
- data/spec/geo_distance/formula/vincenty_spec.rb +33 -0
- data/spec/spec_helper.rb +0 -10
- metadata +97 -96
- data/lib/geo-distance/spherical.rb +0 -24
- data/lib/geo-distance/vincenty.rb +0 -79
- data/spec/core_ext_spec.rb +0 -9
- data/spec/dist_default_spec.rb +0 -23
- data/spec/dist_haversine_spec.rb +0 -21
- data/spec/dist_spherical_spec.rb +0 -21
- data/spec/dist_vincenty_spec.rb +0 -21
data/Gemfile
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
source "http://rubygems.org"
|
2
|
-
# Add dependencies required to use your gem here.
|
3
|
-
# Example:
|
4
|
-
# gem "activesupport", ">= 2.3.5"
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
gem 'geo_point', '~> 0.2.5'
|
4
|
+
gem 'geo_units', '~> 0.2.4.1'
|
5
|
+
|
8
6
|
group :development do
|
9
|
-
gem "rspec",
|
10
|
-
gem "bundler",
|
11
|
-
gem "jeweler",
|
12
|
-
gem "rcov",
|
7
|
+
gem "rspec", ">= 2.6.0"
|
8
|
+
gem "bundler", "~> 1.0.10"
|
9
|
+
gem "jeweler", "~> 1.6.2"
|
10
|
+
gem "rcov", ">= 0"
|
13
11
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,28 +1,45 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
activesupport (3.0.9)
|
4
5
|
diff-lcs (1.1.2)
|
6
|
+
geo_calc (0.7.6)
|
7
|
+
activesupport (>= 3.0.1)
|
8
|
+
geo_units (~> 0.2.1)
|
9
|
+
i18n
|
10
|
+
require_all (~> 1.2.0)
|
11
|
+
sugar-high (~> 0.4.6.3)
|
12
|
+
geo_point (0.2.5)
|
13
|
+
geo_calc (~> 0.7.5)
|
14
|
+
geo_units (~> 0.2.1)
|
15
|
+
geo_units (0.2.4.1)
|
16
|
+
sugar-high (~> 0.4.6.2)
|
5
17
|
git (1.2.5)
|
6
|
-
|
7
|
-
|
18
|
+
i18n (0.6.0)
|
19
|
+
jeweler (1.6.2)
|
20
|
+
bundler (~> 1.0)
|
8
21
|
git (>= 1.2.5)
|
9
22
|
rake
|
10
|
-
rake (0.
|
23
|
+
rake (0.9.2)
|
11
24
|
rcov (0.9.9)
|
12
|
-
|
13
|
-
|
14
|
-
rspec-
|
15
|
-
rspec-
|
16
|
-
|
17
|
-
rspec-
|
25
|
+
require_all (1.2.0)
|
26
|
+
rspec (2.6.0)
|
27
|
+
rspec-core (~> 2.6.0)
|
28
|
+
rspec-expectations (~> 2.6.0)
|
29
|
+
rspec-mocks (~> 2.6.0)
|
30
|
+
rspec-core (2.6.4)
|
31
|
+
rspec-expectations (2.6.0)
|
18
32
|
diff-lcs (~> 1.1.2)
|
19
|
-
rspec-mocks (2.
|
33
|
+
rspec-mocks (2.6.0)
|
34
|
+
sugar-high (0.4.6.4)
|
20
35
|
|
21
36
|
PLATFORMS
|
22
37
|
ruby
|
23
38
|
|
24
39
|
DEPENDENCIES
|
25
|
-
bundler (~> 1.0.
|
26
|
-
|
40
|
+
bundler (~> 1.0.10)
|
41
|
+
geo_point (~> 0.2.5)
|
42
|
+
geo_units (~> 0.2.4.1)
|
43
|
+
jeweler (~> 1.6.2)
|
27
44
|
rcov
|
28
|
-
rspec (>= 2.
|
45
|
+
rspec (>= 2.6.0)
|
data/README.textile
CHANGED
@@ -10,6 +10,7 @@ The formulas curently supported are
|
|
10
10
|
* _Haversine_
|
11
11
|
* _Spherical_
|
12
12
|
* _Vincenty_
|
13
|
+
* _Flat_
|
13
14
|
|
14
15
|
h2. Install & Usage
|
15
16
|
|
@@ -22,17 +23,36 @@ it "should work" do
|
|
22
23
|
lon2 = -104.80
|
23
24
|
lat2 = lat1
|
24
25
|
|
25
|
-
dist = GeoDistance
|
26
|
+
dist = GeoDistance.distance( lat1, lon1, lat2, lon2 ) # in radians
|
26
27
|
|
27
|
-
|
28
|
+
dist = GeoDistance::Haversine.geo_distance( lat1, lon1, lat2, lon2 ).to_meters
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
# Change to (lng, lat) mode
|
31
|
+
GeoPoint.coord_mode = :lng_lat
|
32
|
+
|
33
|
+
p1, p2 = [[lon1, lat1].geo_point, [lon2, lat2].geo_point]
|
34
|
+
|
35
|
+
dist = GeoDistance::Haversine.geo_distance( lon1, lat1, lon2, lat2)
|
36
|
+
dist = GeoDistance::Haversine.geo_distance( p1, p2).to_miles
|
37
|
+
|
38
|
+
puts "the distance from #{lat1}, #{lon1} to #{lat2}, #{lon2} is: #{dist.meters} meters"
|
39
|
+
|
40
|
+
dist.feet
|
41
|
+
dist.meters
|
42
|
+
dist.kms
|
43
|
+
dist.miles
|
34
44
|
end
|
35
|
-
</pre>
|
45
|
+
</pre>
|
46
|
+
|
47
|
+
h2. Distance API
|
48
|
+
|
49
|
+
The call to distance returns an instance of GeoDistance
|
50
|
+
|
51
|
+
@dist = GeoDistance::Haversine.distance( lat1, lon1, lat2, lon2 )@
|
52
|
+
|
53
|
+
The #kms, #meters, #miles and #feet methods return an instance og GeoUnit
|
54
|
+
|
55
|
+
@dist.kms@
|
36
56
|
|
37
57
|
h3. Setting default algorithm
|
38
58
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/geo-distance.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{geo-distance}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date = %q{2011-
|
11
|
+
s.authors = [%q{Kristian Mandrup}]
|
12
|
+
s.date = %q{2011-06-23}
|
13
13
|
s.description = %q{Calculates the geo distance between two locations using longitude and latitude using Haversine, Speherical or Vincenty formula.
|
14
14
|
This is done using Math formulas without resorting to Active Record or SQL DB functionality}
|
15
15
|
s.email = %q{kmandrup@gmail.com}
|
@@ -28,51 +28,59 @@ This is done using Math formulas without resorting to Active Record or SQL DB fu
|
|
28
28
|
"VERSION",
|
29
29
|
"geo-distance.gemspec",
|
30
30
|
"lib/geo-distance.rb",
|
31
|
+
"lib/geo-distance/class_methods.rb",
|
32
|
+
"lib/geo-distance/conversion.rb",
|
33
|
+
"lib/geo-distance/conversion/meters.rb",
|
34
|
+
"lib/geo-distance/conversion/radians.rb",
|
31
35
|
"lib/geo-distance/core_ext.rb",
|
36
|
+
"lib/geo-distance/distance.rb",
|
32
37
|
"lib/geo-distance/formula.rb",
|
33
|
-
"lib/geo-distance/
|
34
|
-
"lib/geo-distance/
|
35
|
-
"lib/geo-distance/
|
36
|
-
"
|
37
|
-
"
|
38
|
-
"
|
39
|
-
"spec/
|
40
|
-
"spec/
|
38
|
+
"lib/geo-distance/formula/flat.rb",
|
39
|
+
"lib/geo-distance/formula/haversine.rb",
|
40
|
+
"lib/geo-distance/formula/n_vector.rb",
|
41
|
+
"lib/geo-distance/formula/spherical.rb",
|
42
|
+
"lib/geo-distance/formula/vincenty.rb",
|
43
|
+
"lib/geo-distance/scale.rb",
|
44
|
+
"spec/geo_distance/class_methods_spec.rb",
|
45
|
+
"spec/geo_distance/core_ext_spec.rb",
|
46
|
+
"spec/geo_distance/distance_spec.rb",
|
47
|
+
"spec/geo_distance/formula/flat_spec.rb",
|
48
|
+
"spec/geo_distance/formula/haversine_spec.rb",
|
49
|
+
"spec/geo_distance/formula/n_vector.rb",
|
50
|
+
"spec/geo_distance/formula/spherical_spec.rb",
|
51
|
+
"spec/geo_distance/formula/vincenty_spec.rb",
|
41
52
|
"spec/spec_helper.rb"
|
42
53
|
]
|
43
54
|
s.homepage = %q{http://github.com/kristianmandrup/geo-distance}
|
44
|
-
s.licenses = [
|
45
|
-
s.require_paths = [
|
46
|
-
s.rubygems_version = %q{1.
|
55
|
+
s.licenses = [%q{MIT}]
|
56
|
+
s.require_paths = [%q{lib}]
|
57
|
+
s.rubygems_version = %q{1.8.5}
|
47
58
|
s.summary = %q{Calculates the geo distance between two locations using longitude and latitude, using Haversine, Speherical or Vincenty formula}
|
48
|
-
s.test_files = [
|
49
|
-
"spec/core_ext_spec.rb",
|
50
|
-
"spec/dist_default_spec.rb",
|
51
|
-
"spec/dist_haversine_spec.rb",
|
52
|
-
"spec/dist_spherical_spec.rb",
|
53
|
-
"spec/dist_vincenty_spec.rb",
|
54
|
-
"spec/spec_helper.rb"
|
55
|
-
]
|
56
59
|
|
57
60
|
if s.respond_to? :specification_version then
|
58
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
59
61
|
s.specification_version = 3
|
60
62
|
|
61
63
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
62
|
-
s.
|
63
|
-
s.
|
64
|
-
s.add_development_dependency(%q<
|
64
|
+
s.add_runtime_dependency(%q<geo_point>, ["~> 0.2.5"])
|
65
|
+
s.add_runtime_dependency(%q<geo_units>, ["~> 0.2.4.1"])
|
66
|
+
s.add_development_dependency(%q<rspec>, [">= 2.6.0"])
|
67
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.10"])
|
68
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
|
65
69
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
66
70
|
else
|
67
|
-
s.add_dependency(%q<
|
68
|
-
s.add_dependency(%q<
|
69
|
-
s.add_dependency(%q<
|
71
|
+
s.add_dependency(%q<geo_point>, ["~> 0.2.5"])
|
72
|
+
s.add_dependency(%q<geo_units>, ["~> 0.2.4.1"])
|
73
|
+
s.add_dependency(%q<rspec>, [">= 2.6.0"])
|
74
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.10"])
|
75
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
|
70
76
|
s.add_dependency(%q<rcov>, [">= 0"])
|
71
77
|
end
|
72
78
|
else
|
73
|
-
s.add_dependency(%q<
|
74
|
-
s.add_dependency(%q<
|
75
|
-
s.add_dependency(%q<
|
79
|
+
s.add_dependency(%q<geo_point>, ["~> 0.2.5"])
|
80
|
+
s.add_dependency(%q<geo_units>, ["~> 0.2.4.1"])
|
81
|
+
s.add_dependency(%q<rspec>, [">= 2.6.0"])
|
82
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.10"])
|
83
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
|
76
84
|
s.add_dependency(%q<rcov>, [">= 0"])
|
77
85
|
end
|
78
86
|
end
|
data/lib/geo-distance.rb
CHANGED
@@ -1,136 +1,18 @@
|
|
1
|
-
|
2
|
-
# this is global because if computing lots of track point distances, it didn't make
|
3
|
-
# sense to new a Hash each time over potentially 100's of thousands of points
|
1
|
+
require 'geo_point'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
{:km => 6371, :miles => 3956, :feet => 20895592, :meters => 6371000}
|
10
|
-
end
|
3
|
+
class GeoDistance
|
4
|
+
autoload :Conversion, 'geo-distance/conversion'
|
5
|
+
autoload :Scale, 'geo-distance/scale'
|
6
|
+
autoload :ClassMethods, 'geo-distance/class_methods'
|
11
7
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
def radians_ratio unit
|
21
|
-
GeoDistance.radians_per_degree * earth_radius[unit]
|
22
|
-
end
|
23
|
-
|
24
|
-
def default_algorithm= name
|
25
|
-
raise ArgumentError, "Not a valid algorithm. Must be one of: #{algorithms}" if !algorithms.include?(name.to_sym)
|
26
|
-
@default_algorithm = name
|
27
|
-
end
|
28
|
-
|
29
|
-
def distance( lat1, lon1, lat2, lon2)
|
30
|
-
klass = case default_algorithm
|
31
|
-
when :haversine
|
32
|
-
GeoDistance::Haversine
|
33
|
-
when :spherical
|
34
|
-
GeoDistance::Spherical
|
35
|
-
when :vincenty
|
36
|
-
GeoDistance::Vincenty
|
37
|
-
else
|
38
|
-
raise ArgumentError, "Not a valid algorithm. Must be one of: #{algorithms}"
|
39
|
-
end
|
40
|
-
klass.distance lat1, lon1, lat2, lon2
|
41
|
-
end
|
42
|
-
|
43
|
-
def default_algorithm
|
44
|
-
@default_algorithm || :haversine
|
45
|
-
end
|
46
|
-
|
47
|
-
protected
|
48
|
-
|
49
|
-
def algorithms
|
50
|
-
[:haversine, :spherical, :vincenty]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class Distance
|
55
|
-
attr_reader :distance, :unit
|
8
|
+
autoload :Haversine, 'geo-distance/formula/haversine'
|
9
|
+
autoload :Spherical, 'geo-distance/formula/spherical'
|
10
|
+
autoload :Vincenty, 'geo-distance/formula/vincenty'
|
11
|
+
autoload :NVector, 'geo-distance/formula/n_vector'
|
12
|
+
autoload :Flat, 'geo-distance/formula/flat'
|
13
|
+
end
|
56
14
|
|
57
|
-
|
58
|
-
|
59
|
-
|
15
|
+
require 'geo-distance/distance'
|
16
|
+
require 'geo-distance/core_ext'
|
17
|
+
require 'geo-distance/formula'
|
60
18
|
|
61
|
-
raise ArgumentError, "Invalid unit: #{unit} - must be one of #{GeoDistance.units}" if !GeoDistance.units.include?(unit.to_sym)
|
62
|
-
@unit = unit.to_sym
|
63
|
-
end
|
64
|
-
|
65
|
-
def [] key
|
66
|
-
method = :"delta_#{key}"
|
67
|
-
raise ArgumentError, "Invalid unit key #{key}" if !respond_to? method
|
68
|
-
Distance.send "in_#{key}", send(method)
|
69
|
-
end
|
70
|
-
|
71
|
-
GeoDistance.units.each do |unit|
|
72
|
-
class_eval %{
|
73
|
-
def #{unit}
|
74
|
-
self[:#{unit}]
|
75
|
-
end
|
76
|
-
}
|
77
|
-
end
|
78
|
-
|
79
|
-
protected
|
80
|
-
|
81
|
-
# delta between the two points in miles
|
82
|
-
GeoDistance.units.each do |unit|
|
83
|
-
class_eval %{
|
84
|
-
def delta_#{unit}
|
85
|
-
GeoDistance.earth_radius[:#{unit}] * distance
|
86
|
-
end
|
87
|
-
}
|
88
|
-
end
|
89
|
-
|
90
|
-
class << self
|
91
|
-
GeoDistance.units.each do |unit|
|
92
|
-
class_eval %{
|
93
|
-
def in_#{unit} number
|
94
|
-
Unit.new :#{unit}, number
|
95
|
-
end
|
96
|
-
}
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
class Unit
|
101
|
-
attr_accessor :name, :number
|
102
|
-
|
103
|
-
def initialize name, number = 0
|
104
|
-
@name = name
|
105
|
-
@number = number
|
106
|
-
end
|
107
|
-
|
108
|
-
def number
|
109
|
-
@number.round_to(precision[name])
|
110
|
-
end
|
111
|
-
|
112
|
-
def to_s
|
113
|
-
"#{number} #{name}"
|
114
|
-
end
|
115
|
-
|
116
|
-
private
|
117
|
-
|
118
|
-
def precision
|
119
|
-
{
|
120
|
-
:feet => 0,
|
121
|
-
:meters => 2,
|
122
|
-
:km => 4,
|
123
|
-
:miles => 4
|
124
|
-
}
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def self.wants? unit_opts, unit
|
130
|
-
unit_opts == unit || unit_opts[unit]
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
require 'geo-distance/haversine'
|
135
|
-
require 'geo-distance/spherical'
|
136
|
-
require 'geo-distance/vincenty'
|
@@ -0,0 +1,71 @@
|
|
1
|
+
class GeoDistance
|
2
|
+
# this is global because if computing lots of track point distances, it didn't make
|
3
|
+
# sense to new a Hash each time over potentially 100's of thousands of points
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
# radius of the great circle in miles
|
7
|
+
# radius in kilometers...some algorithms use 6367
|
8
|
+
|
9
|
+
def distance(*args)
|
10
|
+
klass = case default_algorithm
|
11
|
+
when :flat
|
12
|
+
GeoDistance::Flat
|
13
|
+
when :haversine
|
14
|
+
GeoDistance::Haversine
|
15
|
+
when :spherical
|
16
|
+
GeoDistance::Spherical
|
17
|
+
when :vincenty
|
18
|
+
GeoDistance::Vincenty
|
19
|
+
when :nvector
|
20
|
+
GeoDistance::NVector
|
21
|
+
else
|
22
|
+
raise ArgumentError, "Not a valid algorithm. Must be one of: #{algorithms}"
|
23
|
+
end
|
24
|
+
klass.distance *args
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_units= name
|
28
|
+
raise ArgumentError, "Not a valid units. Must be one of: #{all_units}" if !all_units.include?(name.to_sym)
|
29
|
+
@default_units = GeoUnits.key(name)
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_units
|
33
|
+
@default_units || :kms
|
34
|
+
end
|
35
|
+
|
36
|
+
def default_algorithm= name
|
37
|
+
raise ArgumentError, "Not a valid algorithm. Must be one of: #{algorithms}" if !algorithms.include?(name.to_sym)
|
38
|
+
@default_algorithm = name
|
39
|
+
end
|
40
|
+
|
41
|
+
def default_algorithm
|
42
|
+
@default_algorithm || :haversine
|
43
|
+
end
|
44
|
+
|
45
|
+
def earth_radius units
|
46
|
+
GeoUnits.earth_radius units
|
47
|
+
end
|
48
|
+
|
49
|
+
def radians_per_degree
|
50
|
+
0.017453293 # PI/180
|
51
|
+
end
|
52
|
+
|
53
|
+
def radians_ratio unit
|
54
|
+
GeoDistance.radians_per_degree * earth_radius[unit]
|
55
|
+
end
|
56
|
+
|
57
|
+
def all_units
|
58
|
+
GeoUnits.all_units
|
59
|
+
end
|
60
|
+
|
61
|
+
def units
|
62
|
+
GeoUnits.units
|
63
|
+
end
|
64
|
+
|
65
|
+
def algorithms
|
66
|
+
[:flat, :haversine, :spherical, :vincenty, :nvector]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
extend ClassMethods
|
71
|
+
end
|