Module: Geodesic
- Defined in:
- lib/geodesic.rb
Overview
Geodesic is a Ruby library for calculating distance and bearing on the Earth’s surface. Positions are defined by longitude and latitude. The API uses Float values for all input and returned types. Distances are memasured in kilometers (km).
Defined Under Namespace
Classes: Position
Constant Summary collapse
- EARTH_RADIUS =
Earth’s radius in kilometers
6371.0
Class Method Summary collapse
-
.bearing(lat1, lon1, lat2, lon2) ⇒ Object
Calculate (initial) bearing in degrees between two positions.
-
.dest_position(lat1, lon1, brng, d) ⇒ Object
Calculate destination position given start position, initial bearing (degrees 0.0 to 360.0) and distance (kilometers).
-
.dist_cosine_law(lat1, lon1, lat2, lon2) ⇒ Object
Use Law of Cosines formula to calculate distance (in kilometers) between two positions specified by latitude/longitude in numeric degrees of type Float.
-
.dist_haversine(lat1, lon1, lat2, lon2) ⇒ Object
Use Haversine formula to Calculate distance (in kilometers) between two positions specified by latitude/longitude in numeric degrees of type Float.
Class Method Details
.bearing(lat1, lon1, lat2, lon2) ⇒ Object
Calculate (initial) bearing in degrees between two positions. Return range is 0.0 to 360.0. Latitudes and longitudes are of type Float.
see http://williams.best.vwh.net/avform.htm#Crs
89 90 91 92 93 94 95 96 97 98 |
# File 'lib/geodesic.rb', line 89 def Geodesic.bearing(lat1, lon1, lat2, lon2) lat1 = lat1.to_radians() lat2 = lat2.to_radians() dLon = (lon2-lon1).to_radians() y = Math::sin(dLon) * Math::cos(lat2) x = Math::cos(lat1)*Math::sin(lat2) - Math::sin(lat1)*Math::cos(lat2)*Math::cos(dLon) return Math::atan2(y, x).to_bearing() end |
.dest_position(lat1, lon1, brng, d) ⇒ Object
Calculate destination position given start position, initial bearing (degrees 0.0 to 360.0) and distance (kilometers). All values of type Float. Return a Position class or nil.
see http://williams.best.vwh.net/avform.htm#LL
104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/geodesic.rb', line 104 def Geodesic.dest_position(lat1, lon1, brng, d) lat1 = lat1.to_radians() lon1 = lon1.to_radians() brng = brng.to_radians() lat2 = Math::asin(Math::sin(lat1)*Math::cos(d/EARTH_RADIUS) + Math::cos(lat1)*Math::sin(d/EARTH_RADIUS)*Math::cos(brng) ) lon2 = lon1 + Math::atan2(Math::sin(brng)*Math::sin(d/EARTH_RADIUS)*Math::cos(lat1), Math::cos(d/EARTH_RADIUS)-Math::sin(lat1)*Math::sin(lat2)) lon2 = (lon2+Math::PI)%(2*Math::PI) - Math::PI # normalise to +/-radians return nil if lat2.nan? || lon2.nan? return Position.new(lat2.to_degrees(), lon2.to_degrees()) end |
.dist_cosine_law(lat1, lon1, lat2, lon2) ⇒ Object
Use Law of Cosines formula to calculate distance (in kilometers) between two positions specified by latitude/longitude in numeric degrees of type Float.
79 80 81 82 83 84 |
# File 'lib/geodesic.rb', line 79 def Geodesic.dist_cosine_law(lat1, lon1, lat2, lon2) d = Math::acos(Math::sin(lat1.to_radians())*Math::sin(lat2.to_radians()) + Math::cos(lat1.to_radians())*Math::cos(lat2.to_radians()) * Math::cos((lon2-lon1).to_radians())) * EARTH_RADIUS return d end |
.dist_haversine(lat1, lon1, lat2, lon2) ⇒ Object
Use Haversine formula to Calculate distance (in kilometers) between two positions specified by latitude/longitude in numeric degrees of type Float.
63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/geodesic.rb', line 63 def Geodesic.dist_haversine(lat1, lon1, lat2, lon2) dLat = (lat2-lat1).to_radians() dLon = (lon2-lon1).to_radians() lat1 = lat1.to_radians() lat2 = lat2.to_radians() a = Math::sin(dLat/2) * Math::sin(dLat/2) + Math::cos(lat1) * Math::cos(lat2) * Math::sin(dLon/2) * Math::sin(dLon/2) c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1-a)) d = EARTH_RADIUS * c return d end |