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)