geo_calc 0.6.1 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/Gemfile +3 -0
  2. data/README.textile +12 -0
  3. data/VERSION +1 -1
  4. data/geo_calc.gemspec +29 -6
  5. data/lib/geo_calc/calc/destination.rb +1 -1
  6. data/lib/geo_calc/calc/distance.rb +1 -1
  7. data/lib/geo_calc/calc/rhumb.rb +2 -2
  8. data/lib/geo_calc/calc.rb +20 -21
  9. data/lib/geo_calc/dms/converter.rb +106 -0
  10. data/lib/geo_calc/dms.rb +5 -0
  11. data/lib/geo_calc/extensions/array.rb +26 -0
  12. data/lib/geo_calc/extensions/hash.rb +23 -0
  13. data/lib/geo_calc/extensions/math.rb +6 -0
  14. data/lib/geo_calc/extensions/numeric.rb +24 -0
  15. data/lib/geo_calc/extensions/string.rb +44 -0
  16. data/lib/geo_calc/extensions/symbol.rb +9 -0
  17. data/lib/geo_calc/extensions.rb +4 -0
  18. data/lib/geo_calc/geo_point/class_methods.rb +15 -0
  19. data/lib/geo_calc/geo_point/core_extension.rb +11 -0
  20. data/lib/geo_calc/geo_point/shared.rb +29 -0
  21. data/lib/geo_calc/geo_point.rb +42 -40
  22. data/lib/geo_calc/pretty_print.rb +2 -2
  23. data/lib/geo_calc.rb +5 -0
  24. data/lib/geo_units/converter.rb +123 -0
  25. data/lib/geo_units/numeric_ext.rb +117 -0
  26. data/lib/geo_units.rb +21 -0
  27. data/spec/geo_calc/core_ext/numeric_geo_ext_spec.rb +48 -50
  28. data/spec/geo_calc/core_ext_spec.rb +49 -51
  29. data/spec/geo_calc/dms/converter_spec.rb +60 -0
  30. data/spec/geo_calc/geo_point/class_methods_spec.rb +31 -0
  31. data/spec/geo_calc/geo_point/initializer_spec.rb +148 -0
  32. data/spec/geo_calc/geo_point/lat_lon.rb +115 -0
  33. data/spec/geo_calc/geo_point_spec.rb +4 -274
  34. data/spec/geo_units/converter_spec.rb +57 -0
  35. metadata +56 -17
  36. data/lib/geo_calc/core_ext.rb +0 -318
  37. data/lib/geo_calc/geo.rb +0 -171
  38. data/spec/geo_calc/geo_spec.rb +0 -99
data/Gemfile CHANGED
@@ -1,5 +1,8 @@
1
1
  source "http://rubygems.org"
2
2
 
3
+ gem "require_all", "~> 1.2.0"
4
+ gem "sugar-high", "~> 0.4.5.2"
5
+
3
6
  # Add dependencies to develop your gem here.
4
7
  # Include everything needed to run rake, tests, features, etc.
5
8
  group :development do
data/README.textile CHANGED
@@ -2,6 +2,18 @@ h1. Geo calculations
2
2
 
3
3
  Geo Calculation library. Useful functions to add to your geo arsenal, fx when designing your own Geo library.
4
4
 
5
+ h2. Status update (June 10, 2011)
6
+
7
+ - Major refactoring splitting into more logical file/modular structure
8
+ - Use autoload
9
+ - Extract GeoUnits
10
+ - Extract Dms with converter
11
+ - GeoPoint can now have set :coords_mode which affects how Ruby Core objects such as String and Array are parsed into :lng and :lat.
12
+
13
+ TODO:
14
+ - The GeoPoint class should be extracted into separate gem, then this geo_calc gem should only have the more generic geo functionality as modules to be included
15
+ where needed in other gems!
16
+
5
17
  h2. Install
6
18
 
7
19
  @require 'geo_calc'@
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 0.7.1
data/geo_calc.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{geo_calc}
8
- s.version = "0.6.1"
8
+ s.version = "0.7.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{Kristian Mandrup}]
12
- s.date = %q{2011-05-31}
12
+ s.date = %q{2011-06-11}
13
13
  s.description = %q{Geo calculations in ruby and javascript}
