Skip to content

Commit

Permalink
migrated to hoe
Browse files Browse the repository at this point in the history
added other distance calculations
  • Loading branch information
bkeepers committed Dec 16, 2006
1 parent 6587e86 commit de1e040
Show file tree
Hide file tree
Showing 17 changed files with 317 additions and 136 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG
@@ -0,0 +1,8 @@

0.1.1
* fixed bug in Yahoo that raised error when street address not returned
* migrated to Hoe (http://seattlerb.rubyforge.org/hoe/)
* added Haversine, Spherical and Vincenty distance calculations

0.1 (2006-10-31)
* Initial release
30 changes: 30 additions & 0 deletions LICENSE
@@ -0,0 +1,30 @@
Copyright 2006 Brandon Keepers, Collective Idea. All rights reserved.

Original geocoding code:
Copyright 2006 Eric Hodel, The Robot Co-op. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the names of the authors nor the names of their contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

44 changes: 44 additions & 0 deletions Manifest.txt
@@ -0,0 +1,44 @@
CHANGELOG
LICENSE
Manifest.txt
README
Rakefile
init.rb
lib/graticule.rb
lib/graticule/distance.rb
lib/graticule/distance/haversine.rb
lib/graticule/distance/spherical.rb
lib/graticule/distance/vincenty.rb
lib/graticule/geocoder.rb
lib/graticule/geocoders/bogus.rb
lib/graticule/geocoders/geocoder_us.rb
lib/graticule/geocoders/google.rb
lib/graticule/geocoders/meta_carta.rb
lib/graticule/geocoders/rest.rb
lib/graticule/geocoders/yahoo.rb
lib/graticule/location.rb
lib/graticule/version.rb
test/fixtures/responses/geocoder_us/success.xml
test/fixtures/responses/geocoder_us/unknown.xml
test/fixtures/responses/google/badkey.xml
test/fixtures/responses/google/limit.xml
test/fixtures/responses/google/missing_address.xml
test/fixtures/responses/google/server_error.xml
test/fixtures/responses/google/success.xml
test/fixtures/responses/google/unavailable.xml
test/fixtures/responses/google/unknown_address.xml
test/fixtures/responses/meta_carta/bad_address.xml
test/fixtures/responses/meta_carta/multiple.xml
test/fixtures/responses/meta_carta/success.xml
test/fixtures/responses/yahoo/success.xml
test/fixtures/responses/yahoo/unknown_address.xml
test/mocks/uri.rb
test/test_helper.rb
test/unit/graticule/distance_test.rb
test/unit/graticule/geocoder_test.rb
test/unit/graticule/geocoders/geocoder_us_test.rb
test/unit/graticule/geocoders/geocoders.rb
test/unit/graticule/geocoders/google_test.rb
test/unit/graticule/geocoders/meta_carta_test.rb
test/unit/graticule/geocoders/yahoo_test.rb
test/unit/graticule/location_test.rb
3 changes: 2 additions & 1 deletion README
Expand Up @@ -4,6 +4,7 @@ Graticule is a geocoding API for looking up address coordinates. It supports su

= Usage

require 'rubygems'
require 'graticule'
geocoder = Graticle.service(:google).new "api_key"
geocoder = Graticule.service(:google).new "api_key"
location = geocoder.locate "61 East 9th Street, Holland, MI"
117 changes: 11 additions & 106 deletions Rakefile
@@ -1,110 +1,15 @@
require 'rubygems'
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
require 'rake/gempackagetask'
require 'rake/contrib/rubyforgepublisher'


PKG_VERSION = "0.1.0"
PKG_NAME = "graticule"
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"

PKG_FILES = FileList[
"lib/**/*", "examples/**/*", "[A-Z]*", "rakefile"
].exclude(/\.svn$/)


desc "Default Task"
task :default => [ :test ]

# Run the unit tests

Rake::TestTask.new(:test) do |t|
t.pattern = 'test/unit/**/*_test.rb'
t.ruby_opts << '-rubygems'
t.verbose = true
end

Rake::TestTask.new(:test_remote) do |t|
t.pattern = 'test/remote_tests/*_test.rb'
t.ruby_opts << '-rubygems'
t.verbose = true
end

# Genereate the RDoc documentation
Rake::RDocTask.new do |rdoc|
rdoc.rdoc_dir = 'doc'
rdoc.title = "Graticule Geocoding Library"
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README', 'CHANGELOG')
rdoc.rdoc_files.include('lib/**/*.rb')
end

task :install => [:package] do
`gem install pkg/#{PKG_FILE_NAME}.gem`
end

task :lines do
lines = 0
codelines = 0
Dir.foreach("lib") { |file_name|
next unless file_name =~ /.*rb/

f = File.open("lib/" + file_name)

while line = f.gets
lines += 1
next if line =~ /^\s*$/
next if line =~ /^\s*#/
codelines += 1
end
}
puts "Lines #{lines}, LOC #{codelines}"
end

desc "Publish the gem"
task :publish => [:rdoc, :package] do
Rake::SshFilePublisher.new("host.collectiveidea.com", "/var/www/vhosts/source.collectiveidea.com/public/dist/pkg", "pkg", "#{PKG_FILE_NAME}.zip").upload
Rake::SshFilePublisher.new("host.collectiveidea.com", "/var/www/vhosts/source.collectiveidea.com/public/dist/pkg", "pkg", "#{PKG_FILE_NAME}.tgz").upload
Rake::SshFilePublisher.new("host.collectiveidea.com", "/var/www/vhosts/source.collectiveidea.com/public/dist/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
`ssh host.collectiveidea.com "mkdir -p /var/www/vhosts/source.collectiveidea.com/public/dist/api/#{PKG_NAME}"`
Rake::SshDirPublisher.new("host.collectiveidea.com", "/var/www/vhosts/source.collectiveidea.com/public/dist/api/#{PKG_NAME}", "doc").upload
end

desc "Delete tar.gz / zip / rdoc"
task :cleanup => [ :rm_packages, :clobber_rdoc ]

task :install => [:package] do
`gem install pkg/#{PKG_FILE_NAME}.gem`
end

spec = Gem::Specification.new do |s|
s.name = PKG_NAME
s.version = PKG_VERSION
s.summary = "Library for using various geocoding APIs."

s.files = %w(README LICENSE CHANGELOG) + Dir['lib/**/*']

s.has_rdoc = true
s.extra_rdoc_files = %w( README )
s.rdoc_options.concat ['--main', 'README']

s.require_path = 'lib'
s.autorequire = 'graticule'
s.author = "Brandon Keepers"
s.email = "brandon@opensoul.org"
s.homepage = ""
end

Rake::GemPackageTask.new(spec) do |p|
p.gem_spec = spec
require 'hoe'
require File.join(File.dirname(__FILE__), 'lib', 'graticule', 'version.rb')

Hoe.new("graticule", Graticule::Version) do |p|
p.rubyforge_name = "graticule"
p.author = 'Brandon Keepers'
p.email = 'brandon@opensoul.org'
p.summary = "API for using all the popular geocoding services."
p.description = 'Graticule is a geocoding API that provides a common interface to all the popular services, including Google, Yahoo, Geocoder.us, and MetaCarta.'
p.url = 'http://graticule.rubyforge.org'
p.need_tar = true
p.need_zip = true
end

desc "Continuously watch unit tests"
task :watch do
system("clear")
system("stakeout \"rake\" `find . -name '*.rb'`")
p.test_globs = ['test/**/*_test.rb']
end
2 changes: 2 additions & 0 deletions init.rb
@@ -0,0 +1,2 @@

require 'graticule'
3 changes: 2 additions & 1 deletion lib/graticule.rb
@@ -1,4 +1,3 @@

$:.unshift(File.dirname(__FILE__))

require 'graticule/location'
Expand All @@ -11,3 +10,5 @@
require 'graticule/geocoders/meta_carta'
require 'graticule/distance'
require 'graticule/distance/haversine'
require 'graticule/distance/spherical'
require 'graticule/distance/vincenty'
6 changes: 5 additions & 1 deletion lib/graticule/distance.rb
@@ -1,7 +1,11 @@
module Graticule
module Distance
EARTH_RADIUS = { :kilometers => 6378.135, :miles => 3963.1676 }
# WGS-84 numbers
EARTH_MAJOR_AXIS_RADIUS = { :kilometers => 6378.137, :miles => 3963.19059 }
EARTH_MINOR_AXIS_RADIUS = { :kilometers => 6356.7523142, :miles => 3949.90276 }

class DistanceFormula
EARTH_RADIUS = { :kilometers => 6378.135, :miles => 3963.1676 }

def initialize
raise NotImplementedError
Expand Down
67 changes: 51 additions & 16 deletions lib/graticule/distance/haversine.rb
@@ -1,29 +1,64 @@

module Graticule
module Distance

#
# Thanks to Chris Veness for distance formulas.
# * http://www.movable-type.co.uk/scripts/LatLong.html
#
# Distance Measured usign the Haversine Formula
# Works better at small distances than the Spherical Law of Cosines
# R = earth’s radius (mean radius = 6,371km)
# Δlat = lat2− lat1
# Δlong = long2− long1
# a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
# c = 2.atan2(√a, √(1−a))
# d = R.c
#
class Haversine < DistanceFormula

def self.distance(from, to, units = :miles)
first_longitude = deg2rad(from.longitude)
first_latitude = deg2rad(from.latitude)
second_longitude = deg2rad(to.longitude)
second_latitude = deg2rad(to.latitude)
from_longitude = deg2rad(from.longitude)
from_latitude = deg2rad(from.latitude)
to_longitude = deg2rad(to.longitude)
to_latitude = deg2rad(to.latitude)

latitude_delta = to_latitude - from_latitude
longitude_delta = to_longitude - from_longitude

Math.acos(
Math.cos(first_longitude) *
Math.cos(second_longitude) *
Math.cos(first_latitude) *
Math.cos(second_latitude) +
a = Math.sin(latitude_delta/2)**2 +
Math.cos(from_latitude) *
Math.cos(to_latitude) *
Math.sin(longitude_delta/2)**2

Math.cos(first_latitude) *
Math.sin(first_longitude) *
Math.cos(second_latitude) *
Math.sin(second_longitude) +
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))

Math.sin(first_latitude) *
Math.sin(second_latitude)
) * EARTH_RADIUS[units.to_sym]
d = EARTH_RADIUS[units.to_sym] * c
end

