Permalink
Browse files

added unit class

  • Loading branch information...
1 parent 729577b commit 3f7ffffb62f568a722d2514641e9d55ddeb55b6d @kristianmandrup committed May 5, 2011
@@ -11,7 +11,7 @@ module ClassMethods
def distance *args
points = extract_points *args
options = extract_options *args
- unit = options[:unit]
+ unit = GeoMagic::Unit.key options[:unit] if options[:unit]
dist = ::GeoMagic::Distance.send(:distance, *points)
unit ? dist.send(unit) : dist
end
@@ -2,7 +2,7 @@
module GeoMagic
module UnitExt
- ::GeoMagic::Distance.units.each do |unit|
+ ::GeoMagic::Distance.all_units.each do |unit|
class_eval %{
def #{unit}
GeoMagic::Distance.new(self, :#{unit})
View
@@ -4,6 +4,7 @@
require 'geo_magic/distance/formula'
require 'geo_magic/distance/point_distance'
require 'geo_magic/distance/points_distance'
+require 'geo_magic/distance/unit'
module GeoMagic
class Distance
@@ -27,15 +28,18 @@ def reject_all points
def initialize distance, unit = :radians, options = {}
check_numeric! distance
@distance = distance
+ unit = GeoMagic::Unit.key unit
raise ArgumentError, "Invalid unit: #{unit} - must be one of #{GeoMagic::Distance.units}" if !GeoMagic::Distance.units.include?(unit.to_sym)
- @unit = unit.to_sym
+ @unit = unit
@lat_factor = options[:lat_factor] || 1
end
[:<, :<=, :>, :>=, :==].each do |op|
class_eval %{
def #{op} dist_unit
- in_meters #{op} dist_unit.in_meters
+ raise ArgumentError, "Must be compared with either a GeoMagic::Distance or a Fixnum (number)" if !dist_unit.any_kind_of?(Fixnum, GeoMagic::Distance)
+ dist = dist_unit.kind_of?(Fixnum) ? dist_unit : dist_unit.in_meters
+ in_meters #{op} dist
end
}
end
@@ -72,17 +76,7 @@ def to_s
def check_numeric! arg
raise ArgumentError, "Argument must be Numeric" if !arg.is_a? Numeric
- end
-
- def precision
- {
- :feet => 0,
- :meters => 2,
- :km => 4,
- :miles => 4,
- :radians => 4
- }
- end
+ end
end
end
@@ -4,19 +4,34 @@ module ClassMethods
# 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}
+ {
+ :feet => 20895592,
+ :meters => 6371000,
+ :kms => 6371,
+ :miles => 3956
+ }
end
def radian_radius
- {:km => 6371/180, :miles => 3956/180, :feet => 20895592/180, :meters => 6371000/180}
+ {
+ :feet => 364491.8,
+ :meters => 111170,
+ :kms => 111.17,
+ :miles => 69.407,
+ :radians => 1
+ }
end
def radians_per_degree
0.017453293 # PI/180
end
+ def all_units
+ [:miles, :mile, :kms, :km, :feet, :foot, :meter, :meters, :radians, :rad]
+ end
+
def units
- [:miles, :km, :feet, :meters, :radians]
+ [:miles, :kms, :feet, :meters, :radians]
end
def valid_radius_type? type
@@ -9,13 +9,15 @@ def [] key
(::GeoMagic::Distance.units - [:meters]).each do |unit|
class_eval %{
def in_#{unit}
- dist = (unit == :radians) ? in_radians : distance
- convert_to_meters(dist) * meters_map[:#{unit}]
+ dist = (unit == :radians) ? in_radians : distance
+ un = GeoMagic::Unit.key :#{unit}
+ convert_to_meters(dist) * GeoMagic::Unit.meters_map[un]
end
def to_#{unit}!
- self.distance = in_meters * meters_map[:#{unit}]
- self.unit = :#{unit}
+ un = GeoMagic::Unit.key :#{unit}
+ self.distance = in_meters * GeoMagic::Unit.meters_map[un]
+ self.unit = un
self
end
}
@@ -35,20 +37,26 @@ def to_meters!
self
end
- ::GeoMagic::Distance.units.each do |unit|
- class_eval %{
+ ::GeoMagic::Distance.all_units.each do |unit|
+ class_eval %{
def #{unit}
- as_#{unit}
- end
-
+ un = GeoMagic::Unit.key :#{unit}
+ send(:"as_\#{un}")
+ end
+ }
+ end
+
+ ::GeoMagic::Distance.units.each do |unit|
+ class_eval %{
def as_#{unit}
in_#{unit}
end
def to_#{unit}
- cloned = self.dup
- cloned.distance = in_meters * meters_map[:#{unit}]
- cloned.unit = :#{unit}
+ cloned = self.dup
+ un = GeoMagic::Unit.key :#{unit}
+ cloned.distance = in_meters * GeoMagic::Unit.meters_map[un]
+ cloned.unit = un
cloned
end
}
@@ -80,7 +88,8 @@ def in_radians
GeoMagic::Distance.units.each do |unit|
class_eval %{
def delta_#{unit}
- GeoMagic::Distance.earth_radius[:#{unit}]
+ un = GeoMagic::Unit.key :#{unit}
+ GeoMagic::Distance.earth_radius[un]
end
}
end
@@ -90,38 +99,6 @@ def delta_#{unit}
def earth_factor u = nil
(GeoMagic::Distance.earth_radius[u ||= unit] / 180) * lat_factor
end
-
- # from mongoid-geo, as suggested by niedhui :)
- def radian_multiplier
- {
- :feet => 364491.8,
- :ft => 364491.8,
- :m => 111170,
- :meter => 111170,
- :meters => 111170,
- :km => 111.17,
- :kms => 111.17,
- :mil => 69.407,
- :mile => 69.407,
- :miles => 69.407
- }
- end
-
- def meters_map
- {
- :mil => 69.407,
- :mile => 0.00062137,
- :miles => 0.00062137,
- :ft => 3.2808,
- :feet => 3.2808,
- :km => 0.001,
- :kms => 0.001,
- :kilometers => 0.001,
- :m => 1,
- :meter => 1,
- :meters => 1
- }
- end
end
end
end
@@ -2,10 +2,43 @@ module GeoMagic
class Unit
class << self
- def key unit
+ def key unit = :km
+ unit = unit.to_sym
methods.grep(/_unit/).each do |meth|
- return meth.chomp('_unit').to_sym
+ return meth.to_s.chomp('_unit').to_sym if send(meth).include? unit
end
+ raise ArgumentError, "Unknown unit key: #{unit}"
+ end
+
+ def precision
+ {
+ :feet => 0,
+ :meters => 2,
+ :kms => 4,
+ :miles => 4,
+ :radians => 4
+ }
+ end
+
+ # from mongoid-geo, as suggested by niedhui :)
+ def radian_multiplier
+ {
+ :feet => 364491.8,
+ :meters => 111170,
+ :kms => 111.17,
+ :miles => 69.407,
+ :radians => 1
+ }
+ end
+
+ def meters_map
+ {
+ :feet => 3.2808,
+ :meters => 1,
+ :kms => 0.001,
+ :miles => 0.00062137,
+ :radians => 111170
+ }
end
protected
@@ -14,17 +47,21 @@ def feet_unit
[:ft, :feet, :foot]
end
- def meter_unit
+ def meters_unit
[:m, :meter, :meters]
end
- def km_unit
+ def kms_unit
[:km, :kms, :kilometer, :kilometers]
end
- def mile_unit
+ def miles_unit
[:mil, :mile, :miles]
end
+
+ def radians_unit
+ [:rad, :radians]
+ end
end
end
end
@@ -1,6 +1,6 @@
require 'spec_helper'
-RAD_KM_LAT45 = GeoMagic::Distance.radian_radius[:km] * 2
+RAD_KM_LAT45 = GeoMagic::Distance.radian_radius[:kms] * 2
describe GeoMagic::Vector do
context 'an almost 1 radian vector' do
@@ -41,13 +41,13 @@
describe '#length' do
describe ':latitude' do
it "is has a latitude length of ..." do
- @vector.length(:latitude).in_km.should >= 0.5
+ @vector.length(:latitude).in_kms.should >= 0.5
end
end
describe ':longitude' do
it "is has a longitude length of ..." do
- @vector.length(:longitude).in_km.should >= 0.5
+ @vector.length(:longitude).in_kms.should >= 0.5
end
end
end

0 comments on commit 3f7ffff

Please sign in to comment.