Module: Measurable::Haversine
- Included in:
- Measurable
- Defined in:
- lib/measurable/haversine.rb
Instance Method Summary collapse
-
#haversine(u, v, unit = :meters) ⇒ Object
call-seq: haversine(u, v) -> Float.
Instance Method Details
#haversine(u, v, unit = :meters) ⇒ Object
call-seq:
haversine(u, v) -> Float
Compute accurate distances between two points given their latitudes and longitudes, even for short distances. This isn’t a distance measure in the same sense as the other methods in Measurable
.
The distance returned is the great circle (or orthodromic) distance between u
and v
, which is the shortest distance between them on the surface of a sphere. Thus, this implementation considers the Earth to be a sphere.
Reminding that the input vectors are of the form [latitude, longitude] in degrees, so if you have the coordinates [23 32’ S, 46 37’ W] (from São Paulo), the corresponding vector is [-23.53333, -46.61667].
References:
-
Arguments :
-
u
-> An array of Numeric objects. -
v
-> An array of Numeric objects. -
unit
-> (Optional) A Symbol representing the unit of measure. Availableoptions are +:miles+, +:feet+, +:km+ and +:meters+.
-
-
Returns :
-
The great circle distance between
u
andv
.
-
-
Raises :
-
ArgumentError
-> The size ofu
andv
must be 2. -
ArgumentError
->unit
must be a Symbol.
-
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/measurable/haversine.rb', line 51 def haversine(u, v, unit = :meters) # TODO: Create better exceptions. raise ArgumentError if u.size != 2 || v.size != 2 raise ArgumentError if unit.class != Symbol dlat = u[0] - v[0] dlon = u[1] - v[1] dlon_rad = dlon * RAD_PER_DEG dlat_rad = dlat * RAD_PER_DEG lat1_rad = v[0] * RAD_PER_DEG lon1_rad = v[1] * RAD_PER_DEG lat2_rad = u[0] * RAD_PER_DEG lon2_rad = u[1] * RAD_PER_DEG a = (Math.sin(dlat_rad / 2)) ** 2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * (Math.sin(dlon_rad / 2)) ** 2 c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) EARTH_RADIUS[unit] * c end |