geo_point 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "geo_calc", '~> 0.7.3'
4
+ gem "geo_units", '>= 0.2.0'
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", ">= 2.6.0"
10
+ gem "bundler", "~> 1.0.6"
11
+ gem "jeweler", "~> 1.6.2"
12
+ gem "rcov", ">= 0"
13
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Kristian Mandrup
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,103 @@
1
+ h1. Geo Point
2
+
3
+ Adds the concept of a GeoPoint for geo libraries. A GeoPoint encapsulates latitude and longitude, and:
4
+
5
+ * a coordinates mode (coord_mode) that can be set to either :lng_lat or :lat_lng
6
+ * calculations such as distance, bearing, midpoint etc.
7
+ * parsing from various String, Hash or Array formats, including from DMS string format, such as "58 38 38N, 003 04 12W"
8
+
9
+ Using GeoPoints makes it much easier and more efficient to transport location point data and various geo libraries adds additional functionality such as
10
+ vector operations on top (see fx _geo_vectors_ gem). Enjoy!
11
+
12
+ h2. Install
13
+
14
+ Gemfile:
15
+
16
+ @gem 'geo_point'@
17
+
18
+ $ bundle
19
+
20
+ h2. Quick start (Usage)
21
+
22
+ First define the points on the globe you want to work with.
23
+ The GeoPoint initializer is very flexible with regards to the arguments it can handle.
24
+
25
+ <pre>
26
+ # factory method on core ruby classes
27
+ "51 12 03 N, 24 10 02 E".geo_point
28
+ [51.5136, -0.0983].geo_point
29
+ {:latitude => 27.3, :longitude => "24 10 02 E"}.geo_point
30
+
31
+ # two arguments
32
+ p1 = GeoPoint.new 51.5136, -0.0983
33
+ p2 = GeoPoint.new "14 11 01 N", "-0.0983"
34
+ p3 = GeoPoint.new 51.5136, "24 10 02 E"
35
+
36
+ # a String
37
+ p1 = GeoPoint.new "51.5136, -0.0983"
38
+ p1 = GeoPoint.new "51.5136, 24 10 02 E"
39
+ p3 = GeoPoint.new "51.4778, -0.0015"
40
+ p1 = GeoPoint.new "51 12 03 N, 24 10 02 E"
41
+
42
+ # an Array
43
+ p2 = GeoPoint.new [51.5136, -0.0983]
44
+ p2 = GeoPoint.new [51.5136, "24 10 02 E"]
45
+ p2 = GeoPoint.new [51.5136, {:lon => 27.3}]
46
+
47
+ # a Hash
48
+ p4 = GeoPoint.new {:lat => 27.3, :lng => "24 10 02 E"}
49
+ p4 = GeoPoint.new {:latitude => 27.3, :longitude => "24 10 02 E"}
50
+ </pre>
51
+
52
+ h2. Utility methods
53
+
54
+ These are some of the utility methods you can use on a GeoPoint object
55
+
56
+ <pre>
57
+ p1 = GeoPoint.new 5.1, -7
58
+ p1.lat # latitude
59
+ p1.lon # longitude
60
+ p1.to_lat_lng # Array representation of [lat, lng]
61
+ p1.to_lng_lat # Array representation of [lng, lat]
62
+ p1.to_s # String representation (DMS format)
63
+ p1.to_coords # calls either #to_lat_lng or #to_lng_lat depending on global :coord_mode setting
64
+ </pre>
65
+
66
+ h2. Global configuration options
67
+
68
+ <pre>
69
+ GeoPoint.coord_mode = :lat_lng
70
+ GeoPoint.coord_mode = :lng_lat
71
+
72
+ GeoPoint.earth_radius_km = 6379
73
+ GeoPoint.earth_radius_km = 6371
74
+ </pre>
75
+
76
+ h2. GeoPoint functionality
77
+
78
+ A GeoPoint always has the following calculation API available:
79
+
80
+ * bearing
81
+ * destination
82
+ * distancer
83
+ * intersection
84
+ * midpoint
85
+ * rhumb (distance)
86
+
87
+ See the _geo_calc_ gem for details on how to use this Api
88
+
89
+ h2. Contributing to geo_point
90
+
91
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
92
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
93
+ * Fork the project
94
+ * Start a feature/bugfix branch
95
+ * Commit and push until you are happy with your contribution
96
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
97
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
98
+
99
+ h2. Copyright
100
+
101
+ Copyright (c) 2011 Kristian Mandrup. See LICENSE.txt for
102
+ further details.
103
+
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "geo_point"
18
+ gem.homepage = "http://github.com/kristianmandrup/geo_point"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{A GeoPoint encapsulates latitude, longitude and various geo calculations relative to itself}
21
+ gem.description = %Q{Allows for easy parsing of Strings, Hashes and Arrays into a GeoPoint with lat/long}
22
+ gem.email = "kmandrup@gmail.com"
23
+ gem.authors = ["Kristian Mandrup"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "geo_point #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/geo_point.gemspec ADDED
@@ -0,0 +1,72 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{geo_point}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{Kristian Mandrup}]
12
+ s.date = %q{2011-06-13}
13
+ s.description = %q{Allows for easy parsing of Strings, Hashes and Arrays into a GeoPoint with lat/long}
14
+ s.email = %q{kmandrup@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.textile"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "LICENSE.txt",
24
+ "README.textile",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "geo_point.gemspec",
28
+ "lib/geo_point.rb",
29
+ "lib/geo_point/calc.rb",
30
+ "lib/geo_point/class_methods.rb",
31
+ "lib/geo_point/core_extension.rb",
32
+ "lib/geo_point/shared.rb",
33
+ "spec/geo_point/class_methods_spec.rb",
34
+ "spec/geo_point/initializer_spec.rb",
35
+ "spec/geo_point/lat_lon.rb",
36
+ "spec/geo_point_spec.rb",
37
+ "spec/spec_helper.rb"
38
+ ]
39
+ s.homepage = %q{http://github.com/kristianmandrup/geo_point}
40
+ s.licenses = [%q{MIT}]
41
+ s.require_paths = [%q{lib}]
42
+ s.rubygems_version = %q{1.8.5}
43
+ s.summary = %q{A GeoPoint encapsulates latitude, longitude and various geo calculations relative to itself}
44
+
45
+ if s.respond_to? :specification_version then
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
+ s.add_runtime_dependency(%q<geo_calc>, ["~> 0.7.3"])
50
+ s.add_runtime_dependency(%q<geo_units>, [">= 0.2.0"])
51
+ s.add_development_dependency(%q<rspec>, [">= 2.6.0"])
52
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.6"])
53
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.2"])
54
+ s.add_development_dependency(%q<rcov>, [">= 0"])
55
+ else
56
+ s.add_dependency(%q<geo_calc>, ["~> 0.7.3"])
57
+ s.add_dependency(%q<geo_units>, [">= 0.2.0"])
58
+ s.add_dependency(%q<rspec>, [">= 2.6.0"])
59
+ s.add_dependency(%q<bundler>, ["~> 1.0.6"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
61
+ s.add_dependency(%q<rcov>, [">= 0"])
62
+ end
63
+ else
64
+ s.add_dependency(%q<geo_calc>, ["~> 0.7.3"])
65
+ s.add_dependency(%q<geo_units>, [">= 0.2.0"])
66
+ s.add_dependency(%q<rspec>, [">= 2.6.0"])
67
+ s.add_dependency(%q<bundler>, ["~> 1.0.6"])
68
+ s.add_dependency(%q<jeweler>, ["~> 1.6.2"])
69
+ s.add_dependency(%q<rcov>, [">= 0"])
70
+ end
71
+ end
72
+
@@ -0,0 +1,59 @@
1
+ class GeoPoint
2
+ module Calc
3
+ def self.included(base)
4
+ base.send :include, ::GeoCalc
5
+ base.send :include, Destination
6
+ base.send :include, Intersection
7
+ base.send :include, Midpoint
8
+ end
9
+
10
+ module Destination
11
+ def destination_point brng, dist
12
+ GeoPoint.new GeoCalc::Destination.destination_point(self, brng, dist).to_coords
13
+ end
14
+
15
+ # Returns the destination point from this point having travelled the given distance (in km) on the
16
+ # given initial bearing (bearing may vary before destination is reached)
17
+ #
18
+ # see http:#williams.best.vwh.net/avform.htm#LL
19
+ #
20
+ # - Numeric bearing: Initial bearing in degrees
21
+ # - Numeric dist: Distance in km
22
+ # Returns GeoPoint: Destination point
23
+ def self.destination_point base_point, brng, dist
24
+ GeoPoint.new GeoCalc::Destination.destination_point(base_point, brng, dist).to_coords
25
+ end
26
+ end
27
+
28
+ module Intersection
29
+ # see(#intersection)
30
+ # @returns [GeoPoint] Destination point (null if no unique intersection defined)
31
+ def self.intersection_point p1, brng1, p2, brng2
32
+ GeoPoint.new GeoCalc::Intersection.intersection(p1, brng1, p2, brng2).to_coords
33
+ end
34
+
35
+ # see(#intersection)
36
+ # @returns [GeoPoint] Destination point (null if no unique intersection defined)
37
+ def intersection_point brng1, p2, brng2
38
+ GeoPoint.new GeoCalc::Intersection.intersection(self, brng1, p2, brng2).to_coords
39
+ end
40
+ end
41
+
42
+ module Midpoint
43
+ def midpoint_to point
44
+ GeoPoint.new GeoCalc::Midpoint.midpoint_to(self, point).to_coords
45
+ end
46
+
47
+ # Returns the midpoint between this point and the supplied point.
48
+ # see(http:#mathforum.org/library/drmath/view/51822.html for derivation)
49
+ #
50
+ # @param [GeoPoint] base_point: Starting point (latitude, longitude)
51
+ # @param [GeoPoint] point: Destination point (latitude, longitude)
52
+ # @return [Array] Midpoint between this point and the supplied point
53
+ #
54
+ def self.midpoint_to base_point, point
55
+ GeoPoint.new GeoCalc::Midpoint.midpoint_to(base_point, point).to_coords
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,15 @@
1
+ require '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,16 @@
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
12
+
13
+ [Array, Hash, String].each do |cls|
14
+ cls.send :include, GeoPoint::CoreExtension
15
+ end
16
+
@@ -0,0 +1,37 @@
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
+ def is_numeric? arg
20
+ arg.is_a? Numeric
21
+ end
22
+
23
+ alias_method :is_num?, :is_numeric?
24
+
25
+ def check_numeric! arg
26
+ raise ArgumentError, "Argument must be Numeric" if !is_numeric? arg
27
+ end
28
+
29
+ def valid_earth_radius? radius_km
30
+ is_numeric?(radius_km) && radius_km.is_between?(6350, 6380)
31
+ end
32
+
33
+ def valid_mode? mode
34
+ [:lng_lat, :lat_lng].include? mode
35
+ end
36
+ end
37
+ end
data/lib/geo_point.rb ADDED
@@ -0,0 +1,142 @@
1
+ require 'sugar-high/arguments'
2
+ require 'geo_calc'
3
+ # Sample usage:
4
+ # p1 = GeoPoint.new(51.5136, -0.0983)
5
+ # p2 = GeoPoint.new(51.4778, -0.0015)
6
+ # dist = p1.distance_to(p2) # in km
7
+ # brng = p1.bearing_to(p2) # in degrees clockwise from north
8
+ # ... etc
9
+ # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10
+
11
+ class GeoPoint
12
+ autoload :Calc, 'geo_point/calc'
13
+ autoload :Shared, 'geo_point/shared'
14
+ autoload :ClassMethods, 'geo_point/class_methods'
15
+ autoload :CoreExtension, 'geo_point/core_extension'
16
+
17
+ include GeoPoint::Calc
18
+ include GeoCalc::PrettyPrint
19
+
20
+ attr_reader :lat, :lon
21
+
22
+ # Creates a point on the earth's surface at the supplied latitude / longitude
23
+ #
24
+ # - Numeric latitude in numeric degrees
25
+ # - Numeric longitude in numeric degrees
26
+
27
+ # Optional options
28
+ # - :radius - earth radius in km
29
+ # - :mode - coordinates mode, either :lng_lat or :lat_lng, otherwise uses global setting as per GeoPoint.coord_mode
30
+ def initialize *args
31
+ options = args.is_a?(GeoPoint) ? {} : args.last_option
32
+ earth_radius_km = options[:radius]
33
+ coord_mode = options[:mode]
34
+
35
+ case args.size
36
+ when 1
37
+ create_from_one args
38
+ when 2
39
+ create_from_two *args
40
+ else
41
+ raise "GeoPoint must be initialized with either one or to arguments defining the (latitude, longitude) coordinate on the map"
42
+ end
43
+ end
44
+
45
+ extend ClassMethods
46
+ include Shared
47
+
48
+ def coord_mode
49
+ @coord_mode ||= GeoPoint.coord_mode
50
+ end
51
+
52
+ def earth_radius_km
53
+ @earth_radius_km ||= GeoPoint.earth_radius_km # default
54
+ end
55
+
56
+ def lat= value
57
+ @lat = value.to_lat
58
+ end
59
+
60
+ def lon= value
61
+ @lon = value.to_lng
62
+ end
63
+
64
+ (Symbol.lng_symbols - [:lon]).each do |sym|
65
+ class_eval %{
66
+ alias_method :#{sym}, :lon
67
+ alias_method :#{sym}=, :lon=
68
+ }
69
+ end
70
+ alias_method :to_lng, :lng
71
+
72
+ (Symbol.lat_symbols - [:lat]).each do |sym|
73
+ class_eval %{
74
+ alias_method :#{sym}, :lat
75
+ alias_method :#{sym}=, :lat=
76
+ }
77
+ end
78
+ alias_method :to_lat, :lat
79
+
80
+ def [] key
81
+ case key
82
+ when Fixnum
83
+ raise ArgumentError, "Index must be 0 or 1" if !(0..1).cover?(key)
84
+ to_a[key]
85
+ when String, Symbol
86
+ send(key) if respond_to? key
87
+ else
88
+ raise ArgumentError, "Key must be a Fixnum (index) or a method name"
89
+ end
90
+ end
91
+
92
+ alias_method :to_dms, :to_s
93
+
94
+ def reverse_point!
95
+ self.lat = lat * -1
96
+ self.lng = lng * -1
97
+ self
98
+ end
99
+
100
+ def reverse_point
101
+ self.dup.reverse_point!
102
+ end
103
+
104
+ def to_lat_lng
105
+ [lat, lng]
106
+ end
107
+
108
+ def to_lng_lat
109
+ [lng, lat]
110
+ end
111
+
112
+ def to_a
113
+ send(:"to_#{coord_mode}")
114
+ end
115
+
116
+ protected
117
+
118
+ def is_numeric? arg
119
+ arg.is_a? Numeric
120
+ end
121
+
122
+ alias_method :is_num?, :is_numeric?
123
+
124
+ def check_numeric! arg
125
+ raise ArgumentError, "Argument must be Numeric" if !is_numeric? arg
126
+ end
127
+
128
+ def to_coords points
129
+ points.send(:"to_#{coord_mode}")
130
+ end
131
+
132
+ def create_from_one args
133
+ args = args.first
134
+ create_from_two *to_coords(args)
135
+ end
136
+
137
+ def create_from_two lat, lon
138
+ @lat = lat.to_lat
139
+ @lon = lon.to_lng
140
+ end
141
+ end
142
+
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ # - www.movable-type.co.uk/scripts/latlong.html
4
+ describe GeoPoint do
5
+ describe 'Class methods' do
6
+ describe '#coord_mode' do
7
+ it 'should change global coordinates mode' do
8
+ GeoPoint.coord_mode = :lng_lat
9
+ GeoPoint.coord_mode.should == :lng_lat
10
+
11
+ GeoPoint.coord_mode = :lat_lng
12
+ GeoPoint.coord_mode.should == :lat_lng
13
+ end
14
+
15
+ it 'shoould not allow setting invalid coord mode' do
16
+ lambda { GeoPoint.coord_mode = :blip }.should raise_error
17
+ end
18
+ end
19
+
20
+ describe '#earth_radius_km' do
21
+ it 'should change global earth_radius_km' do
22
+ GeoPoint.earth_radius_km = 6360
23
+ GeoPoint.earth_radius_km.should == 6360
24
+ end
25
+
26
+ it 'shoould not allow setting invalid earth radius' do
27
+ lambda { GeoPoint.earth_radius_km = 6100 }.should raise_error
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+
3
+ # - www.movable-type.co.uk/scripts/latlong.html
4
+ describe GeoPoint do
5
+ before do
6
+ GeoPoint.earth_radius_km = 6371
7
+ end
8
+
9
+ describe '#initializer' do
10
+ describe '1 argument' do
11
+ describe 'single String' do
12
+ describe '50.1, 5.0 ' do
13
+ it 'should create a GeoPoint' do
14
+ p1 = GeoPoint.new "50.1, 5.0"
15
+ p1.should be_a(GeoPoint)
16
+ p1.lat.should == 50.1
17
+ p1.lon.should == 5.0
18
+ p1.unit.should == :degrees
19
+ p1.earth_radius_km.should == 6371
20
+ end
21
+ end
22
+
23
+ describe '(50.1, 5.0)' do
24
+ it 'should create a GeoPoint' do
25
+ p1 = GeoPoint.new "(50.1, 5.2)"
26
+ p1.should be_a(GeoPoint)
27
+ p1.lat.should == 50.1
28
+ p1.lon.should == 5.2
29
+ p1.unit.should == :degrees
30
+ p1.earth_radius_km.should == 6371
31
+ end
32
+ end
33
+
34
+ describe '58 38 38N, 003 04 12W' do
35
+ it 'should create a GeoPoint' do
36
+ p1 = GeoPoint.new "58 38 38N, 003 04 12W"
37
+ p1.should be_a(GeoPoint)
38
+ p1.lat.should be_within(0.5).of(58.38)
39
+ p1.lon.should be_within(0.5).of(-3)
40
+ p1.unit.should == :degrees
41
+ p1.earth_radius_km.should == 6371
42
+ end
43
+ end
44
+
45
+ describe '(58 38 38N, 003 04 12W)' do
46
+ it 'should create a GeoPoint' do
47
+ p1 = GeoPoint.new "(58 38 38N, 003 04 12W)"
48
+ p1.should be_a(GeoPoint)
49
+ p1.lat.should be_within(0.5).of(58.38)
50
+ p1.lon.should be_within(0.5).of(-3) # W is negative, then normalize
51
+ p1.unit.should == :degrees
52
+ p1.earth_radius_km.should == 6371
53
+ end
54
+ end
55
+ end
56
+
57
+ describe 'single Array' do
58
+ describe '2 Fixed numbers: 50,5 ' do
59
+ it 'should create a GeoPoint' do
60
+ p1 = GeoPoint.new [50, 5]
61
+ p1.should be_a(GeoPoint)
62
+ p1.lat.should == 50
63
+ p1.lon.should == 5
64
+ p1.unit.should == :degrees
65
+ p1.earth_radius_km.should == 6371
66
+ end
67
+ end
68
+
69
+ describe '2 Float numbers: 50.1, 5.0 ' do
70
+ it 'should create a GeoPoint' do
71
+ p1 = GeoPoint.new [50.1, 5.0]
72
+ p1.should be_a(GeoPoint)
73
+ p1.lat.should == 50.1
74
+ p1.lon.should == 5.0
75
+ p1.unit.should == :degrees
76
+ p1.earth_radius_km.should == 6371
77
+ end
78
+ end
79
+
80
+ describe 'single Hash' do
81
+ describe 'with: {:lat => 50.1, :lng => 5.1}' do
82
+ it 'should create a GeoPoint' do
83
+ p1 = GeoPoint.new :lat => 50.1, :lng => 5.1
84
+ p1.should be_a(GeoPoint)
85
+ p1.lat.should == 50.1
86
+ p1.lon.should == 5.1
87
+ p1.unit.should == :degrees
88
+ p1.earth_radius_km.should == 6371
89
+ end
90
+ end
91
+
92
+ describe 'with: {:lat => 50.1, :long => 5.1}' do
93
+ it 'should create a GeoPoint' do
94
+ p1 = GeoPoint.new :lat => 50.1, :long => 5.1
95
+ p1.should be_a(GeoPoint)
96
+ p1.lat.should == 50.1
97
+ p1.lon.should == 5.1
98
+ p1.unit.should == :degrees
99
+ p1.earth_radius_km.should == 6371
100
+ end
101
+ end
102
+
103
+ describe 'with: {:latitude => 50.1, :longitude => 5.1}' do
104
+ it 'should create a GeoPoint' do
105
+ p1 = GeoPoint.new :latitude => 50.1, :longitude => 5.1
106
+ p1.should be_a(GeoPoint)
107
+ p1.lat.should == 50.1
108
+ p1.lon.should == 5.1
109
+ p1.unit.should == :degrees
110
+ p1.earth_radius_km.should == 6371
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ describe 'with 2 arguments' do
118
+ describe '2 Fixed numbers (Fixnum)' do
119
+ it 'should create a GeoPoint' do
120
+ p1 = GeoPoint.new 50, 5
121
+ p1.should be_a(GeoPoint)
122
+ p1.lat.should == 50
123
+ p1.lon.should == 5
124
+ p1.unit.should == :degrees
125
+ p1.earth_radius_km.should == 6371
126
+ end
127
+ end
128
+
129
+ describe '2 Float numbers' do
130
+ it 'should create a GeoPoint' do
131
+ p1 = GeoPoint.new 50.1, 5.0
132
+ p1.should be_a(GeoPoint)
133
+ p1.lat.should == 50.1
134
+ p1.lon.should == 5.0
135
+ p1.unit.should == :degrees
136
+ p1.earth_radius_km.should == 6371
137
+ end
138
+ end
139
+
140
+ describe '2 Strings: "58 38 38N", "003 04 12W"' do
141
+ it 'should create a GeoPoint' do
142
+ p1 = GeoPoint.new "58 38 38N", "003 04 12W"
143
+ p1.should be_a(GeoPoint)
144
+ p1.lat.should be_within(0.5).of(58.38)
145
+ p1.lon.should be_within(0.5).of(-3)
146
+ p1.unit.should == :degrees
147
+ p1.earth_radius_km.should == 6371
148
+ end
149
+ end
150
+ end
151
+ end # initializer
152
+ end
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ # - www.movable-type.co.uk/scripts/latlong.html
4
+ describe GeoPoint do
5
+ describe '#lat' do
6
+ before :each do
7
+ @p1 = GeoPoint.new 50, 5
8
+ end
9
+
10
+ it 'should return latitude' do
11
+ @p1.lat.should == 50
12
+ end
13
+
14
+ describe '#latitude (alias)' do
15
+ it 'should return latitude' do
16
+ @p1.latitude.should == 50
17
+ end
18
+ end
19
+
20
+ describe '#to_lat (alias)' do
21
+ it 'should return latitude' do
22
+ @p1.to_lat.should == 50
23
+ end
24
+ end
25
+ end
26
+
27
+ describe '#lat=' do
28
+ before :each do
29
+ @p1 = GeoPoint.new 50, 5
30
+ end
31
+
32
+ it 'should set new latitude' do
33
+ @p1.lat = 60
34
+ @p1.lat.should == 60
35
+ end
36
+
37
+ it 'should set new latitude -2' do
38
+ @p1.lat = -2
39
+ @p1.lat.should == -2
40
+ end
41
+
42
+ it 'should convert latitude -182 to -2' do
43
+ @p1.lat = -2
44
+ @p1.lat.should == -2
45
+ end
46
+
47
+
48
+ it 'should set new latitude within allowed range' do
49
+ @p1.lat = 520
50
+ @p1.lat.should be_between(0, 360)
51
+ end
52
+
53
+ describe '#latitude (alias)' do
54
+ it 'should set latitude' do
55
+ @p1.lat = 72
56
+ @p1.latitude.should == 72
57
+ end
58
+ end
59
+ end
60
+
61
+ describe '#lon' do
62
+ before :each do
63
+ @p1 = GeoPoint.new 5, 50
64
+ end
65
+
66
+ it 'should return longitude' do
67
+ @p1.lon.should == 50
68
+ end
69
+
70
+ it 'should return longitude (via lng)' do
71
+ @p1.lng.should == 50
72
+ end
73
+
74
+ describe '#longitude (alias)' do
75
+ it 'should return longitude' do
76
+ @p1.longitude.should == 50
77
+ end
78
+ end
79
+
80
+ describe '#to_lng (alias)' do
81
+ it 'should return latitude' do
82
+ @p1.to_lng.should == 50
83
+ end
84
+ end
85
+ end
86
+
87
+ describe '#lon=' do
88
+ before :each do
89
+ @p1 = GeoPoint.new 5, 50
90
+ end
91
+
92
+ it 'should set new longitude' do
93
+ @p1.lat.should == 5
94
+ @p1.lon = 60
95
+ @p1.lon.should == 60
96
+ end
97
+
98
+ it 'should return longitude (via lng)' do
99
+ @p1.lng = 70
100
+ @p1.lng.should == 70
101
+ end
102
+
103
+ it 'should set new latitude within allowed range' do
104
+ @p1.lon = 520
105
+ @p1.longitude.should be_between(-180, 180)
106
+ end
107
+
108
+ describe '#latitude (alias)' do
109
+ it 'should set latitude' do
110
+ @p1.longitude = 72
111
+ @p1.longitude.should == 72
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ # - www.movable-type.co.uk/scripts/latlong.html
4
+ describe GeoPoint do
5
+ describe '#reverse_point' do
6
+ before :each do
7
+ @p = GeoPoint.new -2, 5
8
+ end
9
+
10
+ it 'should return reverse GeoPoint (2, -5)' do
11
+ @p2 = @p.reverse_point
12
+ @p2.should_not == @p
13
+ @p2.lat.should == 2
14
+ @p2.lng.should == -5
15
+ end
16
+ end
17
+
18
+ describe '#reverse_point!' do
19
+ before :each do
20
+ @p = GeoPoint.new -2, 5
21
+ end
22
+
23
+ it 'should return reverse GeoPoint (2, -5)' do
24
+ @p.reverse_point!
25
+ @p.lat.should == 2
26
+ @p.lng.should == -5
27
+ end
28
+ end
29
+
30
+ describe '#to_s' do
31
+ before :each do
32
+ @p1 = GeoPoint.new 50.1, 5
33
+ end
34
+
35
+ it 'should return GeoPoint as a dms formatted String' do
36
+ @p1.to_s.should match /50.+5/
37
+ end
38
+
39
+ it 'should return GeoPoint as a dms formatted String' do
40
+ @p1.to_s(:dm, 2).should match /50.+5/
41
+ end
42
+ end
43
+
44
+ describe '#[]' do
45
+ before :each do
46
+ @p1 = GeoPoint.new 50, 5
47
+ end
48
+
49
+ it 'index of 0 should return latitude' do
50
+ @p1[0].should == 50
51
+ end
52
+
53
+ it 'index of 1 should return longitude' do
54
+ @p1[1].should == 5
55
+ end
56
+
57
+ it 'index of 2 should raise error' do
58
+ lambda {@p1[2]}.should raise_error
59
+ end
60
+
61
+ it ':lat should return latitude' do
62
+ @p1[:lat].should == 50
63
+ end
64
+
65
+ it ':long should return longitude' do
66
+ @p1[:long].should == 5
67
+ end
68
+ end
69
+
70
+ describe '#to_a' do
71
+ before :each do
72
+ @p1 = GeoPoint.new 50, 5
73
+ end
74
+
75
+ it 'should return GeoPoint as an array depending on state of reverse_arr' do
76
+ @p1.to_a.should == [50, 5]
77
+ end
78
+ end
79
+
80
+ describe '#to_lat_lng' do
81
+ before :each do
82
+ @p1 = GeoPoint.new 50, 5
83
+ end
84
+
85
+ it 'should return GeoPoint as an array of [lat, lng]' do
86
+ @p1.to_lat_lng.should == [50, 5]
87
+ end
88
+ end
89
+
90
+ describe '#to_lng_lat' do
91
+ before :each do
92
+ @p1 = GeoPoint.new 50, 5
93
+ end
94
+
95
+ it 'should return GeoPoint as an array of [lng, lat]' do
96
+ @p1.to_lng_lat.should == [5, 50]
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,6 @@
1
+ require 'rspec'
2
+ require 'geo_point'
3
+
4
+ RSpec.configure do |config|
5
+
6
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geo_point
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kristian Mandrup
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-06-13 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: geo_calc
16
+ requirement: &2161453140 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.7.3
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2161453140
25
+ - !ruby/object:Gem::Dependency
26
+ name: geo_units
27
+ requirement: &2161452560 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 0.2.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2161452560
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &2161451960 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 2.6.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2161451960
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: &2161451360 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.0.6
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2161451360
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &2161450760 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 1.6.2
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2161450760
69
+ - !ruby/object:Gem::Dependency
70
+ name: rcov
71
+ requirement: &2161450160 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2161450160
80
+ description: Allows for easy parsing of Strings, Hashes and Arrays into a GeoPoint
81
+ with lat/long
82
+ email: kmandrup@gmail.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files:
86
+ - LICENSE.txt
87
+ - README.textile
88
+ files:
89
+ - .document
90
+ - .rspec
91
+ - Gemfile
92
+ - LICENSE.txt
93
+ - README.textile
94
+ - Rakefile
95
+ - VERSION
96
+ - geo_point.gemspec
97
+ - lib/geo_point.rb
98
+ - lib/geo_point/calc.rb
99
+ - lib/geo_point/class_methods.rb
100
+ - lib/geo_point/core_extension.rb
101
+ - lib/geo_point/shared.rb
102
+ - spec/geo_point/class_methods_spec.rb
103
+ - spec/geo_point/initializer_spec.rb
104
+ - spec/geo_point/lat_lon.rb
105
+ - spec/geo_point_spec.rb
106
+ - spec/spec_helper.rb
107
+ homepage: http://github.com/kristianmandrup/geo_point
108
+ licenses:
109
+ - MIT
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ segments:
121
+ - 0
122
+ hash: 373389270659259712
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ none: false
125
+ requirements:
126
+ - - ! '>='
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 1.8.5
132
+ signing_key:
133
+ specification_version: 3
134
+ summary: A GeoPoint encapsulates latitude, longitude and various geo calculations
135
+ relative to itself
136
+ test_files: []