geodesy 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5895d5c7c414ff0ead805f95cafa9bd69580c9cc
4
+ data.tar.gz: de52ebeb588d32fe325d6fe2597796ae8843e87e
5
+ SHA512:
6
+ metadata.gz: 6ccd58b4bf1bfae19720d938e49ab57337686b4881e0793f8b4978802c8ac4a8116e6f2b33d5704147ffb34a6b5d89837944d27e29264c8beefcb779d7400116
7
+ data.tar.gz: ab3c1e4bccdfb2f6e911ac94b790ba65ddf00aeab7fd570df0251bfd6b11bf86eaf6cb3af90123d4947762033959ea147468b7b5feeab6d2309a1abf8a221add
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ ruby '2.2.0'
3
+
4
+ # Specify your gem's dependencies in geodesy.gemspec
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Robert Evans
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # Geodesy
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/**/**/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => 'test'
data/geodesy.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'geodesy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "geodesy"
8
+ spec.version = Geodesy::VERSION
9
+ spec.authors = ["Robert Evans"]
10
+ spec.email = ["robert@codewranglers.org"]
11
+ spec.summary = %q{Some simple Geo-Calculations}
12
+ spec.description = %q{Simple Geo-Calculations}
13
+ spec.homepage = "http://www.codewranglers.org"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "minitest"
24
+ end
@@ -0,0 +1,32 @@
1
+
2
+ module Geodesy
3
+ class Bearing
4
+ using FloatExtension
5
+
6
+ attr_reader :starting_point, :ending_point
7
+
8
+ #
9
+ # start_point is a Geodesy::Coordinates
10
+ # end_point is a Geodesy::Coordinates
11
+ #
12
+ def initialize(start_point, end_point)
13
+ @starting_point = start_point
14
+ @ending_point = end_point
15
+ end
16
+
17
+ def calculate
18
+ start_lat_in_radians = starting_point.lat.to_radians
19
+ end_lat_in_radians = ending_point.lat.to_radians
20
+ delta = (ending_point.lng.angle - starting_point.lng.angle).to_radians
21
+
22
+ # formula: http://mathforum.org/library/drmath/view/55417.html
23
+ y = Math.sin(delta) * Math.cos(end_lat_in_radians)
24
+ x = ( Math.cos(start_lat_in_radians) * Math.sin(end_lat_in_radians) ) -
25
+ ( Math.sin(start_lat_in_radians) * Math.cos(end_lat_in_radians) * Math.cos(delta) )
26
+ z = Math.atan2(y, x)
27
+
28
+ ( z.to_degrees + 360 ) % 360
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,42 @@
1
+
2
+ module Geodesy
3
+ COMPASS_POINTS = %w[N NE E SE S SW W NW]
4
+ EARTH_RADIUS = 6371.0
5
+ KM_TO_MI = 0.621371192
6
+ DEGREES_PER_RADIAN = 57.2957795
7
+ YARDS_PER_METER = 1.09361
8
+ METERS_TO_YARDS = 0.9144
9
+
10
+ module Conversions
11
+ extend self
12
+
13
+ def kilometers_to_miles
14
+ KM_TO_MI
15
+ end
16
+
17
+ def miles_to_kilometers
18
+ 1.0 / KM_TO_MI
19
+ end
20
+
21
+ def meters_to_yards
22
+ METERS_TO_YARDS
23
+ end
24
+
25
+ def yards_to_meters
26
+ YARDS_PER_METER
27
+ end
28
+
29
+ def feet_to_yards
30
+ 3
31
+ end
32
+
33
+ def yards_to_feet
34
+ 3
35
+ end
36
+
37
+ def feet_to_inches
38
+ 12
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'latitude'
2
+ require_relative 'longitude'
3
+
4
+ module Geodesy
5
+ class Coordinates
6
+ attr_reader :lat, :lng, :altitude, :radius
7
+
8
+ def initialize(lat, lng, altitude = nil)
9
+ @lat = Geodesy::Latitude.new(lat)
10
+ @lng = Geodesy::Longitude.new(lng)
11
+ @altitude = altitude
12
+ @radius = Geodesy::EARTH_RADIUS # in kilometers
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+
2
+ module FloatExtension
3
+ refine Float do
4
+
5
+ # Assumes degrees to radians
6
+ def to_radians
7
+ self * Math::PI / 180
8
+ end
9
+
10
+ # assumes radians to degrees
11
+ def to_degrees
12
+ self * 180 / Math::PI
13
+ end
14
+
15
+ def to_kilometers(miles)
16
+ miles * Geodesy::Conversions.miles_to_kilometers
17
+ end
18
+
19
+ def to_miles(kilometers)
20
+ kilometers * Geodesy::Conversions.kilometers_to_miles
21
+ end
22
+
23
+ def to_meters(yards)
24
+ yards * Geodesy::Conversions.yards_to_meters
25
+ end
26
+
27
+ def to_yards(meters)
28
+ meters * Geodesy::Conversions.meters_to_yards
29
+ end
30
+
31
+ def to_feet(yards)
32
+ yards * Geodesy::Conversions.yards_to_feet
33
+ end
34
+
35
+ def to_inches(feet)
36
+ feet * Geodesy::Conversions.feet_to_inches
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,44 @@
1
+ #
2
+ # Will return a coordinate based on a starting point, the bearing,
3
+ # and the distance.
4
+ #
5
+ module Geodesy
6
+ class Destination
7
+ using FloatExtension
8
+
9
+ attr_reader :starting_point, :distance, :bearing, :radius
10
+
11
+ #
12
+ # StartingPoint is a Coordinate Object
13
+ # Bearing is a Float Object
14
+ # Distance is an Integer or Float Object - default units: meters
15
+ #
16
+ def initialize(starting_point, bearing, distance)
17
+ @starting_point = starting_point
18
+ @radius = Geodesy::EARTH_RADIUS
19
+ @bearing = bearing
20
+ @distance = distance
21
+ end
22
+
23
+ def calculate
24
+ angular_distance = distance / radius
25
+ bearing_to_radians = bearing.to_radians
26
+ lat_radians = starting_point.lat.to_radians
27
+ lng_radians = starting_point.lng.to_radians
28
+
29
+ x = Math.asin(
30
+ ( Math.sin(lat_radians) * Math.cos(angular_distance) ) +
31
+ ( Math.cos(lat_radians) * Math.sin(angular_distance) * Math.cos(bearing_to_radians) )
32
+ )
33
+ y = lng_radians + Math.atan2(
34
+ Math.sin(bearing_to_radians) * Math.sin(angular_distance) * Math.cos(lat_radians),
35
+ Math.cos(angular_distance) - Math.sin(lat_radians) * Math.sin(x)
36
+ )
37
+ # normalize y to -180°..+180°
38
+ z = ( y + 3 * Math::PI ) % ( 2 * Math::PI ) - Math::PI
39
+
40
+ Coordinates.new( x.to_degrees, z.to_degrees )
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module Geodesy
3
+ class Latitude
4
+ using FloatExtension
5
+
6
+ attr_reader :angle
7
+
8
+ def initialize(lat)
9
+ @angle = lat
10
+ end
11
+
12
+ def to_radians
13
+ angle.to_radians
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module Geodesy
3
+ class Longitude
4
+ using FloatExtension
5
+
6
+ attr_reader :angle
7
+
8
+ def initialize(lng)
9
+ @angle = lng
10
+ end
11
+
12
+ def to_radians
13
+ angle.to_radians
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Geodesy
2
+ VERSION = "0.0.1"
3
+ end
data/lib/geodesy.rb ADDED
@@ -0,0 +1,45 @@
1
+ require "geodesy/version"
2
+ require 'geodesy/conversions'
3
+ require 'geodesy/core_ext/float_extension'
4
+ require 'geodesy/coordinates'
5
+ require 'geodesy/bearing'
6
+ require 'geodesy/destination'
7
+
8
+
9
+ module Geodesy
10
+ extend self
11
+
12
+ #
13
+ # starting is an array of [ lat, lng ]
14
+ # ending is an array of [ lat, lng ]
15
+ #
16
+ ### Returns
17
+ #
18
+ # It returns a floating point number
19
+ #
20
+ def bearing(starting, ending)
21
+ Bearing.new(
22
+ Coordinates.new(*starting),
23
+ Coordinates.new(*ending)
24
+ ).calculate
25
+ end
26
+
27
+
28
+ #
29
+ # starting is an array of [ lat, lng ]
30
+ # bearing is a float
31
+ # distance is an integer or float - units: meters
32
+ #
33
+ ### Returns
34
+ #
35
+ # It returns a Coordinates Object
36
+ #
37
+ def final_coordinate(starting, bearing, distance = 10)
38
+ Destination.new(
39
+ Coordinates.new(*starting),
40
+ bearing,
41
+ distance
42
+ ).calculate
43
+ end
44
+
45
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ module Geodesy
4
+ class BearingTest < Minitest::Test
5
+
6
+ def tee_point
7
+ @tee_point ||= Coordinates.new(33.27254375003685, -117.2873803284383)
8
+ end
9
+
10
+ def green_point
11
+ @green_point ||= Coordinates.new(33.269139395705295, -117.28715699010904)
12
+ end
13
+
14
+
15
+ def test_initialization
16
+ bearing = Bearing.new(tee_point, green_point)
17
+
18
+ assert_equal tee_point, bearing.starting_point
19
+ assert_equal green_point, bearing.ending_point
20
+ end
21
+
22
+
23
+ def test_calculation
24
+ bearing = Bearing.new(tee_point, green_point)
25
+
26
+ assert_equal 176.86038830369012, bearing.calculate
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,22 @@
1
+ require 'test_helper'
2
+
3
+ class CoordinatesTest < Minitest::Test
4
+ def lat
5
+ @lat ||= Geodesy::Latitude.new(33.26926373135873)
6
+ end
7
+
8
+ def lng
9
+ @lng ||= Geodesy::Longitude.new(-117.2871651469912)
10
+ end
11
+
12
+ def test_initialization
13
+ coord = Geodesy::Coordinates.new(33.26926373135873,
14
+ -117.2871651469912)
15
+
16
+ assert_equal lat.angle, coord.lat.angle
17
+ assert_equal lng.angle, coord.lng.angle
18
+ assert_nil coord.altitude
19
+ assert_equal Geodesy::EARTH_RADIUS, coord.radius
20
+ end
21
+
22
+ end
@@ -0,0 +1,34 @@
1
+ require 'test_helper'
2
+
3
+ module Geodesy
4
+ class DestinationTest < Minitest::Test
5
+
6
+ def starting_point
7
+ @starting_points ||= Coordinates.new(33.269139395705295,
8
+ -117.28715699010904)
9
+ end
10
+
11
+ def bearing
12
+ 176.86038830369012
13
+ end
14
+
15
+
16
+ def test_initialization
17
+ dest = Destination.new(starting_point, bearing, 20)
18
+
19
+ assert_equal starting_point, dest.starting_point
20
+ assert_equal bearing, dest.bearing
21
+ assert_equal 20, dest.distance
22
+ assert_equal 6371.0, dest.radius
23
+ end
24
+
25
+
26
+ def test_calculate
27
+ dest = Destination.new(starting_point, bearing, 20)
28
+
29
+ assert_equal 33.08954448933676, dest.calculate.lat.angle
30
+ assert_equal -117.27539907324454, dest.calculate.lng.angle
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class Point
4
+ using FloatExtension
5
+
6
+ attr_reader :lat, :lng
7
+
8
+ def initialize(point)
9
+ @lat, @lng = *point
10
+ end
11
+
12
+ def lat_to_radians
13
+ lat.to_radians
14
+ end
15
+
16
+ def lng_to_radians
17
+ lng.to_radians
18
+ end
19
+
20
+
21
+ def to_degrees(radians)
22
+ radians.to_degrees
23
+ end
24
+
25
+ end
26
+
27
+ class FloatExtensionTest < Minitest::Test
28
+ def point
29
+ @point ||= Point.new([33.26926373135873, -117.2871651469912])
30
+ end
31
+
32
+ def test_initialization
33
+ assert_equal 33.26926373135873, point.lat
34
+ assert_equal -117.2871651469912, point.lng
35
+ end
36
+
37
+
38
+ def test_radians
39
+ assert_equal 0.5806581918265441, point.lat_to_radians
40
+ assert_equal -2.0470472021453356, point.lng_to_radians
41
+ end
42
+
43
+
44
+ def test_degrees
45
+ assert_equal 33.269263731358734, point.to_degrees(point.lat_to_radians)
46
+ assert_equal point.lng, point.to_degrees(point.lng_to_radians).round(13)
47
+ end
48
+
49
+ end
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class GeodesyTest < Minitest::Test
4
+ def starting_point
5
+ [ 33.27254375003685,
6
+ -117.2873803284383 ]
7
+ end
8
+
9
+ def ending_point
10
+ [ 33.269139395705295,
11
+ -117.28715699010904]
12
+ end
13
+
14
+ def bearing
15
+ 176.86038830369012
16
+ end
17
+
18
+
19
+ def test_bearing
20
+ assert_equal bearing,
21
+ Geodesy.bearing(starting_point,
22
+ ending_point)
23
+ end
24
+
25
+
26
+ def test_final_coordinate
27
+ final_coord = Geodesy.final_coordinate(
28
+ ending_point,
29
+ bearing,
30
+ 20
31
+ )
32
+
33
+ assert_equal 33.08954448933676,
34
+ final_coord.lat.angle
35
+
36
+ assert_equal -117.27539907324454,
37
+ final_coord.lng.angle
38
+ end
39
+
40
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ class LatitudeTest < Minitest::Test
4
+
5
+ def lat
6
+ 33.26926373135873
7
+ end
8
+
9
+ def test_initialization
10
+ assert_equal lat, Geodesy::Latitude.new(lat).angle
11
+ end
12
+
13
+ def test_radians
14
+ assert_equal 0.5806581918265441,
15
+ Geodesy::Latitude.new(lat).to_radians
16
+ end
17
+
18
+ end
@@ -0,0 +1,19 @@
1
+ require 'test_helper'
2
+
3
+ class LongitudeTest < Minitest::Test
4
+
5
+ def lng
6
+ -117.2871651469912
7
+ end
8
+
9
+ def test_initialization
10
+ assert_equal lng,
11
+ Geodesy::Longitude.new(lng).angle
12
+ end
13
+
14
+ def test_radians
15
+ assert_equal -2.0470472021453356,
16
+ Geodesy::Longitude.new(lng).to_radians
17
+ end
18
+
19
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'geodesy'
3
+ require 'minitest/autorun'
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: geodesy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Robert Evans
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Simple Geo-Calculations
56
+ email:
57
+ - robert@codewranglers.org
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - geodesy.gemspec
68
+ - lib/geodesy.rb
69
+ - lib/geodesy/bearing.rb
70
+ - lib/geodesy/conversions.rb
71
+ - lib/geodesy/coordinates.rb
72
+ - lib/geodesy/core_ext/float_extension.rb
73
+ - lib/geodesy/destination.rb
74
+ - lib/geodesy/latitude.rb
75
+ - lib/geodesy/longitude.rb
76
+ - lib/geodesy/version.rb
77
+ - test/bearing_test.rb
78
+ - test/coordinates_test.rb
79
+ - test/destination_test.rb
80
+ - test/float_extension_test.rb
81
+ - test/geodesy_test.rb
82
+ - test/latitude_test.rb
83
+ - test/longitude_test.rb
84
+ - test/test_helper.rb
85
+ homepage: http://www.codewranglers.org
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.4.5
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: Some simple Geo-Calculations
109
+ test_files:
110
+ - test/bearing_test.rb
111
+ - test/coordinates_test.rb
112
+ - test/destination_test.rb
113
+ - test/float_extension_test.rb
114
+ - test/geodesy_test.rb
115
+ - test/latitude_test.rb
116
+ - test/longitude_test.rb
117
+ - test/test_helper.rb
118
+ has_rdoc: