Class: DistanceFox::Calculations
- Inherits:
-
Object
- Object
- DistanceFox::Calculations
- Defined in:
- lib/distance_fox/calculations.rb
Constant Summary collapse
- EARTH_RADIUS =
6371.0
Class Method Summary collapse
-
.driving_distance(origin, destination) ⇒ Object
Origin and destination can be:.
-
.geocode(address) ⇒ Object
Address can be: a geocodable address (string).
-
.linear_distance(origin, destination) ⇒ Object
Origin and destination can be:.
-
.nearest_driving_distance(origin, destinations) ⇒ Object
Driving Distance to nearest location from multiple locations.
-
.nearest_linear_distance(origin, destinations) ⇒ Object
Linear Distance to nearest location from multiple locations Origin can be: * an array of float coordinates ([lat,lon]) * an array of string coordinates ([‘lat’,‘lon’]).
Class Method Details
.driving_distance(origin, destination) ⇒ Object
Origin and destination can be:
-
an array of coordinates ([lat,lon])
-
an array of coordinates ([‘lat’,‘lon’])
-
a geocodable address (string)
62 63 64 65 66 67 68 |
# File 'lib/distance_fox/calculations.rb', line 62 def self.driving_distance(origin, destination) origin = extract_coordinates(origin).join(',') destination = extract_coordinates(destination).join(',') google_distance_query = "https://maps.googleapis.com/maps/api/distancematrix/json?mode=driving&origins=#{origin}&destinations=#{destination}&key=#{DistanceFox.configuration.api_key}" google_distance_response = HTTParty.get(URI.escape(google_distance_query)) google_distance_response['rows'][0]['elements'][0]['distance']['value'].to_f / 1000 end |
.geocode(address) ⇒ Object
Address can be: a geocodable address (string)
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/distance_fox/calculations.rb', line 88 def self.geocode(address) google_distance_response = HTTParty.get(URI.escape(google_distance_query)) case google_distance_response["results"] when [] raise "Status: #{google_distance_response['status']}" else coordinates = google_distance_response['results'][0]['geometry']['location'] end [coordinates['lat'], coordinates['lng']] end |
.linear_distance(origin, destination) ⇒ Object
Origin and destination can be:
-
an array of coordinates ([lat,lon])
-
an array of coordinates ([‘lat’,‘lon’])
-
a geocodable address (string)
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/distance_fox/calculations.rb', line 12 def self.linear_distance(origin, destination) lat_origin, lon_origin = extract_coordinates origin lat_destination, lon_destination = extract_coordinates destination delta_lat = (lat_destination - lat_origin) * Math::PI / 180 delta_lon = (lon_destination - lon_origin) * Math::PI / 180 a = Math.sin(delta_lat / 2) * Math.sin(delta_lat / 2) + Math.cos(lat_origin * Math::PI / 180) * Math.cos(lat_destination * Math::PI / 180) * Math.sin(delta_lon / 2) * Math.sin(delta_lon / 2) c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) d = EARTH_RADIUS * c d.round(3) end |
.nearest_driving_distance(origin, destinations) ⇒ Object
Driving Distance to nearest location from multiple locations
Origin can be:
-
an array of coordinates ([lat,lon])
-
an array of coordinates ([‘lat’,‘lon’])
-
a geocodable address (string)
Destinations can be:
-
an array of hashes ([=> ‘City’, ‘coordinates’ => [‘lat’,‘lon’]])
80 81 82 83 84 |
# File 'lib/distance_fox/calculations.rb', line 80 def self.nearest_driving_distance(origin, destinations) origin = origin.join(',') destination = nearest_linear_distance(origin, destinations)['coordinates']['destination'].join(',') driving_distance(origin, destination) end |
.nearest_linear_distance(origin, destinations) ⇒ Object
Linear Distance to nearest location from multiple locations Origin can be:
-
an array of float coordinates ([lat,lon])
-
an array of string coordinates ([‘lat’,‘lon’])
Destinations can be:
-
an array of hashes ([=> ‘City’, ‘coordinates’ => [‘lat’,‘lon’]])
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/distance_fox/calculations.rb', line 39 def self.nearest_linear_distance(origin, destinations) origins_with_distance = [] origin_coordinates = extract_coordinates origin destinations.each do |destination| distance = linear_distance(origin_coordinates, destination['coordinates']) origins_with_distance.push( 'destination' => destination['city'], 'distance' => distance, 'coordinates' => { 'origin' => origin_coordinates, 'destination' => destination['coordinates'] } ) end origins_with_distance.min_by { |key| key['distance'] } end |