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

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