Class: Cartier::Navigation
- Inherits:
-
Object
- Object
- Cartier::Navigation
- Defined in:
- lib/cartier/navigation.rb
Overview
Encapsulating class for Navigation calculations
Constant Summary collapse
- EARTH_RADIUS =
radius in km
6371
- RADIANS =
57.29578
Class Method Summary collapse
-
.closest_point(location_here, array_of_locations = nil) ⇒ Object
-
Args : -
location_here
-> GPSLocation object representing current location -array_of_locations
-> an Array of GPSLocation objects * Returns : - GPSLocation object representing closest location.
-
-
.equirectangular_projection(location, destination) ⇒ Object
-
Args : -
location
-> GPSLocation object representing current location -longitude
-> GPSLocation object representing current destination * Returns : - distance in km.
-
-
.get_bearing(location, destination) ⇒ Object
-
Args : -
location
-> GPSLocation object representing current location -destination
-> GPSLocation object representing destination * Returns : - Bearing in Degrees (not radians).
-
-
.get_destination_point(location, bearing, distance) ⇒ Object
-
Args : -
location
-> Cartier::GPSLocation -bearing
-> Bearing in Degrees -distance
-> Distance in km * Returns : - Cartier::GPSLocation object representing final point.
-
-
.get_midpoint(location, destination) ⇒ Object
-
Args : -
location
-> GPSLocation object representing current location -destination
-> GPSLocation object representing destination * Returns : - Cartier::GPSLocation object representing midpoint.
-
-
.haversine_distance(location, destination) ⇒ Object
-
Args : -
location
-> GPSLocation object representing current location -longitude
-> GPSLocation object representing current destination * Returns : - distance in km.
-
Class Method Details
.closest_point(location_here, array_of_locations = nil) ⇒ Object
-
Args :
-
location_here
-> GPSLocation object representing current location -
array_of_locations
-> an Array of GPSLocation objects
-
-
Returns :
-
GPSLocation object representing closest location
-
55 56 57 58 59 |
# File 'lib/cartier/navigation.rb', line 55 def self.closest_point(location_here, array_of_locations=nil) array_of_locations.sort do |a, b| self.haversine_distance(location_here, a) <=> self.haversine_distance(location_here, b) end.first end |
.equirectangular_projection(location, destination) ⇒ Object
-
Args :
-
location
-> GPSLocation object representing current location -
longitude
-> GPSLocation object representing current destination
-
-
Returns :
-
distance in km
-
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/cartier/navigation.rb', line 35 def self.equirectangular_projection(location, destination) latitude_1 = (location.latitude.to_f) * Math::PI/180 latitude_2 = (destination.latitude.to_f) * Math::PI/180 longitude_1 = (location.longitude.to_f) * Math::PI/180 longitude_2 = (destination.longitude.to_f) * Math::PI/180 x = (longitude_2 - longitude_1) * Math.cos((latitude_1+latitude_2)/2) y = latitude_2 - latitude_1 Math.sqrt(x*x + y*y) * EARTH_RADIUS end |
.get_bearing(location, destination) ⇒ Object
-
Args :
-
location
-> GPSLocation object representing current location -
destination
-> GPSLocation object representing destination
-
-
Returns :
-
Bearing in Degrees (not radians)
-
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/cartier/navigation.rb', line 69 def self.get_bearing(location, destination) location_long = location.longitude.to_f * Math::PI/180 location_latitude = location.latitude.to_f * Math::PI/180 destination_long = destination.longitude.to_f destination_latitude = destination.latitude.to_f delta_long = (destination_long - location_long) * Math::PI/180 y = Math.sin(delta_long) * Math.cos(destination_latitude) x = Math.cos(location_latitude) * Math.sin(destination_latitude) - Math.sin(location_latitude) * Math.cos(destination_latitude) * Math.cos(delta_long) theta = (Math.atan2(y, x) / Math::PI) * 180 (theta + 360) % 360 end |
.get_destination_point(location, bearing, distance) ⇒ Object
-
Args :
-
location
-> Cartier::GPSLocation -
bearing
-> Bearing in Degrees -
distance
-> Distance in km
-
-
Returns :
-
Cartier::GPSLocation object representing final point
-
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/cartier/navigation.rb', line 119 def self.get_destination_point(location, bearing, distance) distance_in_radians = distance / EARTH_RADIUS bearing_in_radians = bearing * Math::PI/180 latitude_1 = location.latitude.to_f * Math::PI/180 longitude_1 = location.longitude.to_f * Math::PI/180 latitude_2 = Math.asin( Math.sin(latitude_1)*Math.cos(distance_in_radians) + Math.cos(latitude_1)*Math.sin(distance_in_radians)*Math.cos(bearing_in_radians) ) longitude_2 = longitude_1 + Math.atan2(Math.sin(bearing_in_radians)*Math.sin(distance_in_radians)*Math.cos(latitude_1), Math.cos(distance_in_radians)-Math.sin(latitude_1)*Math.sin(latitude_2)) longitude_2 = (longitude_2+3*Math::PI) % (2*Math::PI) - Math::PI latitude_2 = latitude_2 * RADIANS longitude_2 = longitude_2 * RADIANS Cartier::GPSLocation.new(latitude_2.to_s, longitude_2.to_s) end |
.get_midpoint(location, destination) ⇒ Object
-
Args :
-
location
-> GPSLocation object representing current location -
destination
-> GPSLocation object representing destination
-
-
Returns :
-
Cartier::GPSLocation object representing midpoint
-
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/cartier/navigation.rb', line 91 def self.get_midpoint(location, destination) latitude_1 = location.latitude.to_f * Math::PI/180 longitude_1 = location.longitude.to_f * Math::PI/180 latitude_2 = destination.latitude.to_f * Math::PI/180 delta_long = (destination.longitude.to_f - location.longitude.to_f) * Math::PI/180 bx = Math.cos(latitude_2) * Math.cos(delta_long) by = Math.cos(latitude_2) * Math.sin(delta_long) latitude_3 = Math.atan2(Math.sin(latitude_1) + Math.sin(latitude_2), Math.sqrt( (Math.cos(latitude_1)+bx)*(Math.cos(latitude_1)+bx) + by*by)) longitude_3 = longitude_1 + Math.atan2(by, Math.cos(latitude_1) + bx) longitude_3 = (longitude_3+3*Math::PI) % (2*Math::PI) - Math::PI latitude_3 = latitude_3 * RADIANS longitude_3 = longitude_3 * RADIANS Cartier::GPSLocation.new(latitude_3.to_s, longitude_3.to_s) end |
.haversine_distance(location, destination) ⇒ Object
-
Args :
-
location
-> GPSLocation object representing current location -
longitude
-> GPSLocation object representing current destination
-
-
Returns :
-
distance in km
-
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/cartier/navigation.rb', line 16 def self.haversine_distance(location, destination) delta_lat = (destination.latitude.to_f - location.latitude.to_f) * Math::PI/180 delta_long = (destination.longitude.to_f - location.longitude.to_f) * Math::PI/180 latitude_1 = (location.latitude.to_f) * Math::PI/180 latitude_2 = (destination.latitude.to_f) * Math::PI/180 a = Math.sin(delta_lat/2)**2 + Math.sin(delta_long/2)**2 * Math.cos(latitude_1) * Math.cos(latitude_2) c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) EARTH_RADIUS * c end |