14
14
  s.email = %q{kmandrup@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -34,37 +34,58 @@ Gem::Specification.new do |s|
34
34
  "lib/geo_calc/calc/intersection.rb",
35
35
  "lib/geo_calc/calc/midpoint.rb",
36
36
  "lib/geo_calc/calc/rhumb.rb",
37
- "lib/geo_calc/core_ext.rb",
38
- "lib/geo_calc/geo.rb",
37
+ "lib/geo_calc/dms.rb",
38
+ "lib/geo_calc/dms/converter.rb",
39
+ "lib/geo_calc/extensions.rb",
40
+ "lib/geo_calc/extensions/array.rb",
41
+ "lib/geo_calc/extensions/hash.rb",
42
+ "lib/geo_calc/extensions/math.rb",
43
+ "lib/geo_calc/extensions/numeric.rb",
44
+ "lib/geo_calc/extensions/string.rb",
45
+ "lib/geo_calc/extensions/symbol.rb",
39
46
  "lib/geo_calc/geo_point.rb",
47
+ "lib/geo_calc/geo_point/class_methods.rb",
48
+ "lib/geo_calc/geo_point/core_extension.rb",
49
+ "lib/geo_calc/geo_point/shared.rb",
40
50
  "lib/geo_calc/pretty_print.rb",
51
+ "lib/geo_units.rb",
52
+ "lib/geo_units/converter.rb",
53
+ "lib/geo_units/numeric_ext.rb",
41
54
  "spec/geo_calc/calculations_spec.rb",
42
55
  "spec/geo_calc/core_ext/array_ext_spec.rb",
43
56
  "spec/geo_calc/core_ext/hash_ext_spec.rb",
44
57
  "spec/geo_calc/core_ext/numeric_geo_ext_spec.rb",
45
58
  "spec/geo_calc/core_ext/string_ext_spec.rb",
46
59
  "spec/geo_calc/core_ext_spec.rb",
60
+ "spec/geo_calc/dms/converter_spec.rb",
61
+ "spec/geo_calc/geo_point/class_methods_spec.rb",
62
+ "spec/geo_calc/geo_point/initializer_spec.rb",
63
+ "spec/geo_calc/geo_point/lat_lon.rb",
47
64
  "spec/geo_calc/geo_point_spec.rb",
48
- "spec/geo_calc/geo_spec.rb",
65
+ "spec/geo_units/converter_spec.rb",
49
66
  "spec/spec_helper.rb",
50
67
  "vendor/assets/javascript/geo_calc.js"
51
68
  ]
