class GeoRb::Distance

Constants

EARTH_RADIUS

Attributes

kilometers[R]
km[R]
m[R]
meters[R]

Public Class Methods

between(*addresses, adapter: GeoRb::GeoCoders::Nominatim) click to toggle source
# File lib/geo_rb/distance.rb, line 14
def self.between(*addresses, adapter: GeoRb::GeoCoders::Nominatim)
  return new if addresses.size == 1

  requests = addresses.map do |address|
    Concurrent::Promises.future(address) { |a| adapter.new.geocode(a) }
  end

  locations = Concurrent::Promises.zip(*requests).value!
  new(*locations)
end
new(*locations) click to toggle source
# File lib/geo_rb/distance.rb, line 25
def initialize(*locations)
  GeoRb.logger.debug locations
  @meters = case locations.size
  when 0..1
    0
  else
    locations.each_cons(2).reduce(0) do |distance, pair|
      a, b = sanitize_location(pair.first), sanitize_location(pair.last)
      distance + measure(a, b)
    end
  end
  @kilometers = @meters.to_d / 1_000
end

Public Instance Methods

ensure_same_altitude(a, b) click to toggle source
# File lib/geo_rb/distance.rb, line 39
def ensure_same_altitude(a, b)
  raise LatitudeMismatch if (a.altitude - b.altitude).abs > 1e-6
end
measure(a, b) click to toggle source
# File lib/geo_rb/distance.rb, line 43
def measure(a, b)
  ensure_same_altitude(a, b)
  r = Wgs84.new.distance(a.latitude, a.longitude, b.latitude, b.longitude).first
  r.to_d
end

Private Instance Methods

sanitize_location(location) click to toggle source
# File lib/geo_rb/distance.rb, line 51
def sanitize_location(location)
  case location
  when Location, Point
    location
  when Array
    case location.size
    when 2..3
      Point.new(*location.map(&:to_f))
    else
      raise CoordsError
    end
  when String
    points = location.split(",")
    raise CoordsError unless [2, 3].include?(points.size)

    Point.new(*points.map(&:to_f))
  else
    raise LocationError
  end
end