lib/geo_rb/distance.rb in geo_rb-0.0.1 vs lib/geo_rb/distance.rb in geo_rb-0.0.2

- old
+ new

@@ -1,33 +1,50 @@ -require "geographiclib" +require "bigdecimal/util" +require "concurrent" +require "geodesic_wgs84" + module GeoRb class Distance EARTH_RADIUS = 6_371.0088 - attr_reader :kilometers + attr_reader :kilometers, :meters alias_method :km, :kilometers + alias_method :m, :meters + 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 + def initialize(*locations) - @kilometers = case locations.size - when 1 - Float(locations.first) if locations.size == 1 + 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 def ensure_same_altitude(a, b) raise LatitudeMismatch if (a.altitude - b.altitude).abs > 1e-6 end def measure(a, b) ensure_same_altitude(a, b) - r = GeographicLib::Geodesic::WGS84.inverse(a.latitude, a.longitude, b.latitude, b.longitude) - r[:s12] / 1_000 + r = Wgs84.new.distance(a.latitude, a.longitude, b.latitude, b.longitude).first + r.to_d end private def sanitize_location(location)