52
69
  s.homepage = %q{http://github.com/kristianmandrup/geo_calc}
53
70
  s.licenses = [%q{MIT}]
54
71
  s.require_paths = [%q{lib}]
55
- s.rubygems_version = %q{1.8.3}
72
+ s.rubygems_version = %q{1.8.5}
56
73
  s.summary = %q{Geo calculation library}
57
74
 
58
75
  if s.respond_to? :specification_version then
59
76
  s.specification_version = 3
60
77
 
61
78
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
79
+ s.add_runtime_dependency(%q<require_all>, ["~> 1.2.0"])
80
+ s.add_runtime_dependency(%q<sugar-high>, ["~> 0.4.5.2"])
62
81
  s.add_development_dependency(%q<rspec>, [">= 2.5.0"])
63
82
  s.add_development_dependency(%q<bundler>, [">= 1"])
64
83
  s.add_development_dependency(%q<jeweler>, [">= 1.5.2"])
65
84
  s.add_development_dependency(%q<rcov>, [">= 0"])
66
85
  s.add_development_dependency(%q<rake>, [">= 0.9"])
67
86
  else
87
+ s.add_dependency(%q<require_all>, ["~> 1.2.0"])
88
+ s.add_dependency(%q<sugar-high>, ["~> 0.4.5.2"])
68
89
  s.add_dependency(%q<rspec>, [">= 2.5.0"])
69
90
  s.add_dependency(%q<bundler>, [">= 1"])
70
91
  s.add_dependency(%q<jeweler>, [">= 1.5.2"])
@@ -72,6 +93,8 @@ Gem::Specification.new do |s|
72
93
  s.add_dependency(%q<rake>, [">= 0.9"])
73
94
  end
74
95
  else
96
+ s.add_dependency(%q<require_all>, ["~> 1.2.0"])
97
+ s.add_dependency(%q<sugar-high>, ["~> 0.4.5.2"])
75
98
  s.add_dependency(%q<rspec>, [">= 2.5.0"])
76
99
  s.add_dependency(%q<bundler>, [">= 1"])
77
100
  s.add_dependency(%q<jeweler>, [">= 1.5.2"])
@@ -14,7 +14,7 @@ module GeoCalc::Calc
14
14
  # Returns GeoPoint: Destination point
15
15
 
16
16
  def self.destination_point base_point, brng, dist
17
- dist = dist / base_point.radius # convert dist to angular distance in radians
17
+ dist = dist / base_point.earth_radius_km # convert dist to angular distance in radians
18
18
  brng = brng.to_rad
19
19
  lat1 = base_point.lat.to_rad
20
20
  lon1 = base_point.lon.to_rad
@@ -35,7 +35,7 @@ module GeoCalc::Calc
35
35
 
36
36
  a = Math.sin(dlat/2) * Math.sin(dlat/2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dlon/2) * Math.sin(dlon/2)
37
37
  c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
38
- d = base_point.radius * c
38
+ d = base_point.earth_radius_km * c
39
39
  d.round(precision)
40
40
  end
41
41
  end
@@ -29,7 +29,7 @@ module GeoCalc::Calc
29
29
  # if dlon over 180° take shorter rhumb across 180° meridian:
30
30
  dlon = 2*Math::PI - dlon if (dlon > Math::PI)
31
31
 
32
- dist = Math.sqrt(dlat*dlat + q*q*dlon*dlon) * base_point.radius;
32
+ dist = Math.sqrt(dlat*dlat + q*q*dlon*dlon) * base_point.earth_radius_km;
33
33
 
34
34
  dist.round(4) # 4 sig figures reflects typical 0.3% accuracy of spherical model
35
35
  end
@@ -69,7 +69,7 @@ module GeoCalc::Calc
69
69
  # @returns {LatLon} Destination point
70
70
 
71
71
  def self.rhumb_destination_point base_point, brng, dist
72
- d = dist / base_point.radius # d = angular distance covered on earth's surface
72
+ d = dist / base_point.earth_radius_km # d = angular distance covered on earth's surface
73
73
  lat1 = base_point.lat.to_rad
74
74
  lon1 = base_point.lon.to_rad
75
75
  brng = brng.to_rad
data/lib/geo_calc/calc.rb CHANGED
@@ -1,27 +1,26 @@
1
1
  module GeoCalc
2
2
  autoload :PrettyPrint, 'geo_calc/pretty_print'
3
-
4
- module Calc
5
- end
6
3
  end
7
4
 
8
- module GeoCalc::Calc
9
- autoload :Bearing, 'geo_calc/calc/bearing'
10
- autoload :Destination, 'geo_calc/calc/destination'
11
- autoload :Distance, 'geo_calc/calc/distance'
12
- autoload :Intersection, 'geo_calc/calc/intersection'
13
- autoload :Midpoint, 'geo_calc/calc/midpoint'
14
- autoload :Rhumb, 'geo_calc/calc/rhumb'
5
+ module GeoCalc
6
+ module Calc
7
+ autoload :Bearing, 'geo_calc/calc/bearing'
8
+ autoload :Destination, 'geo_calc/calc/destination'
9
+ autoload :Distance, 'geo_calc/calc/distance'
10
+ autoload :Intersection, 'geo_calc/calc/intersection'
11
+ autoload :Midpoint, 'geo_calc/calc/midpoint'
12
+ autoload :Rhumb, 'geo_calc/calc/rhumb'
15
13
 
16
- module All
17
- def self.included base
18
- base.send :include, GeoCalc::Calc::Bearing
19
- base.send :include, GeoCalc::Calc::Destination
20
- base.send :include, GeoCalc::Calc::Distance
21
- base.send :include, GeoCalc::Calc::Intersection
22
- base.send :include, GeoCalc::Calc::Midpoint
23
- base.send :include, GeoCalc::Calc::Rhumb
24
- base.send :include, GeoCalc::PrettyPrint
25
- end
26
- end
14
+ module All
15
+ def self.included base
16
+ base.send :include, GeoCalc::Calc::Bearing
17
+ base.send :include, GeoCalc::Calc::Destination
18
+ base.send :include, GeoCalc::Calc::Distance
19
+ base.send :include, GeoCalc::Calc::Intersection
20
+ base.send :include, GeoCalc::Calc::Midpoint
21
+ base.send :include, GeoCalc::Calc::Rhumb
22
+ base.send :include, GeoCalc::PrettyPrint
23
+ end
24
+ end
25
+ end
27
26
  end
@@ -0,0 +1,106 @@
1
+ module GeoCalc
2
+ module Dms
3
+ module Converter
4
+ include GeoCalc::NumericCheckExt
5
+
6
+ def parse_dms dms_str
7
+ # check for signed decimal degrees without NSEW, if so return it directly
8
+ return dms_str if is_numeric?(dms_str)
9
+
10
+ # strip off any sign or compass dir'n & split out separate d/m/s
11
+ dms = dms_str.trim.gsub(/^-/,'').gsub(/[NSEW]$/i,'').split(/[^0-9.,]+/).map(&:trim).map(&:to_f)
12
+ return nil if dms.empty?
13
+
14
+ # and convert to decimal degrees...
15
+ deg = case dms.length
16
+ when 3 # interpret 3-part result as d/m/s
17
+ dms[0]/1 + dms[1]/60 + dms[2]/3600
18
+ when 2 # interpret 2-part result as d/m
19
+ dms[0]/1 + dms[1]/60
20
+ when 1 # just d (possibly decimal) or non-separated dddmmss
21
+ d = dms[0];
22
+ # check for fixed-width unseparated format eg 0033709W
23
+ d = "0#{d}" if (/[NS]/i.match(dms_str)) # - normalise N/S to 3-digit degrees
24
+ d = "#{d.slice(0,3)/1}#{deg.slice(3,5)/60}#{deg.slice(5)/3600}" if (/[0-9]{7}/.match(deg))
25
+ d
26
+ else
27
+ nil
28
+ end
29
+ return nil if !deg
30
+ deg = (deg * -1) if (/^-|[WS]$/i.match(dms_str.trim)) # take '-', west and south as -ve
31
+ deg.to_f
32
+ end
33
+
34
+ # Convert decimal degrees to deg/min/sec format
35
+ # - degree, prime, double-prime symbols are added, but sign is discarded, though no compass
36
+ # direction is added
37
+ #
38
+ #
39
+ # @param {Number} deg: Degrees
40
+ # @param {String} [format=dms]: Return value as 'd', 'dm', 'dms'
41
+ # @param {Number} [dp=0|2|4]: No of decimal places to use - default 0 for dms, 2 for dm, 4 for d
42
+ # @returns {String} deg formatted as deg/min/secs according to specified format
43
+ # @throws {TypeError} deg is an object, perhaps DOM object without .value?
44
+
45
+ def to_dms deg, format = :dms, dp = nil
46
+ deg = begin
47
+ deg.to_f
48
+ rescue
49
+ nil
50
+ end
51
+ return nil if !deg # give up here if we can't make a number from deg
52
+
53
+ # default values
54
+ format ||= :dms
55
+ dp = if dp.nil?
56
+ case format.to_sym
57
+ when :d
58
+ 4
59
+ when :dm
60
+ 2
61
+ else
62
+ 0 # default
63
+ end
64
+ end
65
+ dp ||= 0
66
+
67
+ deg = deg.abs # (unsigned result ready for appending compass dir'n)
68
+
69
+ case format
70
+ when :d
71
+ d = deg.round(dp) # round degrees
72
+ ds = "0#{d}" if (d <100) # pad with leading zeros
73
+ ds = "0#{ds}" if (d <10)
74
+ dms = ds.to_s.concat("\u00B0") # add º symbol
75
+ when :dm
76
+ min = (deg*60).round(dp) # convert degrees to minutes & round
77
+ d = d.to_i
78
+ d = (min / 60).floor # get component deg/min
79
+ m = (min % 60).round(dp) # pad with trailing zeros
80
+ ds = d
81
+ ms = m
82
+ ds = "0#{d}" if (d<100) # pad with leading zeros
83
+ ds = "0#{d}" if (d<10)
84
+ ms = "0#{m}" if (m<10)
85
+ dms = ds.to_s.concat("\u00B0", ms, "\u2032") # add º, ' symbols
86
+ when :dms
87
+ sec = (deg * 3600).round # convert degrees to seconds & round
88
+ d = (sec / 3600).floor # get component deg/min/sec
89
+ m = ((sec / 60) % 60).floor
90
+ s = (sec % 60).round(dp) # pad with trailing zeros
91
+ ds = d
92
+ ms = m
93
+ ss = s
94
+ ds = "0#{d}" if (d < 100) # pad with leading zeros
95
+ ds = "0#{ds}" if (d < 10)
96
+ ms = "0#{m}" if (m < 10)
97
+ ss = "0#{s}" if (s < 10)
98
+ dms = ds.to_s.concat("\u00B0", ms, "\u2032", ss, "\u2033") # add º, ', " symbols
99
+ end
100
+ return dms
101
+ end
102
+
103
+ extend self
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,5 @@
1
+ module GeoCalc
2
+ module Dms
3
+ autoload :Converter, 'geo_calc/dms/converter'
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ class Array
2
+ include ::GeoPoint::CoreExtension
3
+
4
+ def to_lat_lng
5
+ raise "Array must contain at least two elements to be converted to latitude and longitude" if !(size >= 2)
6
+ [to_lat, to_lng]
7
+ end
8
+
9
+ def to_lng_lat
10
+ to_lat_lng.reverse
11
+ end
12
+
13
+ def to_lat
14
+ raise "Array must contain at least one element to return the latitude" if empty?
15
+ first.to_lat
16
+ end
17
+
18
+ def to_lng
19
+ raise "Array must contain at least two elements to return the longitude" if !self[1]
20
+ self[1].to_lng
21
+ end
22
+
23
+ def trim
24
+ join.trim
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ class Hash
2
+ include GeoPoint::CoreExtension
3
+
4
+ def to_lat_lng
5
+ [to_lat, to_lng]
6
+ end
7
+
8
+ def to_lng_lat
9
+ to_lat_lng.reverse
10
+ end
11
+
12
+ def to_lat
13
+ v = Symbol.lat_symbols.select {|key| self[key] }
14
+ return self[v.first].to_lat if !v.empty?
15
+ raise "Hash must contain either of the keys: [:lat, :latitude] to be converted to a latitude"
16
+ end
17
+
18
+ def to_lng
19
+ v = Symbol.lng_symbols.select {|key| self[key] }
20
+ return self[v.first].to_lng if !v.empty?
21
+ raise "Hash must contain either of the keys: [:lon, :long, :lng, :longitude] to be converted to a longitude"
22
+ end
23
+ end
@@ -0,0 +1,6 @@
1
+ module Math
2
+ def self.log10e
3
+ 0.4342944819032518
4
+ end
5
+ end
6
+
@@ -0,0 +1,24 @@
1
+ require 'geo_units'
2
+
3
+ module GeoCalc
4
+ module NumericCheckExt
5
+ def is_numeric? arg
6
+ arg.is_a? Numeric
7
+ end
8
+
9
+ alias_method :is_num?, :is_numeric?
10
+
11
+ def check_numeric! arg
12
+ raise ArgumentError, "Argument must be Numeric" if !is_numeric? arg
13
+ end
14
+ end
15
+ end
16
+
17
+ class Fixnum
18
+ include ::GeoUnits::NumericExt
19
+ end
20
+
21
+ class Float
22
+ include ::GeoUnits::NumericExt
23
+ end
24
+
@@ -0,0 +1,44 @@
1
+ class String
2
+ include ::GeoPoint::CoreExtension
3
+
4
+ def concat *args
5
+ args.inject(self) do |res, arg|
6
+ res << arg.to_s
7
+ res
8
+ end
9
+ end
10
+
11
+ def parse_dms
12
+ GeoCalc::Dms::Converter.parse_dms self
13
+ end
14
+
15
+ def to_rad
16
+ parse_dms.to_rad
17
+ end
18
+
19
+ def trim
20
+ strip
21
+ end
22
+
23
+ def geo_clean
24
+ self.gsub(/^\(/, '').gsub(/\)$/, '').trim
25
+ end
26
+
27
+ def to_lat_lng
28
+ geo_clean.split(',').to_lat_lng
29
+ end
30
+
31
+ def to_lng_lat
32
+ geo_clean.split(',').to_lng_lat
33
+ end
34
+
35
+ def to_lat
36
+ raise "An empty String has no latitude" if empty?
37
+ geo_clean.parse_dms.to_f.to_lat
38
+ end
39
+
40
+ def to_lng
41
+ raise "An empty String has no latitude" if empty?
42
+ geo_clean.parse_dms.to_f.to_lng
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ class Symbol
2
+ def self.lng_symbols
3
+ [:lon, :long, :lng, :longitude]
4
+ end
5
+
6
+ def self.lat_symbols
7
+ [:lat, :latitude]
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ require 'require_all'
2
+ require 'geo_calc/geo_point/core_extension'
3
+
4
+ require_all File.dirname(__FILE__) + '/extensions'
@@ -0,0 +1,15 @@
1
+ require 'geo_calc/geo_point/shared'
2
+
3
+ class GeoPoint
4
+ module ClassMethods
5
+ def earth_radius_km
6
+ @earth_radius_km ||= 6371
7
+ end
8
+
9
+ def coord_mode
10
+ @coord_mode ||= :lat_lng
11
+ end
12
+
13
+ include Shared
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ class GeoPoint
2
+ module CoreExtension
3
+ def to_coords
4
+ send(:"to_#{GeoPoint.coord_mode}")
5
+ end
6
+
7
+ def geo_point
8
+ GeoPoint.new to_coords
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,29 @@
1
+ class GeoPoint
2
+ module Shared
3
+ def unit
4
+ :degrees
5
+ end
6
+
7
+ def earth_radius_km= radius_km
8
+ raise ArgumentException, "Not a valid earth km radius: #{radius_km}" unless valid_earth_radius? radius_km
9
+ @earth_radius_km = radius_km
10
+ end
11
+
12
+ def coord_mode= mode
13
+ raise ArgumentException, "Not a valid coordinates mode: #{mode}" unless valid_mode? mode
14
+ @coord_mode = mode
15
+ end
16
+
17
+ protected
18
+
19
+ include GeoCalc::NumericCheckExt
20
+
21
+ def valid_earth_radius? radius_km
22
+ is_numeric?(radius_km) && radius_km.is_between?(6350, 6380)
23
+ end
24
+
25
+ def valid_mode? mode
26
+ [:lng_lat, :lat_lng].include? mode
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,7 @@
1
- require 'geo_calc/geo'
1
+ require 'sugar-high/arguments'
2
2
  require 'geo_calc/calc'
3
+ require 'geo_calc/extensions'
4
+ require 'geo_calc/geo_point/shared'
3
5
 
4
6
  # Sample usage:
5
7
  # p1 = GeoPoint.new(51.5136, -0.0983)
@@ -8,38 +10,48 @@ require 'geo_calc/calc'
8
10
  # brng = p1.bearing_to(p2) # in degrees clockwise from north
9
11
  # ... etc
10
12
  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
11
- #
12
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
13
- # Note that minimal error checking is performed in this example code!
14
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
15
13
 
16
14
  class GeoPoint
17
15
  include GeoCalc::Calc::All
16
+
17
+ autoload :Shared, 'geo_calc/geo_point/shared'
18
+ autoload :ClassMethods, 'geo_calc/geo_point/class_methods'
19
+ autoload :CoreExtension, 'geo_calc/geo_point/core_extension'
20
+
21
+ attr_reader :lat, :lon
22
+
18
23
  # Creates a point on the earth's surface at the supplied latitude / longitude
19
24
  #
20
- # Constructor
21
- # - Numeric lat: latitude in numeric degrees
22
- # - Numeric lon: longitude in numeric degrees
23
- # - Numeric [rad=6371]: radius of earth if different value is required from standard 6,371km
25
+ # - Numeric latitude in numeric degrees
26
+ # - Numeric longitude in numeric degrees
24
27
 
25
- attr_reader :lat, :lon
26
- attr_accessor :radius
27
-
28
+ # Optional options
29
+ # - :radius - earth radius in km
30
+ # - :mode - coordinates mode, either :lng_lat or :lat_lng, otherwise uses global setting as per GeoPoint.coord_mode
28
31
  def initialize *args
29
- rad = args.delete(args.size) if is_numeric?(args.last) && args.last.is_between?(6350, 6380)
30
- rad ||= 6371 # default
32
+ options = args.is_a?(GeoPoint) ? {} : args.last_option
33
+ earth_radius_km = options[:radius]
34
+ coord_mode = options[:mode]
35
+
31
36
  case args.size
32
37
  when 1
33
- create_from_one *args, rad
38
+ create_from_one args
34
39
  when 2
35
- create_from_two *args, rad
40
+ create_from_two *args
36
41
  else
37
42
  raise "GeoPoint must be initialized with either one or to arguments defining the (latitude, longitude) coordinate on the map"
38
43
  end
39
44
  end
40
45
 
41
- def unit
42
- :degrees
46
+ extend ClassMethods
47
+ include Shared
48
+
49
+ def coord_mode
50
+ @coord_mode ||= GeoPoint.coord_mode
51
+ end
52
+
53
+ def earth_radius_km
54
+ @earth_radius_km ||= GeoPoint.earth_radius_km # default
43
55
  end
44
56
 
45
57
  def lat= value
@@ -70,7 +82,7 @@ class GeoPoint
70
82
  case key
71
83
  when Fixnum
72
84
  raise ArgumentError, "Index must be 0 or 1" if !(0..1).cover?(key)
73
- to_arr[key]
85
+ to_a[key]
74
86
  when String, Symbol
75
87
  send(key) if respond_to? key
76
88
  else
@@ -98,36 +110,26 @@ class GeoPoint
98
110
  [lng, lat]
99
111
  end
100
112
 
101
- def to_arr
102
- a = to_lat_lng
103
- reverse_arr? ? a.reverse : a
104
- end
105
-
106
- def reverse_arr?
107
- @reverse_arr
108
- end
109
-
110
- def reverse_arr!
111
- @reverse_arr = true
112
- end
113
-
114
- def normal_arr!
115
- @reverse_arr = false
113
+ def to_a
114
+ send(:"to_#{coord_mode}")
116
115
  end
117
116
 
118
117
  protected
119
118
 
120
- include NumericCheckExt
119
+ include ::GeoCalc::NumericCheckExt
120
+
121
+ def to_coords points
122
+ points.send(:"to_#{coord_mode}")
123
+ end
121
124
 
122
- def create_from_one points, rad = 6371
123
- create_from_two *points.to_lat_lng, rad
125
+ def create_from_one args
126
+ args = args.first
127
+ create_from_two *to_coords(args)
124
128
  end
125
129
 
126
- def create_from_two lat, lon, rad = 6371
127
- rad ||= 6371 # earth's mean radius in km
130
+ def create_from_two lat, lon
128
131
  @lat = lat.to_lat
129
132
  @lon = lon.to_lng
130
- @radius = rad
131
133
  end
132
134
  end
133
135
 
@@ -43,8 +43,8 @@ module GeoCalc
43
43
 
44
44
  return '-,-' if !lat || !lon
45
45
 
46
- _lat = Geo.to_lat lat, format, dp
47
- _lon = Geo.to_lon lon, format, dp
46
+ _lat = GeoUnits::Converter.to_lat lat, format, dp
47
+ _lon = GeoUnits::Converter.to_lon lon, format, dp
48
48
 
49
49
  "#{_lat}, #{_lon}"
50
50
  end
data/lib/geo_calc.rb CHANGED
@@ -1 +1,6 @@
1
1
  require 'geo_calc/geo_point'
2
+ require 'geo_units'
3
+
4
+ module GeoCalc
5
+ autoload :Dms, 'geo_calc/dms'
6
+ end