lib/graticule/distance/spherical.rb in graticule-0.1.1 vs lib/graticule/distance/spherical.rb in graticule-0.1.2
- old
+ new
@@ -1,15 +1,22 @@
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
+ # The Spherical Law of Cosines is the simplist though least accurate distance
+ # formula (earth isn't a perfect sphere).
#
class Spherical < DistanceFormula
+ # Calculate the distance between two Locations using the Spherical formula
+ #
+ # Graticule::Distance::Spherical.distance(
+ # Graticule::Location.new(:latitude => 42.7654, :longitude => -86.1085),
+ # Graticule::Location.new(:latitude => 41.849838, :longitude => -87.648193)
+ # )
+ # #=> 101.061720831853
+ #
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)
@@ -22,9 +29,24 @@
Math.cos(to_latitude) *
Math.cos(to_longitude - from_longitude)
) * EARTH_RADIUS[units.to_sym]
end
+ def self.to_sql(options)
+ options = {
+ :units => :miles,
+ :latitude_column => 'latitude',
+ :longitude_column => 'longitude'
+ }.merge(options)
+ %{(ACOS(
+ SIN(RADIANS(#{options[:latitude]})) *
+ SIN(RADIANS(#{options[:latitude_column]})) +
+ COS(RADIANS(#{options[:latitude]})) *
+ COS(RADIANS(#{options[:latitude_column]})) *
+ COS(RADIANS(#{options[:longitude_column]}) - RADIANS(#{options[:longitude]}))
+ ) * #{Graticule::Distance::EARTH_RADIUS[options[:units].to_sym]})
+ }.gsub("\n", '').squeeze(" ")
+ end
end
end
end
\ No newline at end of file