diff --git a/lib/google_maps_service/apis/directions.rb b/lib/google_maps_service/apis/directions.rb index 6ae9fa2..2425082 100644 --- a/lib/google_maps_service/apis/directions.rb +++ b/lib/google_maps_service/apis/directions.rb @@ -57,13 +57,19 @@ module Directions # `rail` is equivalent to `["train", "tram", "subway"]`. # @param [String] transit_routing_preference Specifies preferences for transit # requests. Valid values are `less_walking` or `fewer_transfers`. + # @param [String] traffic_model Specifies the assumptions to use when calculating time in traffic. + # This setting affects the value returned in the duration_in_traffic field in the response, + # which contains the predicted time in traffic based on historical averages. The traffic_model + # parameter may only be specified for driving directions where the request includes a + # `departure_time`, and only if the request includes an API key or a Google Maps APIs Premium + # Plan client ID. Valid values are `best_guess` (default), `pessimistic` or `optimistic`. # # @return [Array] Array of routes. def directions(origin, destination, mode: nil, waypoints: nil, alternatives: false, avoid: nil, language: nil, units: nil, region: nil, departure_time: nil, arrival_time: nil, optimize_waypoints: false, transit_mode: nil, - transit_routing_preference: nil) + transit_routing_preference: nil, traffic_model: nil) params = { origin: GoogleMapsService::Convert.waypoint(origin), @@ -94,6 +100,11 @@ def directions(origin, destination, params[:transit_mode] = GoogleMapsService::Convert.join_list("|", transit_mode) if transit_mode params[:transit_routing_preference] = transit_routing_preference if transit_routing_preference + params[:traffic_model] = GoogleMapsService::Validator.traffic_model(traffic_model) if traffic_model + + if traffic_model and not departure_time + raise ArgumentError, 'Must specify departure_time if specifying traffic_model' + end return get('/maps/api/directions/json', params)[:routes] end diff --git a/lib/google_maps_service/apis/distance_matrix.rb b/lib/google_maps_service/apis/distance_matrix.rb index 87f9bbb..c396586 100644 --- a/lib/google_maps_service/apis/distance_matrix.rb +++ b/lib/google_maps_service/apis/distance_matrix.rb @@ -52,13 +52,19 @@ module DistanceMatrix # `rail` is equivalent to `["train", "tram", "subway"]`. # @param [String] transit_routing_preference Specifies preferences for transit # requests. Valid values are `less_walking` or `fewer_transfers`. + # @param [String] traffic_model Specifies the assumptions to use when calculating time in traffic. + # This setting affects the value returned in the duration_in_traffic field in the response, + # which contains the predicted time in traffic based on historical averages. The traffic_model + # parameter may only be specified for driving directions where the request includes a + # `departure_time`, and only if the request includes an API key or a Google Maps APIs Premium + # Plan client ID. Valid values are `best_guess` (default), `pessimistic` or `optimistic`. # # @return [Hash] Matrix of distances. Results are returned in rows, each row # containing one origin paired with each destination. def distance_matrix(origins, destinations, mode: nil, language: nil, avoid: nil, units: nil, departure_time: nil, arrival_time: nil, transit_mode: nil, - transit_routing_preference: nil) + transit_routing_preference: nil, traffic_model: nil) params = { origins: GoogleMapsService::Convert.waypoints(origins), destinations: GoogleMapsService::Convert.waypoints(destinations) @@ -78,6 +84,11 @@ def distance_matrix(origins, destinations, params[:transit_mode] = GoogleMapsService::Convert.join_list('|', transit_mode) if transit_mode params[:transit_routing_preference] = transit_routing_preference if transit_routing_preference + params[:traffic_model] = GoogleMapsService::Validator.traffic_model(traffic_model) if traffic_model + + if traffic_model and not departure_time + raise ArgumentError, 'Must specify departure_time if specifying traffic_model' + end return get('/maps/api/distancematrix/json', params) end diff --git a/lib/google_maps_service/validator.rb b/lib/google_maps_service/validator.rb index 51c37fd..6231bf7 100644 --- a/lib/google_maps_service/validator.rb +++ b/lib/google_maps_service/validator.rb @@ -35,5 +35,19 @@ def avoid(avoid) end avoid end + + # Validate traffic model. The valid values of traffic are `best_guess`, `pessimistic` or `optimistic`. + # + # @param [String, Symbol] traffic_model Traffic model to be validated + # + # @raise ArgumentError The traffic model is invalid. + # + # @return [String] Valid traffic model + def traffic_model(traffic_model) + unless [:best_guess, :pessimistic, :optimistic].include?(traffic_model.to_sym) + raise ArgumentError, 'Invalid traffic model.' + end + traffic_model + end end end \ No newline at end of file diff --git a/spec/google_maps_service/apis/directions_spec.rb b/spec/google_maps_service/apis/directions_spec.rb index 7cebeb0..7a3091c 100644 --- a/spec/google_maps_service/apis/directions_spec.rb +++ b/spec/google_maps_service/apis/directions_spec.rb @@ -146,4 +146,18 @@ expect(a_request(:get, 'https://maps.googleapis.com/maps/api/directions/json?origin=Sydney+Town+Hall&destination=Parramatta+Town+Hall&alternatives=true&key=%s' % api_key)).to have_been_made end end + + context 'traffic_model parameter' do + it 'should call Google Maps Web Service' do + now = Time.now + client.directions('Sydney Town Hall', 'Parramatta Town Hall', traffic_model: 'pessimistic', departure_time: now) + expect(a_request(:get, 'https://maps.googleapis.com/maps/api/directions/json?origin=Sydney+Town+Hall&destination=Parramatta+Town+Hall&traffic_model=pessimistic&departure_time=%d&key=%s' % [now.to_i, api_key])).to have_been_made + end + + it 'should error if departure_time not provided' do + expect { + client.directions('Sydney Town Hall', 'Parramatta Town Hall', traffic_model: 'pessimistic') + }.to raise_error ArgumentError + end + end end \ No newline at end of file diff --git a/spec/google_maps_service/apis/distance_matrix_spec.rb b/spec/google_maps_service/apis/distance_matrix_spec.rb index ee15a80..7c01539 100644 --- a/spec/google_maps_service/apis/distance_matrix_spec.rb +++ b/spec/google_maps_service/apis/distance_matrix_spec.rb @@ -87,4 +87,22 @@ }.to raise_error ArgumentError end end + + context 'traffic_model parameter' do + it 'should call Google Maps Web Service' do + origins = ["Vancouver BC", "Seattle"] + destinations = ["San Francisco", "Victoria BC"] + now = Time.now + client.distance_matrix(origins, destinations, traffic_model: 'pessimistic', departure_time: now) + expect(a_request(:get, 'https://maps.googleapis.com/maps/api/distancematrix/json?origins=Vancouver+BC%%7CSeattle&destinations=San+Francisco%%7CVictoria+BC&traffic_model=pessimistic&departure_time=%d&key=%s' % [now.to_i, api_key])).to have_been_made + end + + it 'should error if departure_time not provided' do + expect { + origins = ["Vancouver BC", "Seattle"] + destinations = ["San Francisco", "Victoria BC"] + client.distance_matrix(origins, destinations, traffic_model: 'pessimistic') + }.to raise_error ArgumentError + end + end end \ No newline at end of file diff --git a/spec/google_maps_service/validator_spec.rb b/spec/google_maps_service/validator_spec.rb index 72aaa99..95cc775 100644 --- a/spec/google_maps_service/validator_spec.rb +++ b/spec/google_maps_service/validator_spec.rb @@ -33,10 +33,29 @@ end end - context 'with invalid travel mode' do + context 'with invalid route restriction' do it 'should raise ArgumentError' do expect { GoogleMapsService::Validator.avoid('people') }.to raise_error ArgumentError end end end + + describe '.traffic_model' do + context 'with valid traffic model' do + it 'should return the traffic model' do + [:best_guess, :pessimistic, :optimistic].each do |mode| + expect(GoogleMapsService::Validator.traffic_model(mode)).to eq(mode) + end + ['best_guess', 'pessimistic', 'optimistic'].each do |mode| + expect(GoogleMapsService::Validator.traffic_model(mode)).to eq(mode) + end + end + end + + context 'with invalid traffic model' do + it 'should raise ArgumentError' do + expect { GoogleMapsService::Validator.traffic_model('nonexistent') }.to raise_error ArgumentError + end + end + end end \ No newline at end of file