rvincenty 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Reto Schüttel, <reto ät schuettel (DOT) ch>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,37 @@
1
+ = rvincenty
2
+
3
+ This is a ruby implementation of the Vincenty's formulae to calcuclate the distance between
4
+ two points on earth. The formula assumpts that the figure of the Earth is an oblate spheroid
5
+ and is therefore much accurate than other methods which assume a spherical Earth.
6
+
7
+ The code was heavily inspired by Chris Veness Javascript implementation and explainaitions:
8
+
9
+
10
+ [Vincenty formula for distance between two Latitude/Longitude points] http://www.movable-type.co.uk/scripts/latlong-vincenty.html
11
+
12
+ == Usage
13
+
14
+ require 'rvincenty'
15
+
16
+ point_a = 45.965, 63.305 # Baikonur Cosmodrome
17
+ point_b = 28.585, -80.651 # John F. Kennedy Space Center
18
+
19
+ distance = RVincenty.distance(point_a, point_b)
20
+
21
+ puts "Distance between %s and %s is %f km" % [point_a.inspect, point_b.inspect, distance / 1000]
22
+
23
+
24
+ == Note on Patches/Pull Requests
25
+
26
+ * Fork the project.
27
+ * Make your feature addition or bug fix.
28
+ * Add tests for it. This is important so I don't break it in a
29
+ future version unintentionally.
30
+ * Commit, do not mess with rakefile, version, or history.
31
+ (if you want to have your own version, that is fine but
32
+ bump version in a commit by itself I can ignore when I pull)
33
+ * Send me a pull request. Bonus points for topic branches.
34
+
35
+ == Copyright
36
+
37
+ Copyright (c) 2009 Reto Schüttel. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ require 'bundler/setup'
4
+
5
+ require 'rake'
6
+
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |gem|
10
+ gem.name = "rvincenty"
11
+ gem.summary = "Pure Ruby implementation of Vincenty formula to calculate distance between two points"
12
+ gem.description = "rvincenty is a pure ruby implementation of Thaddeus Vincenty's formulae "
13
+ "which caluclates the distance between two points on the earth's surface"
14
+ gem.email = "reto@schuettel.ch"
15
+ gem.homepage = "http://github.com/retoo/rvincenty"
16
+ gem.authors = ["Reto Schüttel"]
17
+ gem.add_development_dependency "yard"
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/*_test.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/*_test.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ task :test => :check_dependencies
45
+
46
+ task :default => :test
47
+
48
+ begin
49
+ require 'yard'
50
+ YARD::Rake::YardocTask.new
51
+ rescue LoadError
52
+ task :yardoc do
53
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
54
+ end
55
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/rvincenty.rb ADDED
@@ -0,0 +1,72 @@
1
+ module RVincenty
2
+ # Calculates the distance between two given points.
3
+ # A point is a two-elmeent array containing the points coordinates (Latitude and Longitutde)
4
+ # experessed as a floating point number.
5
+ def self.distance(point_a, point_b)
6
+ lat1, lon1 = point_a
7
+ lat2, lon2 = point_b
8
+
9
+ # WGS-84 ellipsiod
10
+ a = 6378137.0
11
+ b = 6356752.3142
12
+ f = 1.0/298.257223563
13
+
14
+ l = deg_to_rad(lon2 - lon1)
15
+ u1 = Math.atan((1.0-f) * Math.tan(deg_to_rad(lat1)));
16
+ u2 = Math.atan((1.0-f) * Math.tan(deg_to_rad(lat2)));
17
+
18
+ sinU1 = Math.sin(u1)
19
+ cosU1 = Math.cos(u1)
20
+ sinU2 = Math.sin(u2)
21
+ cosU2 = Math.cos(u2)
22
+
23
+ lambda = l
24
+
25
+ iterLimit = 100
26
+ lambdaP = nil
27
+ while true
28
+ sinLambda = Math.sin(lambda)
29
+ cosLambda = Math.cos(lambda)
30
+
31
+ sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +
32
+ (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda))
33
+
34
+ # co-incident points
35
+ return 0 if (sinSigma==0)
36
+
37
+ cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;
38
+ sigma = Math.atan2(sinSigma, cosSigma);
39
+ sinalpha = cosU1 * cosU2 * sinLambda / sinSigma;
40
+ cosSqalpha = 1.0 - sinalpha*sinalpha;
41
+ cos2SigmaM = cosSigma - 2.0*sinU1*sinU2/cosSqalpha;
42
+ if cos2SigmaM.nan?
43
+ cos2SigmaM = 0
44
+ end
45
+
46
+ c = f/16*cosSqalpha*(4+f*(4-3*cosSqalpha));
47
+ lambdaP = lambda;
48
+ lambda = l + (1.0-c) * f * sinalpha * (sigma + c*sinSigma*(cos2SigmaM+c*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
49
+ iterLimit -= 1
50
+
51
+ break if (lambda-lambdaP).abs < 1e-12 || iterLimit <= 0
52
+ end
53
+
54
+ #formula failed to converge
55
+ return NaN if (iterLimit==0)
56
+
57
+ uSq = cosSqalpha * (a*a - b*b) / (b*b);
58
+ va = 1 + uSq/16384.0*(4096.0+uSq*(-768.0+uSq*(320.0-175.0*uSq)))
59
+ vb = uSq/1024.0 * (256.0+uSq*(-128.0+uSq*(74.0-47.0*uSq)))
60
+ deltaSigma = vb*sinSigma*(cos2SigmaM+vb/4.0*(cosSigma*(-1.0+2.0*cos2SigmaM*cos2SigmaM)-
61
+ vb/6*cos2SigmaM*(-3.0+4.0*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)))
62
+ s = b*va*(sigma-deltaSigma)
63
+
64
+ return s;
65
+ end
66
+
67
+ private
68
+
69
+ def self.deg_to_rad(deg)
70
+ (Math::PI * deg) / 180
71
+ end
72
+ end
data/rvincenty.gemspec ADDED
@@ -0,0 +1,53 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rvincenty}
8
+ s.version = "0.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Reto Sch\303\274ttel"]
12
+ s.date = %q{2009-08-23}
13
+ s.description = %q{rvincenty is a pure ruby implementation of Thaddeus Vincenty's formulae }
14
+ s.email = %q{reto@schuettel.ch}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/rvincenty.rb",
27
+ "rvincenty.gemspec",
28
+ "test/rvincenty_test.rb",
29
+ "test/test_helper.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/retoo/rvincenty}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.5}
35
+ s.summary = %q{Pure Ruby implementation of Vincenty formula to calculate distance between two points}
36
+ s.test_files = [
37
+ "test/rvincenty_test.rb",
38
+ "test/test_helper.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
46
+ s.add_development_dependency(%q<yard>, [">= 0"])
47
+ else
48
+ s.add_dependency(%q<yard>, [">= 0"])
49
+ end
50
+ else
51
+ s.add_dependency(%q<yard>, [">= 0"])
52
+ end
53
+ end
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+ require 'rvincenty'
3
+
4
+
5
+ class RVincentyTest < Test::Unit::TestCase
6
+ # positions are from Wikipedia
7
+ BAIKONUR_COSMODROME = [45.965, 63.305 ]
8
+ KENNEDY_SPACE_CENTER = [28.585, -80.651 ]
9
+ JIUQUAN_SATELLITE_LAUNCH_CENTER = [40.957778, 100.291667 ]
10
+ SAN_MARCO_PLATFORM = [-2.938333, 40.2125 ]
11
+ SOUTH_POLE = [-90, -0 ]
12
+ NORTH_POLE = [90, -0 ]
13
+ AMUNDSEN_SCOTT_SOUTH_POLE_STATION = [-90, -139.266667 ]
14
+
15
+ # distance values are from http://www.movable-type.co.uk/scripts/latlong-vincenty.html
16
+ DISTANCES = [
17
+ [BAIKONUR_COSMODROME, KENNEDY_SPACE_CENTER, 10_986_163.684],
18
+ [SOUTH_POLE, JIUQUAN_SATELLITE_LAUNCH_CENTER, 14_537_850.120],
19
+ [SOUTH_POLE, AMUNDSEN_SCOTT_SOUTH_POLE_STATION, 0],
20
+ [SOUTH_POLE, NORTH_POLE, 20_003_931.459],
21
+ [NORTH_POLE, SOUTH_POLE, 20_003_931.459],
22
+ [BAIKONUR_COSMODROME, JIUQUAN_SATELLITE_LAUNCH_CENTER, 3_016_381.278],
23
+ [AMUNDSEN_SCOTT_SOUTH_POLE_STATION, SAN_MARCO_PLATFORM, 9_677_058.827],
24
+ [AMUNDSEN_SCOTT_SOUTH_POLE_STATION, AMUNDSEN_SCOTT_SOUTH_POLE_STATION, 0],
25
+ [JIUQUAN_SATELLITE_LAUNCH_CENTER, BAIKONUR_COSMODROME, 3016381.278],
26
+ ]
27
+
28
+ def test_vincenty
29
+ DISTANCES.each do |a, b, distance|
30
+ calc_distance = RVincenty.distance(a,b)
31
+
32
+ assert_in_delta distance, calc_distance, 0.0005, "from: %s to: %s" % [a.inspect, b.inspect]
33
+ end
34
+ end
35
+
36
+ def test_readme_example
37
+ point_a = 45.965, 63.305 # Baikonur Cosmodrome
38
+ point_b = 28.585, -80.651 # John F. Kennedy Space Center
39
+
40
+ distance = RVincenty.distance(point_a, point_b)
41
+
42
+ assert_in_delta distance, 10_986_163.684, 0.0005
43
+
44
+ out = "Distance between %s and %s is %f km" % [point_a.inspect, point_b.inspect, distance / 1000]
45
+ end
46
+
47
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'rvincenty'
7
+
8
+ class Test::Unit::TestCase
9
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rvincenty
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - "Reto Sch\xC3\xBCttel"
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-07-27 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ prerelease: false
22
+ type: :development
23
+ name: rake
24
+ version_requirements: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ requirement: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ prerelease: false
34
+ type: :development
35
+ name: bundler
36
+ version_requirements: &id002 !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ segments:
41
+ - 1
42
+ - 0
43
+ - 0
44
+ version: 1.0.0
45
+ requirement: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ prerelease: false
48
+ type: :development
49
+ name: jeweler
50
+ version_requirements: &id003 !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 1
56
+ - 6
57
+ - 4
58
+ version: 1.6.4
59
+ requirement: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ prerelease: false
62
+ type: :development
63
+ name: yard
64
+ version_requirements: &id004 !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ requirement: *id004
72
+ description: "rvincenty is a pure ruby implementation of Thaddeus Vincenty's formulae "
73
+ email: reto@schuettel.ch
74
+ executables: []
75
+
76
+ extensions: []
77
+
78
+ extra_rdoc_files:
79
+ - LICENSE
80
+ - README.rdoc
81
+ files:
82
+ - .document
83
+ - LICENSE
84
+ - README.rdoc
85
+ - Rakefile
86
+ - VERSION
87
+ - lib/rvincenty.rb
88
+ - rvincenty.gemspec
89
+ - test/rvincenty_test.rb
90
+ - test/test_helper.rb
91
+ has_rdoc: true
92
+ homepage: http://github.com/retoo/rvincenty
93
+ licenses: []
94
+
95
+ post_install_message:
96
+ rdoc_options: []
97
+
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ requirements: []
115
+
116
+ rubyforge_project:
117
+ rubygems_version: 1.3.6
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Pure Ruby implementation of Vincenty formula to calculate distance between two points
121
+ test_files: []
122
+