lib/geo-distance.rb in geo-distance-0.1.2 vs lib/geo-distance.rb in geo-distance-0.2.0

- old
+ new

@@ -1,136 +1,18 @@ -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 +require 'geo_point' - 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 +class GeoDistance + autoload :Conversion, 'geo-distance/conversion' + autoload :Scale, 'geo-distance/scale' + autoload :ClassMethods, 'geo-distance/class_methods' - 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 - - class Distance - attr_reader :distance, :unit + autoload :Haversine, 'geo-distance/formula/haversine' + autoload :Spherical, 'geo-distance/formula/spherical' + autoload :Vincenty, 'geo-distance/formula/vincenty' + autoload :NVector, 'geo-distance/formula/n_vector' + autoload :Flat, 'geo-distance/formula/flat' +end - def initialize distance, unit = nil - @distance = distance - return if !unit +require 'geo-distance/distance' +require 'geo-distance/core_ext' +require 'geo-distance/formula' - raise ArgumentError, "Invalid unit: #{unit} - must be one of #{GeoDistance.units}" if !GeoDistance.units.include?(unit.to_sym) - @unit = unit.to_sym - end - - def [] key - method = :"delta_#{key}" - raise ArgumentError, "Invalid unit key #{key}" if !respond_to? method - Distance.send "in_#{key}", send(method) - end - - GeoDistance.units.each do |unit| - class_eval %{ - def #{unit} - self[:#{unit}] - end - } - end - - protected - - # delta between the two points in miles - GeoDistance.units.each do |unit| - class_eval %{ - def delta_#{unit} - GeoDistance.earth_radius[:#{unit}] * distance - end - } - end - - class << self - GeoDistance.units.each do |unit| - class_eval %{ - def in_#{unit} number - Unit.new :#{unit}, number - end - } - end - end - - class Unit - attr_accessor :name, :number - - def initialize name, number = 0 - @name = name - @number = number - end - - def number - @number.round_to(precision[name]) - end - - def to_s - "#{number} #{name}" - end - - private - - def precision - { - :feet => 0, - :meters => 2, - :km => 4, - :miles => 4 - } - end - end - end - - def self.wants? unit_opts, unit - unit_opts == unit || unit_opts[unit] - end -end - -require 'geo-distance/haversine' -require 'geo-distance/spherical' -require 'geo-distance/vincenty'