Module: Measurable::Haversine
 Included in:
 Measurable
 Defined in:
 lib/measurable/haversine.rb
Instance Method Summary collapse

#haversine(u, v, unit = :meters) ⇒ Object
callseq: haversine(u, v) > Float.
Instance Method Details
#haversine(u, v, unit = :meters) ⇒ Object
callseq:
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.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 
# File 'lib/measurable/haversine.rb', line 50 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 