Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added unit class

  • Loading branch information...
commit 3f7ffffb62f568a722d2514641e9d55ddeb55b6d 1 parent 729577b
Kristian Mandrup authored
2  lib/geo_magic/calculate.rb
@@ -11,7 +11,7 @@ module ClassMethods
11 11 def distance *args
12 12 points = extract_points *args
13 13 options = extract_options *args
14   - unit = options[:unit]
  14 + unit = GeoMagic::Unit.key options[:unit] if options[:unit]
15 15 dist = ::GeoMagic::Distance.send(:distance, *points)
16 16 unit ? dist.send(unit) : dist
17 17 end
2  lib/geo_magic/core_ext.rb
@@ -2,7 +2,7 @@
2 2
3 3 module GeoMagic
4 4 module UnitExt
5   - ::GeoMagic::Distance.units.each do |unit|
  5 + ::GeoMagic::Distance.all_units.each do |unit|
6 6 class_eval %{
7 7 def #{unit}
8 8 GeoMagic::Distance.new(self, :#{unit})
20 lib/geo_magic/distance.rb
@@ -4,6 +4,7 @@
4 4 require 'geo_magic/distance/formula'
5 5 require 'geo_magic/distance/point_distance'
6 6 require 'geo_magic/distance/points_distance'
  7 +require 'geo_magic/distance/unit'
7 8
8 9 module GeoMagic
9 10 class Distance
@@ -27,15 +28,18 @@ def reject_all points
27 28 def initialize distance, unit = :radians, options = {}
28 29 check_numeric! distance
29 30 @distance = distance
  31 + unit = GeoMagic::Unit.key unit
30 32 raise ArgumentError, "Invalid unit: #{unit} - must be one of #{GeoMagic::Distance.units}" if !GeoMagic::Distance.units.include?(unit.to_sym)
31   - @unit = unit.to_sym
  33 + @unit = unit
32 34 @lat_factor = options[:lat_factor] || 1
33 35 end
34 36
35 37 [:<, :<=, :>, :>=, :==].each do |op|
36 38 class_eval %{
37 39 def #{op} dist_unit
38   - in_meters #{op} dist_unit.in_meters
  40 + raise ArgumentError, "Must be compared with either a GeoMagic::Distance or a Fixnum (number)" if !dist_unit.any_kind_of?(Fixnum, GeoMagic::Distance)
  41 + dist = dist_unit.kind_of?(Fixnum) ? dist_unit : dist_unit.in_meters
  42 + in_meters #{op} dist
39 43 end
40 44 }
41 45 end
@@ -72,17 +76,7 @@ def to_s
72 76
73 77 def check_numeric! arg
74 78 raise ArgumentError, "Argument must be Numeric" if !arg.is_a? Numeric
75   - end
76   -
77   - def precision
78   - {
79   - :feet => 0,
80   - :meters => 2,
81   - :km => 4,
82   - :miles => 4,
83   - :radians => 4
84   - }
85   - end
  79 + end
86 80 end
87 81 end
88 82
21 lib/geo_magic/distance/class_methods.rb
@@ -4,19 +4,34 @@ module ClassMethods
4 4 # radius of the great circle in miles
5 5 # radius in kilometers...some algorithms use 6367
6 6 def earth_radius
7   - {:km => 6371, :miles => 3956, :feet => 20895592, :meters => 6371000}
  7 + {
  8 + :feet => 20895592,
  9 + :meters => 6371000,
  10 + :kms => 6371,
  11 + :miles => 3956
  12 + }
8 13 end
9 14
10 15 def radian_radius
11   - {:km => 6371/180, :miles => 3956/180, :feet => 20895592/180, :meters => 6371000/180}
  16 + {
  17 + :feet => 364491.8,
  18 + :meters => 111170,
  19 + :kms => 111.17,
  20 + :miles => 69.407,
  21 + :radians => 1
  22 + }
12 23 end
13 24
14 25 def radians_per_degree
15 26 0.017453293 # PI/180
16 27 end
17 28
  29 + def all_units
  30 + [:miles, :mile, :kms, :km, :feet, :foot, :meter, :meters, :radians, :rad]
  31 + end
  32 +
18 33 def units
19   - [:miles, :km, :feet, :meters, :radians]
  34 + [:miles, :kms, :feet, :meters, :radians]
20 35 end
21 36
22 37 def valid_radius_type? type
67 lib/geo_magic/distance/conversion.rb
@@ -9,13 +9,15 @@ def [] key
9 9 (::GeoMagic::Distance.units - [:meters]).each do |unit|
10 10 class_eval %{
11 11 def in_#{unit}
12   - dist = (unit == :radians) ? in_radians : distance
13   - convert_to_meters(dist) * meters_map[:#{unit}]
  12 + dist = (unit == :radians) ? in_radians : distance
  13 + un = GeoMagic::Unit.key :#{unit}
  14 + convert_to_meters(dist) * GeoMagic::Unit.meters_map[un]
14 15 end
15 16
16 17 def to_#{unit}!
17   - self.distance = in_meters * meters_map[:#{unit}]
18   - self.unit = :#{unit}
  18 + un = GeoMagic::Unit.key :#{unit}
  19 + self.distance = in_meters * GeoMagic::Unit.meters_map[un]
  20 + self.unit = un
19 21 self
20 22 end
21 23 }
@@ -35,20 +37,26 @@ def to_meters!
35 37 self
36 38 end
37 39
38   - ::GeoMagic::Distance.units.each do |unit|
39   - class_eval %{
  40 + ::GeoMagic::Distance.all_units.each do |unit|
  41 + class_eval %{
40 42 def #{unit}
41   - as_#{unit}
42   - end
43   -
  43 + un = GeoMagic::Unit.key :#{unit}
  44 + send(:"as_\#{un}")
  45 + end
  46 + }
  47 + end
  48 +
  49 + ::GeoMagic::Distance.units.each do |unit|
  50 + class_eval %{
44 51 def as_#{unit}
45 52 in_#{unit}
46 53 end
47 54
48 55 def to_#{unit}
49   - cloned = self.dup
50   - cloned.distance = in_meters * meters_map[:#{unit}]
51   - cloned.unit = :#{unit}
  56 + cloned = self.dup
  57 + un = GeoMagic::Unit.key :#{unit}
  58 + cloned.distance = in_meters * GeoMagic::Unit.meters_map[un]
  59 + cloned.unit = un
52 60 cloned
53 61 end
54 62 }
@@ -80,7 +88,8 @@ def in_radians
80 88 GeoMagic::Distance.units.each do |unit|
81 89 class_eval %{
82 90 def delta_#{unit}
83   - GeoMagic::Distance.earth_radius[:#{unit}]
  91 + un = GeoMagic::Unit.key :#{unit}
  92 + GeoMagic::Distance.earth_radius[un]
84 93 end
85 94 }
86 95 end
@@ -90,38 +99,6 @@ def delta_#{unit}
90 99 def earth_factor u = nil
91 100 (GeoMagic::Distance.earth_radius[u ||= unit] / 180) * lat_factor
92 101 end
93   -
94   - # from mongoid-geo, as suggested by niedhui :)
95   - def radian_multiplier
96   - {
97   - :feet => 364491.8,
98   - :ft => 364491.8,
99   - :m => 111170,
100   - :meter => 111170,
101   - :meters => 111170,
102   - :km => 111.17,
103   - :kms => 111.17,
104   - :mil => 69.407,
105   - :mile => 69.407,
106   - :miles => 69.407
107   - }
108   - end
109   -
110   - def meters_map
111   - {
112   - :mil => 69.407,
113   - :mile => 0.00062137,
114   - :miles => 0.00062137,
115   - :ft => 3.2808,
116   - :feet => 3.2808,
117   - :km => 0.001,
118   - :kms => 0.001,
119   - :kilometers => 0.001,
120   - :m => 1,
121   - :meter => 1,
122   - :meters => 1
123   - }
124   - end
125 102 end
126 103 end
127 104 end
47 lib/geo_magic/distance/unit.rb
@@ -2,10 +2,43 @@ module GeoMagic
2 2 class Unit
3 3 class << self
4 4
5   - def key unit
  5 + def key unit = :km
  6 + unit = unit.to_sym
6 7 methods.grep(/_unit/).each do |meth|
7   - return meth.chomp('_unit').to_sym
  8 + return meth.to_s.chomp('_unit').to_sym if send(meth).include? unit
8 9 end
  10 + raise ArgumentError, "Unknown unit key: #{unit}"
  11 + end
  12 +
  13 + def precision
  14 + {
  15 + :feet => 0,
  16 + :meters => 2,
  17 + :kms => 4,
  18 + :miles => 4,
  19 + :radians => 4
  20 + }
  21 + end
  22 +
  23 + # from mongoid-geo, as suggested by niedhui :)
  24 + def radian_multiplier
  25 + {
  26 + :feet => 364491.8,
  27 + :meters => 111170,
  28 + :kms => 111.17,
  29 + :miles => 69.407,
  30 + :radians => 1
  31 + }
  32 + end
  33 +
  34 + def meters_map
  35 + {
  36 + :feet => 3.2808,
  37 + :meters => 1,
  38 + :kms => 0.001,
  39 + :miles => 0.00062137,
  40 + :radians => 111170
  41 + }
9 42 end
10 43
11 44 protected
@@ -14,17 +47,21 @@ def feet_unit
14 47 [:ft, :feet, :foot]
15 48 end
16 49
17   - def meter_unit
  50 + def meters_unit
18 51 [:m, :meter, :meters]
19 52 end
20 53
21   - def km_unit
  54 + def kms_unit
22 55 [:km, :kms, :kilometer, :kilometers]
23 56 end
24 57
25   - def mile_unit
  58 + def miles_unit
26 59 [:mil, :mile, :miles]
27 60 end
  61 +
  62 + def radians_unit
  63 + [:rad, :radians]
  64 + end
28 65 end
29 66 end
30 67 end
6 spec/geo_magic/vector_spec.rb
... ... @@ -1,6 +1,6 @@
1 1 require 'spec_helper'
2 2
3   -RAD_KM_LAT45 = GeoMagic::Distance.radian_radius[:km] * 2
  3 +RAD_KM_LAT45 = GeoMagic::Distance.radian_radius[:kms] * 2
4 4
5 5 describe GeoMagic::Vector do
6 6 context 'an almost 1 radian vector' do
@@ -41,13 +41,13 @@
41 41 describe '#length' do
42 42 describe ':latitude' do
43 43 it "is has a latitude length of ..." do
44   - @vector.length(:latitude).in_km.should >= 0.5
  44 + @vector.length(:latitude).in_kms.should >= 0.5
45 45 end
46 46 end
47 47
48 48 describe ':longitude' do
49 49 it "is has a longitude length of ..." do
50   - @vector.length(:longitude).in_km.should >= 0.5
  50 + @vector.length(:longitude).in_kms.should >= 0.5
51 51 end
52 52 end
53 53 end

0 comments on commit 3f7ffff

Please sign in to comment.
Something went wrong with that request. Please try again.