# # What formula is this?
# def self.distance(from, to, units = :miles)
# from_longitude = deg2rad(from.longitude)
# from_latitude = deg2rad(from.latitude)
# to_longitude = deg2rad(to.longitude)
# to_latitude = deg2rad(to.latitude)
#
# Math.acos(
# Math.cos(from_longitude) *
# Math.cos(to_longitude) *
# Math.cos(from_latitude) *
# Math.cos(to_latitude) +
#
# Math.cos(from_latitude) *
# Math.sin(from_longitude) *
# Math.cos(to_latitude) *
# Math.sin(to_longitude) +
#
# Math.sin(from_latitude) *
# Math.sin(to_latitude)
# ) * EARTH_RADIUS[units.to_sym]
# end


end
end
Expand Down
30 changes: 30 additions & 0 deletions lib/graticule/distance/spherical.rb
@@ -0,0 +1,30 @@
module Graticule
module Distance

#
# Distance Measured usign the Spherical Law of Cosines
# Simplist though least accurate (earth isn't a perfect sphere)
# d = acos(sin(lat1).sin(lat2)+cos(lat1).cos(lat2).cos(long2−long1)).R
#
class Spherical < DistanceFormula

def self.distance(from, to, units = :miles)
from_longitude = deg2rad(from.longitude)
from_latitude = deg2rad(from.latitude)
to_longitude = deg2rad(to.longitude)
to_latitude = deg2rad(to.latitude)

Math.acos(
Math.sin(from_latitude) *
Math.sin(to_latitude) +

Math.cos(from_latitude) *
Math.cos(to_latitude) *
Math.cos(to_longitude - from_longitude)
) * EARTH_RADIUS[units.to_sym]
end


end
end
end

0 comments on commit de1e040

Please sign in to comment.