module DistanceCalculatorWithMath

Constants

LATITUDE_REGEXP
LONGITUDE_REGEXP
R
RAD_PER_DEG

Public Instance Methods

call(coords) click to toggle source
# File lib/distance_calculator_with_math.rb, line 9
def call(coords)
  coords.each_cons(2).map { |coord1, coord2| [distance(coord1, coord2).round(2)] }
end

Private Instance Methods

calculate_haversin(coord1, coord2) click to toggle source
# File lib/distance_calculator_with_math.rb, line 40
def calculate_haversin(coord1, coord2)
  lat1, lng1 = coord1
  lat2, lng2 = coord2

  h = haversin(lat2 - lat1) +
      Math.cos(lat1) * Math.cos(lat2) *
      haversin(lng2 - lng1)

  2 * R * Math.asin(Math.sqrt(h))
end
check_locations(locations = []) click to toggle source
# File lib/distance_calculator_with_math.rb, line 22
def check_locations(locations = [])
  locations.each { |l| validate_location(*l) }
end
convert_to_radians(arr) click to toggle source
# File lib/distance_calculator_with_math.rb, line 36
def convert_to_radians(arr)
  arr.map { |e| deg_to_rad(e.to_f) }
end
deg_to_rad(deg) click to toggle source
# File lib/distance_calculator_with_math.rb, line 32
def deg_to_rad(deg)
  deg * RAD_PER_DEG
end
distance(coord1, coord2) click to toggle source
# File lib/distance_calculator_with_math.rb, line 15
def distance(coord1, coord2)
  check_locations([coord1, coord2])
  coord1 = convert_to_radians(coord1)
  coord2 = convert_to_radians(coord2)
  calculate_haversin(coord1, coord2)
end
error_message(lat, lng) click to toggle source
# File lib/distance_calculator_with_math.rb, line 55
def error_message(lat, lng)
  "Latitude or Longitude is incorrect. Please, check parameters: [#{lat}, #{lng}]"
end
haversin(rad) click to toggle source
# File lib/distance_calculator_with_math.rb, line 51
def haversin(rad)
  Math.sin(rad / 2)**2
end
validate_location(lat, lng) click to toggle source
# File lib/distance_calculator_with_math.rb, line 26
def validate_location(lat, lng)
  return if lat =~ LATITUDE_REGEXP && lng =~ LONGITUDE_REGEXP

  raise ArgumentError, error_message(lat, lng)
end