haversine 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", ">= 2.3.0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.5.2"
12
+ gem "rcov", ">= 0"
13
+ end
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.5.2)
7
+ bundler (~> 1.0.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.8.7)
11
+ rcov (0.9.9)
12
+ rspec (2.4.0)
13
+ rspec-core (~> 2.4.0)
14
+ rspec-expectations (~> 2.4.0)
15
+ rspec-mocks (~> 2.4.0)
16
+ rspec-core (2.4.0)
17
+ rspec-expectations (2.4.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.4.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ bundler (~> 1.0.0)
26
+ jeweler (~> 1.5.2)
27
+ rcov
28
+ rspec (>= 2.3.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Kristian Mandrup
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.
@@ -0,0 +1,22 @@
1
+ = haversine
2
+
3
+ Calculates the haversine distance between two locations using longitude and latitude.
4
+ This is done using Math formulas without resorting to Active Record or SQL DB functionality
5
+
6
+ This is meant to ba a replacement for all those geocode and geolocation utils out there that use built in SQL DB functionality for their calculations!
7
+
8
+ == Contributing to haversine
9
+
10
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
11
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
12
+ * Fork the project
13
+ * Start a feature/bugfix branch
14
+ * Commit and push until you are happy with your contribution
15
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
16
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
17
+
18
+ == Copyright
19
+
20
+ Copyright (c) 2011 Kristian Mandrup. See LICENSE.txt for
21
+ further details.
22
+
@@ -0,0 +1,51 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "haversine"
16
+ gem.homepage = "http://github.com/kristianmandrup/haversine"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{Calculates the haversine distance between two locations using longitude and latitude}
19
+ gem.description = %Q{Calculates the haversine distance between two locations using longitude and latitude.
20
+ This is done using Math formulas without resorting to Active Record or SQL DB functionality}
21
+ gem.email = "kmandrup@gmail.com"
22
+ gem.authors = ["Kristian Mandrup"]
23
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
24
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
25
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
26
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
27
+ end
28
+ Jeweler::RubygemsDotOrgTasks.new
29
+
30
+ require 'rspec/core'
31
+ require 'rspec/core/rake_task'
32
+ RSpec::Core::RakeTask.new(:spec) do |spec|
33
+ spec.pattern = FileList['spec/**/*_spec.rb']
34
+ end
35
+
36
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
37
+ spec.pattern = 'spec/**/*_spec.rb'
38
+ spec.rcov = true
39
+ end
40
+
41
+ task :default => :spec
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
46
+
47
+ rdoc.rdoc_dir = 'rdoc'
48
+ rdoc.title = "haversine #{version}"
49
+ rdoc.rdoc_files.include('README*')
50
+ rdoc.rdoc_files.include('lib/**/*.rb')
51
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,66 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
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{haversine}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kristian Mandrup"]
12
+ s.date = %q{2011-01-12}
13
+ s.description = %q{Calculates the haversine distance between two locations using longitude and latitude.
14
+ This is done using Math formulas without resorting to Active Record or SQL DB functionality}
15
+ s.email = %q{kmandrup@gmail.com}
16
+ s.extra_rdoc_files = [
17
+ "LICENSE.txt",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".rspec",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "haversine.gemspec",
30
+ "lib/haversine.rb",
31
+ "spec/haversine_spec.rb",
32
+ "spec/spec_helper.rb"
33
+ ]
34
+ s.homepage = %q{http://github.com/kristianmandrup/haversine}
35
+ s.licenses = ["MIT"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.7}
38
+ s.summary = %q{Calculates the haversine distance between two locations using longitude and latitude}
39
+ s.test_files = [
40
+ "spec/haversine_spec.rb",
41
+ "spec/spec_helper.rb"
42
+ ]
43
+
44
+ if s.respond_to? :specification_version then
45
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
+ s.add_development_dependency(%q<rspec>, [">= 2.3.0"])
50
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
51
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
52
+ s.add_development_dependency(%q<rcov>, [">= 0"])
53
+ else
54
+ s.add_dependency(%q<rspec>, [">= 2.3.0"])
55
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
56
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
57
+ s.add_dependency(%q<rcov>, [">= 0"])
58
+ end
59
+ else
60
+ s.add_dependency(%q<rspec>, [">= 2.3.0"])
61
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
62
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
63
+ s.add_dependency(%q<rcov>, [">= 0"])
64
+ end
65
+ end
66
+
@@ -0,0 +1,109 @@
1
+ #
2
+ # haversine formula to compute the great circle distance between two points given their latitude and longitudes
3
+ #
4
+ # Copyright (C) 2008, 360VL, Inc
5
+ # Copyright (C) 2008, Landon Cox
6
+ #
7
+ # http://www.esawdust.com (Landon Cox)
8
+ # contact:
9
+ # http://www.esawdust.com/blog/businesscard/businesscard.html
10
+ #
11
+ # LICENSE: GNU Affero GPL v3
12
+ # The ruby implementation of the Haversine formula is free software: you can redistribute it and/or modify
13
+ # it under the terms of the GNU Affero General Public License version 3 as published by the Free Software Foundation.
14
+ #
15
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
16
+ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
17
+ # License version 3 for more details. http://www.gnu.org/licenses/
18
+ #
19
+ # Landon Cox - 9/25/08
20
+ #
21
+ # Notes:
22
+ #
23
+ # translated into Ruby based on information contained in:
24
+ # http://mathforum.org/library/drmath/view/51879.html Doctors Rick and Peterson - 4/20/99
25
+ # http://www.movable-type.co.uk/scripts/latlong.html
26
+ # http://en.wikipedia.org/wiki/Haversine_formula
27
+ #
28
+ # This formula can compute accurate distances between two points given latitude and longitude, even for
29
+ # short distances.
30
+
31
+ # PI = 3.1415926535
32
+
33
+ class Haversine
34
+
35
+ RAD_PER_DEG = 0.017453293 # PI/180
36
+
37
+ # the great circle distance d will be in whatever units R is in
38
+
39
+ Rmiles = 3956 # radius of the great circle in miles
40
+ Rkm = 6371 # radius in kilometers...some algorithms use 6367
41
+ Rfeet = Rmiles * 5282 # radius in feet
42
+ Rmeters = Rkm * 1000 # radius in meters
43
+
44
+ # this is global because if computing lots of track point distances, it didn't make
45
+ # sense to new a Hash each time over potentially 100's of thousands of points
46
+
47
+ class Distance
48
+ class << self
49
+
50
+ [:miles, :km, :feet, :meters].each do |unit|
51
+ class_eval %{
52
+ def in_#{unit} number
53
+ Unit.new :#{unit}, number
54
+ end
55
+ }
56
+ end
57
+ end
58
+
59
+ class Unit
60
+ attr_accessor :name, :number
61
+
62
+ def initialize name, number = 0
63
+ @name = name
64
+ @number = number
65
+ end
66
+
67
+ def to_s
68
+ "#{number} #{name}"
69
+ end
70
+ end
71
+ end
72
+
73
+ def self.distances
74
+ @distances ||= Hash.new
75
+ end
76
+
77
+ # given two lat/lon points, compute the distance between the two points using the haversine formula
78
+ # the result will be a Hash of distances which are key'd by 'mi','km','ft', and 'm'
79
+
80
+ def self.distance( lat1, lon1, lat2, lon2 )
81
+ dlon = lon2 - lon1
82
+ dlat = lat2 - lat1
83
+
84
+ dlon_rad = dlon * RAD_PER_DEG
85
+ dlat_rad = dlat * RAD_PER_DEG
86
+
87
+ lat1_rad = lat1 * RAD_PER_DEG
88
+ lon1_rad = lon1 * RAD_PER_DEG
89
+
90
+ lat2_rad = lat2 * RAD_PER_DEG
91
+ lon2_rad = lon2 * RAD_PER_DEG
92
+
93
+ # puts "dlon: #{dlon}, dlon_rad: #{dlon_rad}, dlat: #{dlat}, dlat_rad: #{dlat_rad}"
94
+
95
+ a = (Math.sin(dlat_rad/2))**2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * (Math.sin(dlon_rad/2))**2
96
+ c = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a))
97
+
98
+ dMi = Rmiles * c # delta between the two points in miles
99
+ dKm = Rkm * c # delta in kilometers
100
+ dFeet = Rfeet * c # delta in feet
101
+ dMeters = Rmeters * c # delta in meters
102
+
103
+ distances[:miles] = Distance.in_miles dMi
104
+ distances[:km] = Distance.in_km dKm
105
+ distances[:feet] = Distance.in_feet dFeet
106
+ distances[:meters] = Distance.in_meters dMeters
107
+ distances
108
+ end
109
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe "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 = Haversine.distance( lat1, lon1, lat2, lon2 )
12
+
13
+ puts "the distance from #{lat1}, #{lon1} to #{lat2}, #{lon2} is:"
14
+
15
+ puts dist[:meters].number
16
+
17
+ puts "#{dist[:miles]}"
18
+ puts "#{dist[:km]}"
19
+ puts "#{dist[:feet]}"
20
+ puts "#{dist[:meters]}"
21
+
22
+ dist[:km].to_s.should match(/7\.376*/)
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'haversine'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haversine
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
+ - Kristian Mandrup
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-01-12 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 3
30
+ - 0
31
+ version: 2.3.0
32
+ type: :development
33
+ prerelease: false
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: bundler
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 1
44
+ - 0
45
+ - 0
46
+ version: 1.0.0
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: jeweler
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 1
59
+ - 5
60
+ - 2
61
+ version: 1.5.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: rcov
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: *id004
78
+ description: |-
79
+ Calculates the haversine distance between two locations using longitude and latitude.
80
+ This is done using Math formulas without resorting to Active Record or SQL DB functionality
81
+ email: kmandrup@gmail.com
82
+ executables: []
83
+
84
+ extensions: []
85
+
86
+ extra_rdoc_files:
87
+ - LICENSE.txt
88
+ - README.rdoc
89
+ files:
90
+ - .document
91
+ - .rspec
92
+ - Gemfile
93
+ - Gemfile.lock
94
+ - LICENSE.txt
95
+ - README.rdoc
96
+ - Rakefile
97
+ - VERSION
98
+ - haversine.gemspec
99
+ - lib/haversine.rb
100
+ - spec/haversine_spec.rb
101
+ - spec/spec_helper.rb
102
+ has_rdoc: true
103
+ homepage: http://github.com/kristianmandrup/haversine
104
+ licenses:
105
+ - MIT
106
+ post_install_message:
107
+ rdoc_options: []
108
+
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ none: false
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ hash: -2632364842243364495
117
+ segments:
118
+ - 0
119
+ version: "0"
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ segments:
126
+ - 0
127
+ version: "0"
128
+ requirements: []
129
+
130
+ rubyforge_project:
131
+ rubygems_version: 1.3.7
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: Calculates the haversine distance between two locations using longitude and latitude
135
+ test_files:
136
+ - spec/haversine_spec.rb
137
+ - spec/spec_helper.rb