Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d45e59b
commit 74bc126
Showing
22 changed files
with
425 additions
and
226 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,10 @@ | ||
source "http://rubygems.org" | ||
# Add dependencies required to use your gem here. | ||
# Example: | ||
# gem "activesupport", ">= 2.3.5" | ||
|
||
# Add dependencies to develop your gem here. | ||
# Include everything needed to run rake, tests, features, etc. | ||
gem 'geo_point', '~> 2.5.0' | ||
|
||
group :development do | ||
gem "rspec", ">= 2.3.0" | ||
gem "bundler", "~> 1.0.0" | ||
gem "jeweler", "~> 1.5.2" | ||
gem "rcov", ">= 0" | ||
gem "rspec", ">= 2.6.0" | ||
gem "bundler", "~> 1.0.10" | ||
gem "jeweler", "~> 1.6.2" | ||
gem "rcov", ">= 0" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
0.1.2 | ||
0.1.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,6 @@ | ||
module GeoDistance | ||
# this is global because if computing lots of track point distances, it didn't make | ||
# sense to new a Hash each time over potentially 100's of thousands of points | ||
|
||
class << self | ||
# radius of the great circle in miles | ||
# radius in kilometers...some algorithms use 6367 | ||
def earth_radius | ||
{:km => 6371, :miles => 3956, :feet => 20895592, :meters => 6371000} | ||
end | ||
|
||
def radians_per_degree | ||
0.017453293 # PI/180 | ||
end | ||
|
||
def units | ||
[:miles, :km, :feet, :meters] | ||
end | ||
|
||
def radians_ratio unit | ||
GeoDistance.radians_per_degree * earth_radius[unit] | ||
end | ||
|
||
def default_algorithm= name | ||
raise ArgumentError, "Not a valid algorithm. Must be one of: #{algorithms}" if !algorithms.include?(name.to_sym) | ||
@default_algorithm = name | ||
end | ||
|
||
def distance( lat1, lon1, lat2, lon2) | ||
klass = case default_algorithm | ||
when :haversine | ||
GeoDistance::Haversine | ||
when :spherical | ||
GeoDistance::Spherical | ||
when :vincenty | ||
GeoDistance::Vincenty | ||
else | ||
raise ArgumentError, "Not a valid algorithm. Must be one of: #{algorithms}" | ||
end | ||
klass.distance lat1, lon1, lat2, lon2 | ||
end | ||
|
||
def default_algorithm | ||
@default_algorithm || :haversine | ||
end | ||
|
||
protected | ||
|
||
def algorithms | ||
[:haversine, :spherical, :vincenty] | ||
end | ||
end | ||
|
||
def self.wants? unit_opts, unit | ||
unit_opts == unit || unit_opts[unit] | ||
end | ||
end | ||
|
||
require 'geo_point' | ||
require 'geo-distance/core_ext' | ||
require 'geo-distance/class_methods' | ||
require 'geo-distance/distance' | ||
require 'geo-distance/haversine' | ||
require 'geo-distance/spherical' | ||
require 'geo-distance/vincenty' | ||
require 'geo-distance/formula' | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
class GeoDistance | ||
# this is global because if computing lots of track point distances, it didn't make | ||
# sense to new a Hash each time over potentially 100's of thousands of points | ||
|
||
module ClassMethods | ||
# radius of the great circle in miles | ||
# radius in kilometers...some algorithms use 6367 | ||
|
||
def earth_radius units | ||
GeoDistance.EARTH_RADIUS[units.to_sym] | ||
end | ||
|
||
def radians_per_degree | ||
0.017453293 # PI/180 | ||
end | ||
|
||
def units | ||
[:feet, :meters, :kms, :miles] | ||
end | ||
|
||
def radians_ratio unit | ||
GeoDistance.radians_per_degree * earth_radius[unit] | ||
end | ||
|
||
def default_algorithm= name | ||
raise ArgumentError, "Not a valid algorithm. Must be one of: #{algorithms}" if !algorithms.include?(name.to_sym) | ||
@default_algorithm = name | ||
end | ||
|
||
def distance( lat1, lon1, lat2, lon2) | ||
klass = case default_algorithm | ||
when :flat | ||
GeoDistance::Flat | ||
when :haversine | ||
GeoDistance::Haversine | ||
when :spherical | ||
GeoDistance::Spherical | ||
when :vincenty | ||
GeoDistance::Vincenty | ||
else | ||
raise ArgumentError, "Not a valid algorithm. Must be one of: #{algorithms}" | ||
end | ||
klass.distance lat1, lon1, lat2, lon2 | ||
end | ||
|
||
def default_algorithm | ||
@default_algorithm || :haversine | ||
end | ||
|
||
protected | ||
|
||
def algorithms | ||
[:flat, :haversine, :spherical, :vincenty] | ||
end | ||
end | ||
|
||
extend ClassMethods | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,27 @@ | ||
class Float | ||
def round_to(x) | ||
(self * 10**x).round.to_f / 10**x | ||
end | ||
require 'sugar-high/numeric' | ||
|
||
def ceil_to(x) | ||
(self * 10**x).ceil.to_f / 10**x | ||
module GeoUnitExt | ||
::GeoDistance.units.each do |unit| | ||
class_eval %{ | ||
def #{unit} | ||
GeoDistance.new(self, :#{unit}) | ||
end | ||
} | ||
end | ||
|
||
def floor_to(x) | ||
(self * 10**x).floor.to_f / 10**x | ||
end | ||
|
||
include NumberDslExt # from sugar-high | ||
|
||
def rpd | ||
self * GeoDistance.radians_per_degree | ||
end | ||
alias_method :to_radians, :rpd | ||
end | ||
|
||
require 'geo-distance' | ||
end | ||
|
||
class Integer | ||
::GeoDistance.units.each do |unit| | ||
class_eval %{ | ||
def #{unit} | ||
GeoDistance::Distance.new(self, :#{unit}) | ||
end | ||
} | ||
end | ||
class Fixnum | ||
include GeoUnitExt | ||
end | ||
|
||
class Float | ||
include GeoUnitExt | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
class GeoDistance | ||
attr_reader :distance, :unit | ||
|
||
def initialize distance, unit = :kms | ||
@distance = distance | ||
return if !unit | ||
|
||
raise ArgumentError, "Invalid unit: #{unit} - must be one of #{GeoDistance.units}" if !GeoDistance.units.include?(unit.to_sym) | ||
@unit = unit.to_sym | ||
end | ||
|
||
GeoDistance.units.each do |unit| | ||
class_eval %{ | ||
def #{unit} | ||
delta_#{unit} | ||
end | ||
alias_method :to_#{unit}, :#{unit} | ||
} | ||
end | ||
|
||
protected | ||
|
||
# delta between the two points in miles | ||
GeoDistance.units.each do |unit| | ||
class_eval %{ | ||
def delta_#{unit} | ||
unit = GeoUnits.key(:#{unit}) | ||
GeoDistance.earth_radius[:#{unit}] * distance | ||
end | ||
} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,101 @@ | ||
module GeoDistance | ||
EARTH_RADIUS = { :kilometers => 6378.135, :miles => 3963.1676 } | ||
class GeoDistance | ||
# WGS-84 numbers | ||
EARTH_MAJOR_AXIS_RADIUS = { :kilometers => 6378.137, :miles => 3963.19059 } | ||
EARTH_MINOR_AXIS_RADIUS = { :kilometers => 6356.7523142, :miles => 3949.90276 } | ||
|
||
EARTH_RADIUS = { | ||
:miles => 3963.1676, | ||
:kilometers => 6378.135, | ||
:meters => 6378135, | ||
:feet => 20925639.8 | ||
} | ||
|
||
|
||
EARTH_MAJOR_AXIS_RADIUS = { | ||
:miles => 3963.19059 | ||
:kilometers => 6378.137, | ||
:meters => 6378137, | ||
:feet => 20925646.36 | ||
} | ||
|
||
EARTH_MINOR_AXIS_RADIUS = { | ||
:kilometers => 6356.7523142, | ||
:miles => 3949.90276, | ||
:meters => 6356752.3142, | ||
:feet => 20855486.627 | ||
} | ||
|
||
autoload :Haversine, 'geo-distance/formula/haversine' | ||
autoload :Spherical, 'geo-distance/formula/spherical' | ||
autoload :Vincenty, 'geo-distance/formula/vincenty' | ||
autoload :Flat, 'geo-distance/formula/flat' | ||
|
||
class DistanceFormula | ||
include Math | ||
extend Math | ||
|
||
RADIAN_PER_DEGREE = Math::PI / 180.0 | ||
|
||
# Haversine Formula | ||
# Adapted from Geokit Gem | ||
# https://github.com/andre/geokit-gem.git | ||
# By: Andre Lewis | ||
PI_DIV_RAD = 0.0174 | ||
|
||
KMS_PER_MILE = 1.609 | ||
METERS_PER_FEET = 3.2808399 | ||
|
||
MILES_PER_LATITUDE_DEGREE = 69.1 | ||
KMS_PER_LATITUDE_DEGREE = MILES_PER_LATITUDE_DEGREE * KMS_PER_MILE | ||
LATITUDE_DEGREES = EARTH_RADIUS[:miles] / MILES_PER_LATITUDE_DEGREE | ||
|
||
def initialize | ||
raise NotImplementedError | ||
end | ||
|
||
# use underlying distance formula | ||
def self.geo_distance *args | ||
GeoDistance.new distance(args), get_units(args.last_option) | ||
end | ||
|
||
# used to convert various argument types into GeoPoints | ||
def self.get_points(*args) | ||
units = args.delete(args.last_option) | ||
|
||
case args.size | ||
when 2 | ||
[GeoPoint.new(args.first), GeoPoint.new(args.last), units] | ||
when 4 | ||
[GeoPoint.new(args[0..1]), GeoPoint.new(args[2..3]), units] | ||
else | ||
raise "Distance from point A to B, must be given either as 4 arguments (lat1, lng1, lat2, lng2) or 2 arguments: (pointA, pointB), was: #{args}" | ||
end | ||
end | ||
|
||
# used to get the units for how to calculate the distance | ||
def self.get_units options = {} | ||
GeoUnits.key(options[:units] || :kms) | ||
end | ||
|
||
def self.degrees_to_radians(degrees) | ||
degrees.to_f / 180.0 * Math::PI | ||
end | ||
|
||
def self.units_sphere_multiplier(units) | ||
EARTH_RADIUS[GeoUnit.key units] | ||
end | ||
|
||
def self.units_per_latitude_degree(units) | ||
GeoUnits.radian_multiplier(units.to_sym) | ||
end | ||
|
||
def self.units_per_longitude_degree(lat, units) | ||
miles_per_longitude_degree = (LATITUDE_DEGREES * Math.cos(lat * PI_DIV_RAD)).abs | ||
case units | ||
when :kms | ||
miles_per_longitude_degree * KMS_PER_MILE | ||
when :miles | ||
miles_per_longitude_degree | ||
end | ||
end | ||
end | ||
end | ||
|
Oops, something went wrong.