googlemaps-services 1.2.0 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/googlemaps/services/client.rb +52 -55
- data/lib/googlemaps/services/directions.rb +22 -22
- data/lib/googlemaps/services/distancematrix.rb +17 -22
- data/lib/googlemaps/services/elevation.rb +10 -9
- data/lib/googlemaps/services/exceptions.rb +1 -1
- data/lib/googlemaps/services/geocoding.rb +15 -15
- data/lib/googlemaps/services/places.rb +41 -42
- data/lib/googlemaps/services/roads.rb +24 -24
- data/lib/googlemaps/services/timezone.rb +4 -4
- data/lib/googlemaps/services/util.rb +19 -18
- data/lib/googlemaps/services/version.rb +1 -1
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 18a00c19fa244488e45d19b1072506587f597e57
         | 
| 4 | 
            +
              data.tar.gz: 1d4bf5cef38c7d6be03bd438d2e30278eef31ee3
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 99aa38b29add2f487377ceef2a6cba9e9881defa8c2b6c3a0303a69bdbee8c2cfa4fd94414dda0d40fa2a4bd6b3f5a15b155dea9e66121862cd8d252a4aad270
         | 
| 7 | 
            +
              data.tar.gz: da2efaedd9b47501bc815b005ae47e7a2f97552fcfba47bf61c89b84d5c8e64309ad4b99426cf6b30eedf6fbfc38b77cf8190a6e90abc3fc20b70c1b7b59f781
         | 
| @@ -1,9 +1,9 @@ | |
| 1 | 
            -
            require  | 
| 2 | 
            -
            require  | 
| 3 | 
            -
            require  | 
| 4 | 
            -
            require  | 
| 5 | 
            -
            require  | 
| 6 | 
            -
            require  | 
| 1 | 
            +
            require 'googlemaps/services/exceptions'
         | 
| 2 | 
            +
            require 'googlemaps/services/version'
         | 
| 3 | 
            +
            require 'googlemaps/services/util'
         | 
| 4 | 
            +
            require 'nokogiri'
         | 
| 5 | 
            +
            require 'net/http'
         | 
| 6 | 
            +
            require 'json'
         | 
| 7 7 |  | 
| 8 8 | 
             
            # Core functionality, common across all API requests.
         | 
| 9 9 | 
             
            #
         | 
| @@ -13,9 +13,9 @@ module GoogleMaps | |
| 13 13 | 
             
              #
         | 
| 14 14 | 
             
              # @since 1.0.0
         | 
| 15 15 | 
             
              module Services
         | 
| 16 | 
            -
                 | 
| 17 | 
            -
                 | 
| 18 | 
            -
                 | 
| 16 | 
            +
                USER_AGENT = 'GoogleMapsRubyClient/' + VERSION
         | 
| 17 | 
            +
                DEFAULT_BASE_URL = 'https://maps.googleapis.com'
         | 
| 18 | 
            +
                RETRIABLE_STATUSES = [500, 503, 504]
         | 
| 19 19 |  | 
| 20 20 | 
             
                # Performs requests to the Google Maps API web services.
         | 
| 21 21 | 
             
                class GoogleClient
         | 
| @@ -43,30 +43,30 @@ module GoogleMaps | |
| 43 43 | 
             
                  attr_accessor :response_format
         | 
| 44 44 |  | 
| 45 45 | 
             
                  def initialize(key:, client_id: nil, client_secret: nil, timeout: nil,
         | 
| 46 | 
            -
                                 connect_timeout: nil, read_timeout: nil,retry_timeout: 60, request_opts:  | 
| 46 | 
            +
                                 connect_timeout: nil, read_timeout: nil,retry_timeout: 60, request_opts: {},
         | 
| 47 47 | 
             
                                 queries_per_second: 10, channel: nil, response_format: :json)
         | 
| 48 48 | 
             
                    if !key && !(client_secret && client_id)
         | 
| 49 | 
            -
                      raise StandardError,  | 
| 49 | 
            +
                      raise StandardError, 'Must provide API key or enterprise credentials when creationg client.'
         | 
| 50 50 | 
             
                    end
         | 
| 51 51 |  | 
| 52 | 
            -
                    if key && !key.start_with?( | 
| 53 | 
            -
                      raise StandardError,  | 
| 52 | 
            +
                    if key && !key.start_with?('AIza')
         | 
| 53 | 
            +
                      raise StandardError, 'Invalid API key provided.'
         | 
| 54 54 | 
             
                    end
         | 
| 55 55 |  | 
| 56 56 | 
             
                    if channel
         | 
| 57 | 
            -
                       | 
| 58 | 
            -
                        raise StandardError,  | 
| 57 | 
            +
                      unless client_id
         | 
| 58 | 
            +
                        raise StandardError, 'The channel argument must be used with a client ID.'
         | 
| 59 59 | 
             
                      end
         | 
| 60 60 |  | 
| 61 | 
            -
                       | 
| 62 | 
            -
                        raise StandardError,  | 
| 61 | 
            +
                      unless /^[a-zA-Z0-9._-]*$/.match(channel)
         | 
| 62 | 
            +
                        raise StandardError, 'The channel argument must be an ASCII alphanumeric string. The period (.), underscore (_) and hyphen (-) characters are allowed.'
         | 
| 63 63 | 
             
                      end
         | 
| 64 64 | 
             
                    end
         | 
| 65 65 |  | 
| 66 66 | 
             
                    self.key = key
         | 
| 67 67 |  | 
| 68 68 | 
             
                    if timeout && (connect_timeout || read_timeout)
         | 
| 69 | 
            -
                      raise StandardError,  | 
| 69 | 
            +
                      raise StandardError, 'Specify either timeout, or connect_timeout and read_timeout.'
         | 
| 70 70 | 
             
                    end
         | 
| 71 71 |  | 
| 72 72 | 
             
                    if connect_timeout && read_timeout
         | 
| @@ -79,18 +79,16 @@ module GoogleMaps | |
| 79 79 | 
             
                    self.client_secret = client_secret
         | 
| 80 80 | 
             
                    self.channel = channel
         | 
| 81 81 | 
             
                    self.retry_timeout = retry_timeout
         | 
| 82 | 
            -
                    self.request_opts = request_opts | 
| 83 | 
            -
             | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 86 | 
            -
             | 
| 87 | 
            -
                                                })
         | 
| 88 | 
            -
             | 
| 82 | 
            +
                    self.request_opts = request_opts.merge({
         | 
| 83 | 
            +
                                                               :headers => {'User-Agent' => USER_AGENT},
         | 
| 84 | 
            +
                                                               :timeout => self.timeout,
         | 
| 85 | 
            +
                                                               :verify => true
         | 
| 86 | 
            +
                                                           })
         | 
| 89 87 | 
             
                    self.queries_per_second = queries_per_second
         | 
| 90 88 | 
             
                    self.sent_times = Array.new
         | 
| 91 89 |  | 
| 92 90 | 
             
                    if response_format
         | 
| 93 | 
            -
                      raise StandardError,  | 
| 91 | 
            +
                      raise StandardError, 'Unsupported response format. Should be either :json or :xml.' unless [:json, :xml].include? response_format
         | 
| 94 92 | 
             
                      self.response_format = response_format
         | 
| 95 93 | 
             
                    end
         | 
| 96 94 | 
             
                  end
         | 
| @@ -108,9 +106,9 @@ module GoogleMaps | |
| 108 106 | 
             
                  # @param [Hash] request_opts Additional options for the Net::HTTP client.
         | 
| 109 107 | 
             
                  #
         | 
| 110 108 | 
             
                  # @return [Hash, Array] response body, either in JSON or XML.
         | 
| 111 | 
            -
                  def get(url:, params:, first_request_time: nil, retry_counter: nil, base_url:  | 
| 109 | 
            +
                  def get(url:, params:, first_request_time: nil, retry_counter: nil, base_url: DEFAULT_BASE_URL,
         | 
| 112 110 | 
             
                          accepts_clientid: true, extract_body: nil, request_opts: nil)
         | 
| 113 | 
            -
                     | 
| 111 | 
            +
                    unless first_request_time
         | 
| 114 112 | 
             
                      first_request_time = Util.current_time
         | 
| 115 113 | 
             
                    end
         | 
| 116 114 |  | 
| @@ -125,7 +123,7 @@ module GoogleMaps | |
| 125 123 | 
             
                      # at 1, so subtract that first.
         | 
| 126 124 | 
             
                      delay_seconds = 0.5 * 1.5 ** (retry_counter - 1)
         | 
| 127 125 | 
             
                      # Jitter this value by 50% and pause.
         | 
| 128 | 
            -
                      sleep(delay_seconds * (random.random | 
| 126 | 
            +
                      sleep(delay_seconds * (random.random + 0.5))
         | 
| 129 127 | 
             
                    end
         | 
| 130 128 |  | 
| 131 129 | 
             
                    authed_url = generate_auth_url(url, params, accepts_clientid)
         | 
| @@ -143,7 +141,7 @@ module GoogleMaps | |
| 143 141 | 
             
                    request_opts[:headers].each { |header,value| req.add_field(header, value) }
         | 
| 144 142 |  | 
| 145 143 | 
             
                    http = Net::HTTP.new(uri.host, uri.port)
         | 
| 146 | 
            -
                    http.use_ssl = (uri.scheme ==  | 
| 144 | 
            +
                    http.use_ssl = (uri.scheme == 'https')
         | 
| 147 145 | 
             
                    # Get HTTP response
         | 
| 148 146 | 
             
                    resp = http.request(req)
         | 
| 149 147 |  | 
| @@ -152,10 +150,10 @@ module GoogleMaps | |
| 152 150 | 
             
                    when Net::HTTPRequestTimeOut
         | 
| 153 151 | 
             
                      raise Timeout
         | 
| 154 152 | 
             
                    when Exception
         | 
| 155 | 
            -
                      raise TransportError,  | 
| 153 | 
            +
                      raise TransportError, 'HTTP GET request failed.'
         | 
| 156 154 | 
             
                    end
         | 
| 157 155 |  | 
| 158 | 
            -
                    if  | 
| 156 | 
            +
                    if RETRIABLE_STATUSES.include? resp.code.to_i
         | 
| 159 157 | 
             
                      # Retry request
         | 
| 160 158 | 
             
                      self.get(url, params, first_request_time, retry_counter + 1,
         | 
| 161 159 | 
             
                               base_url, accepts_clientid, extract_body)
         | 
| @@ -185,9 +183,8 @@ module GoogleMaps | |
| 185 183 | 
             
                      self.sent_times.push(Util.current_time)
         | 
| 186 184 | 
             
                      return result
         | 
| 187 185 | 
             
                    rescue RetriableRequest
         | 
| 188 | 
            -
                      #  | 
| 189 | 
            -
                      return self.get(url, params, first_request_time, retry_counter + 1,
         | 
| 190 | 
            -
                                      base_url, accepts_clientid, extract_body)
         | 
| 186 | 
            +
                      # Retry request
         | 
| 187 | 
            +
                      return self.get(url, params, first_request_time, retry_counter + 1, base_url, accepts_clientid, extract_body)
         | 
| 191 188 | 
             
                    end
         | 
| 192 189 | 
             
                  end
         | 
| 193 190 |  | 
| @@ -201,7 +198,7 @@ module GoogleMaps | |
| 201 198 | 
             
                  def get_json_body(resp)
         | 
| 202 199 | 
             
                    status_code = resp.code.to_i
         | 
| 203 200 | 
             
                    if status_code >= 300 && status_code < 400
         | 
| 204 | 
            -
                      return resp[ | 
| 201 | 
            +
                      return resp['location']
         | 
| 205 202 | 
             
                    end
         | 
| 206 203 |  | 
| 207 204 | 
             
                    if status_code != 200
         | 
| @@ -212,20 +209,20 @@ module GoogleMaps | |
| 212 209 | 
             
                    begin
         | 
| 213 210 | 
             
                      body = JSON.parse(resp.body)
         | 
| 214 211 | 
             
                    rescue JSON::ParserError
         | 
| 215 | 
            -
                      raise APIError.new(status_code),  | 
| 212 | 
            +
                      raise APIError.new(status_code), 'Received a malformed JSON response.'
         | 
| 216 213 | 
             
                    end
         | 
| 217 214 |  | 
| 218 | 
            -
                    api_status = body[ | 
| 219 | 
            -
                    if api_status ==  | 
| 215 | 
            +
                    api_status = body['status']
         | 
| 216 | 
            +
                    if api_status == 'OK' || api_status == 'ZERO_RESULTS'
         | 
| 220 217 | 
             
                      return body
         | 
| 221 218 | 
             
                    end
         | 
| 222 219 |  | 
| 223 | 
            -
                    if api_status ==  | 
| 220 | 
            +
                    if api_status == 'OVER_QUERY_LIMIT'
         | 
| 224 221 | 
             
                      raise RetriableRequest
         | 
| 225 222 | 
             
                    end
         | 
| 226 223 |  | 
| 227 | 
            -
                    if body.key?( | 
| 228 | 
            -
                      raise APIError.new(api_status), body[ | 
| 224 | 
            +
                    if body.key?('error_message')
         | 
| 225 | 
            +
                      raise APIError.new(api_status), body['error_message']
         | 
| 229 226 | 
             
                    else
         | 
| 230 227 | 
             
                      raise APIError.new(api_status)
         | 
| 231 228 | 
             
                    end
         | 
| @@ -241,7 +238,7 @@ module GoogleMaps | |
| 241 238 | 
             
                  def get_xml_body(resp)
         | 
| 242 239 | 
             
                    status_code = resp.code.to_i
         | 
| 243 240 | 
             
                    if status_code >= 300 && status_code < 400
         | 
| 244 | 
            -
                      return resp[ | 
| 241 | 
            +
                      return resp['location']
         | 
| 245 242 | 
             
                    end
         | 
| 246 243 |  | 
| 247 244 | 
             
                    if status_code != 200
         | 
| @@ -251,19 +248,19 @@ module GoogleMaps | |
| 251 248 | 
             
                    begin
         | 
| 252 249 | 
             
                      doc = Nokogiri::XML.parse(resp.body)
         | 
| 253 250 | 
             
                    rescue
         | 
| 254 | 
            -
                      raise APIError.new(status_code),  | 
| 251 | 
            +
                      raise APIError.new(status_code), 'Received a malformed XML response.'
         | 
| 255 252 | 
             
                    end
         | 
| 256 253 |  | 
| 257 | 
            -
                    api_status = doc.xpath( | 
| 258 | 
            -
                    if api_status ==  | 
| 254 | 
            +
                    api_status = doc.xpath('//status').first.text
         | 
| 255 | 
            +
                    if api_status == 'OK' || api_status == 'ZERO_RESULTS'
         | 
| 259 256 | 
             
                      return doc
         | 
| 260 257 | 
             
                    end
         | 
| 261 258 |  | 
| 262 | 
            -
                    if api_status ==  | 
| 259 | 
            +
                    if api_status == 'OVER_QUERY_LIMIT'
         | 
| 263 260 | 
             
                      raise RetriableRequest
         | 
| 264 261 | 
             
                    end
         | 
| 265 262 |  | 
| 266 | 
            -
                    error_message = doc.xpath( | 
| 263 | 
            +
                    error_message = doc.xpath('//error_message')
         | 
| 267 264 | 
             
                    if error_message
         | 
| 268 265 | 
             
                      raise APIError.new(api_status), error_message.text
         | 
| 269 266 | 
             
                    else
         | 
| @@ -283,21 +280,21 @@ module GoogleMaps | |
| 283 280 | 
             
                  def generate_auth_url(path, params={}, accepts_clientid)
         | 
| 284 281 | 
             
                    if accepts_clientid && self.client_id && self.client_secret
         | 
| 285 282 | 
             
                      if self.channel
         | 
| 286 | 
            -
                        params[ | 
| 283 | 
            +
                        params['channel'] = self.channel
         | 
| 287 284 | 
             
                      end
         | 
| 288 | 
            -
                      params[ | 
| 285 | 
            +
                      params['client'] = self.client_id
         | 
| 289 286 |  | 
| 290 | 
            -
                      path = [path, Util.urlencode_params(params)].join( | 
| 287 | 
            +
                      path = [path, Util.urlencode_params(params)].join('?')
         | 
| 291 288 | 
             
                      sig = Util.sign_hmac(self.client_secret, path)
         | 
| 292 | 
            -
                      return path +  | 
| 289 | 
            +
                      return path + '&signature=' + sig
         | 
| 293 290 | 
             
                    end
         | 
| 294 291 |  | 
| 295 292 | 
             
                    if self.key
         | 
| 296 | 
            -
                      params[ | 
| 297 | 
            -
                      return path +  | 
| 293 | 
            +
                      params['key'] = self.key
         | 
| 294 | 
            +
                      return path + '?' + Util.urlencode_params(params)
         | 
| 298 295 | 
             
                    end
         | 
| 299 296 |  | 
| 300 | 
            -
                    raise StandardError,  | 
| 297 | 
            +
                    raise StandardError, 'Must provide API key for this API. It does not accept enterprise credentials.'
         | 
| 301 298 | 
             
                  end
         | 
| 302 299 |  | 
| 303 300 | 
             
                  private :get_json_body, :get_xml_body, :generate_auth_url
         | 
| @@ -1,8 +1,8 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'googlemaps/services/util'
         | 
| 2 2 |  | 
| 3 3 | 
             
            module GoogleMaps
         | 
| 4 4 | 
             
              module Services
         | 
| 5 | 
            -
                 | 
| 5 | 
            +
                TRAVEL_MODES = %w(driving walking bicycling transit)
         | 
| 6 6 |  | 
| 7 7 | 
             
                # Performs requests to the Google Maps Directions API.
         | 
| 8 8 | 
             
                #
         | 
| @@ -48,74 +48,74 @@ module GoogleMaps | |
| 48 48 | 
             
                            arrival_time: nil, optimize_waypoints: false, transit_mode: nil,
         | 
| 49 49 | 
             
                            transit_routing_preference: nil, traffic_model: nil)
         | 
| 50 50 | 
             
                    params = {
         | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 51 | 
            +
                        'origin' => Convert.to_latlng(origin),
         | 
| 52 | 
            +
                        'destination' => Convert.to_latlng(destination)
         | 
| 53 53 | 
             
                    }
         | 
| 54 54 |  | 
| 55 55 | 
             
                    if mode
         | 
| 56 | 
            -
                       | 
| 57 | 
            -
                        raise StandardError,  | 
| 56 | 
            +
                      unless TRAVEL_MODES.include? mode
         | 
| 57 | 
            +
                        raise StandardError, 'invalid travel mode.'
         | 
| 58 58 | 
             
                      end
         | 
| 59 | 
            -
                      params[ | 
| 59 | 
            +
                      params['mode'] = mode
         | 
| 60 60 | 
             
                    end
         | 
| 61 61 |  | 
| 62 62 | 
             
                    if waypoints
         | 
| 63 63 | 
             
                      waypoints = Convert.piped_location(waypoints)
         | 
| 64 64 | 
             
                      if optimize_waypoints
         | 
| 65 | 
            -
                        waypoints =  | 
| 65 | 
            +
                        waypoints = 'optimize:true|' + waypoints
         | 
| 66 66 | 
             
                      end
         | 
| 67 | 
            -
                      params[ | 
| 67 | 
            +
                      params['waypoints'] = waypoints
         | 
| 68 68 | 
             
                    end
         | 
| 69 69 |  | 
| 70 70 | 
             
                    if alternatives
         | 
| 71 | 
            -
                      params[ | 
| 71 | 
            +
                      params['alternatives'] = true
         | 
| 72 72 | 
             
                    end
         | 
| 73 73 |  | 
| 74 74 | 
             
                    if avoid
         | 
| 75 | 
            -
                      params[ | 
| 75 | 
            +
                      params['avoid'] = Convert.join_array('|', avoid)
         | 
| 76 76 | 
             
                    end
         | 
| 77 77 |  | 
| 78 78 | 
             
                    if language
         | 
| 79 | 
            -
                      params[ | 
| 79 | 
            +
                      params['language'] = language
         | 
| 80 80 | 
             
                    end
         | 
| 81 81 |  | 
| 82 82 | 
             
                    if units
         | 
| 83 | 
            -
                      params[ | 
| 83 | 
            +
                      params['units'] = units
         | 
| 84 84 | 
             
                    end
         | 
| 85 85 |  | 
| 86 86 | 
             
                    if region
         | 
| 87 | 
            -
                      params[ | 
| 87 | 
            +
                      params['region'] = region
         | 
| 88 88 | 
             
                    end
         | 
| 89 89 |  | 
| 90 90 | 
             
                    if departure_time
         | 
| 91 | 
            -
                      params[ | 
| 91 | 
            +
                      params['departure_time'] = Convert.unix_time(departure_time)
         | 
| 92 92 | 
             
                    end
         | 
| 93 93 |  | 
| 94 94 | 
             
                    if arrival_time
         | 
| 95 | 
            -
                      params[ | 
| 95 | 
            +
                      params['arrival_time'] = Convert.unix_time(arrival_time)
         | 
| 96 96 | 
             
                    end
         | 
| 97 97 |  | 
| 98 98 | 
             
                    if departure_time && arrival_time
         | 
| 99 | 
            -
                      raise StandardError,  | 
| 99 | 
            +
                      raise StandardError, 'should not specify both departure_time and arrival_time.'
         | 
| 100 100 | 
             
                    end
         | 
| 101 101 |  | 
| 102 102 | 
             
                    if transit_mode
         | 
| 103 | 
            -
                      params[ | 
| 103 | 
            +
                      params['transit_mode'] = Convert.join_array('|', transit_mode)
         | 
| 104 104 | 
             
                    end
         | 
| 105 105 |  | 
| 106 106 | 
             
                    if transit_routing_preference
         | 
| 107 | 
            -
                      params[ | 
| 107 | 
            +
                      params['transit_routing_preference'] = transit_routing_preference
         | 
| 108 108 | 
             
                    end
         | 
| 109 109 |  | 
| 110 110 | 
             
                    if traffic_model
         | 
| 111 | 
            -
                      params[ | 
| 111 | 
            +
                      params['traffic_model'] = traffic_model
         | 
| 112 112 | 
             
                    end
         | 
| 113 113 |  | 
| 114 114 | 
             
                    case self.client.response_format
         | 
| 115 115 | 
             
                    when :xml
         | 
| 116 | 
            -
                      self.client.get(url:  | 
| 116 | 
            +
                      self.client.get(url: '/maps/api/directions/xml', params: params).xpath('//route')
         | 
| 117 117 | 
             
                    else
         | 
| 118 | 
            -
                      self.client.get(url:  | 
| 118 | 
            +
                      self.client.get(url: '/maps/api/directions/json', params: params)['routes']
         | 
| 119 119 | 
             
                    end
         | 
| 120 120 | 
             
                  end
         | 
| 121 121 | 
             
                end
         | 
| @@ -1,9 +1,8 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'googlemaps/services/util'
         | 
| 2 2 |  | 
| 3 3 | 
             
            module GoogleMaps
         | 
| 4 4 | 
             
              module Services
         | 
| 5 | 
            -
             | 
| 6 | 
            -
                $AVOIDS = ["tolls", "highways", "ferries"]
         | 
| 5 | 
            +
                AVOIDS = %w(tolls highways ferries)
         | 
| 7 6 |  | 
| 8 7 | 
             
                # Performs requests to the Google Maps Distance Matrix API.
         | 
| 9 8 | 
             
                #
         | 
| @@ -41,57 +40,53 @@ module GoogleMaps | |
| 41 40 | 
             
                            units: nil, departure_time: nil, arrival_time: nil, transit_mode: nil,
         | 
| 42 41 | 
             
                            transit_routing_preference: nil, traffic_model: nil)
         | 
| 43 42 | 
             
                    params = {
         | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 43 | 
            +
                        'origins' => Convert.piped_location(origins),
         | 
| 44 | 
            +
                        'destinations' => Convert.piped_location(destinations)
         | 
| 46 45 | 
             
                    }
         | 
| 47 46 |  | 
| 48 47 | 
             
                    if mode
         | 
| 49 | 
            -
                       | 
| 50 | 
            -
             | 
| 51 | 
            -
                      end
         | 
| 52 | 
            -
                      params["mode"] = mode
         | 
| 48 | 
            +
                      raise StandardError, 'Invalid travel mode.' unless TRAVEL_MODES.include? mode
         | 
| 49 | 
            +
                      params['mode'] = mode
         | 
| 53 50 | 
             
                    end
         | 
| 54 51 |  | 
| 55 52 | 
             
                    if language
         | 
| 56 | 
            -
                      params[ | 
| 53 | 
            +
                      params['language'] = language
         | 
| 57 54 | 
             
                    end
         | 
| 58 55 |  | 
| 59 56 | 
             
                    if avoid
         | 
| 60 | 
            -
                       | 
| 61 | 
            -
             | 
| 62 | 
            -
                      end
         | 
| 63 | 
            -
                      params["avoid"] = avoid
         | 
| 57 | 
            +
                      raise StandardError, 'Invalid route restriction.' unless AVOIDS.include? avoid
         | 
| 58 | 
            +
                      params['avoid'] = avoid
         | 
| 64 59 | 
             
                    end
         | 
| 65 60 |  | 
| 66 61 | 
             
                    if units
         | 
| 67 | 
            -
                      params[ | 
| 62 | 
            +
                      params['units'] = units
         | 
| 68 63 | 
             
                    end
         | 
| 69 64 |  | 
| 70 65 | 
             
                    if departure_time
         | 
| 71 | 
            -
                      params[ | 
| 66 | 
            +
                      params['departure_time'] = Convert.unix_time(departure_time)
         | 
| 72 67 | 
             
                    end
         | 
| 73 68 |  | 
| 74 69 | 
             
                    if arrival_time
         | 
| 75 | 
            -
                      params[ | 
| 70 | 
            +
                      params['arrival_time'] = Convert.unix_time(arrival_time)
         | 
| 76 71 | 
             
                    end
         | 
| 77 72 |  | 
| 78 73 | 
             
                    if departure_time && arrival_time
         | 
| 79 | 
            -
                      raise StandardError,  | 
| 74 | 
            +
                      raise StandardError, 'Should not specify both departure_time and arrival_time.'
         | 
| 80 75 | 
             
                    end
         | 
| 81 76 |  | 
| 82 77 | 
             
                    if transit_mode
         | 
| 83 | 
            -
                      params[ | 
| 78 | 
            +
                      params['transit_mode'] = Convert.join_array('|', transit_mode)
         | 
| 84 79 | 
             
                    end
         | 
| 85 80 |  | 
| 86 81 | 
             
                    if transit_routing_preference
         | 
| 87 | 
            -
                      params[ | 
| 82 | 
            +
                      params['transit_routing_preference'] = transit_routing_preference
         | 
| 88 83 | 
             
                    end
         | 
| 89 84 |  | 
| 90 85 | 
             
                    if traffic_model
         | 
| 91 | 
            -
                      params[ | 
| 86 | 
            +
                      params['traffic_model'] = traffic_model
         | 
| 92 87 | 
             
                    end
         | 
| 93 88 |  | 
| 94 | 
            -
                    self.client.get(url: "/maps/api/distancematrix/#{self.client.response_format}", params: params) | 
| 89 | 
            +
                    self.client.get(url: "/maps/api/distancematrix/#{self.client.response_format}", params: params)
         | 
| 95 90 | 
             
                  end
         | 
| 96 91 | 
             
                end
         | 
| 97 92 | 
             
              end
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'googlemaps/services/util'
         | 
| 2 2 |  | 
| 3 3 |  | 
| 4 4 | 
             
            module GoogleMaps
         | 
| @@ -29,30 +29,31 @@ module GoogleMaps | |
| 29 29 | 
             
                    params = {}
         | 
| 30 30 |  | 
| 31 31 | 
             
                    if path && locations
         | 
| 32 | 
            -
                      raise StandardError,  | 
| 32 | 
            +
                      raise StandardError, 'Should not specify both path and locations.'
         | 
| 33 33 | 
             
                    end
         | 
| 34 34 |  | 
| 35 35 | 
             
                    if locations
         | 
| 36 | 
            -
                      params[ | 
| 36 | 
            +
                      params['locations'] = Convert.shortest_path(locations)
         | 
| 37 37 | 
             
                    end
         | 
| 38 38 |  | 
| 39 39 | 
             
                    if path
         | 
| 40 | 
            -
                       | 
| 40 | 
            +
                      case path.class
         | 
| 41 | 
            +
                      when String
         | 
| 41 42 | 
             
                        path = "enc:#{path}"
         | 
| 42 | 
            -
                       | 
| 43 | 
            +
                      when Array
         | 
| 43 44 | 
             
                        path = Convert.shortest_path(path)
         | 
| 44 45 | 
             
                      else
         | 
| 45 | 
            -
                        raise TypeError,  | 
| 46 | 
            +
                        raise TypeError, 'Path should be either a String or an Array.'
         | 
| 46 47 | 
             
                      end
         | 
| 47 48 |  | 
| 48 | 
            -
                      params = { | 
| 49 | 
            +
                      params = {'path' => path, 'samples' => samples }
         | 
| 49 50 | 
             
                    end
         | 
| 50 51 |  | 
| 51 52 | 
             
                    case self.client.response_format
         | 
| 52 53 | 
             
                    when :xml
         | 
| 53 | 
            -
                      self.client.get(url:  | 
| 54 | 
            +
                      self.client.get(url: '/maps/api/elevation/xml', params: params).xpath('//result')
         | 
| 54 55 | 
             
                    else
         | 
| 55 | 
            -
                      self.client.get(url:  | 
| 56 | 
            +
                      self.client.get(url: '/maps/api/elevation/json', params: params)['results']
         | 
| 56 57 | 
             
                    end
         | 
| 57 58 | 
             
                  end
         | 
| 58 59 | 
             
                end
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'googlemaps/services/util'
         | 
| 2 2 |  | 
| 3 3 |  | 
| 4 4 | 
             
            module GoogleMaps
         | 
| @@ -34,30 +34,30 @@ module GoogleMaps | |
| 34 34 | 
             
                    params = {}
         | 
| 35 35 |  | 
| 36 36 | 
             
                    if address
         | 
| 37 | 
            -
                      params[ | 
| 37 | 
            +
                      params['address'] = address
         | 
| 38 38 | 
             
                    end
         | 
| 39 39 |  | 
| 40 40 | 
             
                    if components
         | 
| 41 | 
            -
                      params[ | 
| 41 | 
            +
                      params['components'] = Convert.components(components)
         | 
| 42 42 | 
             
                    end
         | 
| 43 43 |  | 
| 44 44 | 
             
                    if bounds
         | 
| 45 | 
            -
                      params[ | 
| 45 | 
            +
                      params['bounds'] = Convert.bounds(bounds)
         | 
| 46 46 | 
             
                    end
         | 
| 47 47 |  | 
| 48 48 | 
             
                    if region
         | 
| 49 | 
            -
                      params[ | 
| 49 | 
            +
                      params['region'] = region
         | 
| 50 50 | 
             
                    end
         | 
| 51 51 |  | 
| 52 52 | 
             
                    if language
         | 
| 53 | 
            -
                      params[ | 
| 53 | 
            +
                      params['language'] = language
         | 
| 54 54 | 
             
                    end
         | 
| 55 55 |  | 
| 56 56 | 
             
                    case self.client.response_format
         | 
| 57 57 | 
             
                    when :xml
         | 
| 58 | 
            -
                      self.client.get(url:  | 
| 58 | 
            +
                      self.client.get(url: '/maps/api/geocode/xml', params: params).xpath('//result')
         | 
| 59 59 | 
             
                    else
         | 
| 60 | 
            -
                      self.client.get(url:  | 
| 60 | 
            +
                      self.client.get(url: '/maps/api/geocode/json', params: params)['results']
         | 
| 61 61 | 
             
                    end
         | 
| 62 62 | 
             
                  end
         | 
| 63 63 | 
             
                end
         | 
| @@ -86,28 +86,28 @@ module GoogleMaps | |
| 86 86 | 
             
                    # Check if latlng param is a place_id string.
         | 
| 87 87 | 
             
                    # 'place_id' strings do not contain commas; latlng strings do.
         | 
| 88 88 | 
             
                    if latlng.is_a?(String) && !latlng.include?("'")
         | 
| 89 | 
            -
                      params = { | 
| 89 | 
            +
                      params = {'place_id' => latlng}
         | 
| 90 90 | 
             
                    else
         | 
| 91 | 
            -
                      params = { | 
| 91 | 
            +
                      params = {'latlng' => Convert.to_latlng(latlng)}
         | 
| 92 92 | 
             
                    end
         | 
| 93 93 |  | 
| 94 94 | 
             
                    if result_type
         | 
| 95 | 
            -
                      params[ | 
| 95 | 
            +
                      params['result_type'] = Convert.join_array('|', result_type)
         | 
| 96 96 | 
             
                    end
         | 
| 97 97 |  | 
| 98 98 | 
             
                    if location_type
         | 
| 99 | 
            -
                      params[ | 
| 99 | 
            +
                      params['location_type'] = Convert.join_array('|', location_type)
         | 
| 100 100 | 
             
                    end
         | 
| 101 101 |  | 
| 102 102 | 
             
                    if language
         | 
| 103 | 
            -
                      params[ | 
| 103 | 
            +
                      params['language'] = language
         | 
| 104 104 | 
             
                    end
         | 
| 105 105 |  | 
| 106 106 | 
             
                    case self.client.response_format
         | 
| 107 107 | 
             
                    when :xml
         | 
| 108 | 
            -
                      self.client.get(url:  | 
| 108 | 
            +
                      self.client.get(url: '/maps/api/geocode/xml', params: params).xpath('//result')
         | 
| 109 109 | 
             
                    else
         | 
| 110 | 
            -
                      self.client.get(url:  | 
| 110 | 
            +
                      self.client.get(url: '/maps/api/geocode/json', params: params)['results']
         | 
| 111 111 | 
             
                    end
         | 
| 112 112 | 
             
                  end
         | 
| 113 113 | 
             
                end
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'googlemaps/services/util'
         | 
| 2 2 |  | 
| 3 3 | 
             
            module GoogleMaps
         | 
| 4 4 | 
             
              module Services
         | 
| @@ -27,8 +27,8 @@ module GoogleMaps | |
| 27 27 | 
             
                  # @return [Hash, Nokogiri::XML::Document] Valid JSON or XML response.
         | 
| 28 28 | 
             
                  def search(query:, location: nil, radius: nil, language: nil, min_price: nil,
         | 
| 29 29 | 
             
                             max_price: nil, open_now: false, type: nil, page_token: nil)
         | 
| 30 | 
            -
                    _places(url_part:  | 
| 31 | 
            -
                            language: language, min_price: min_price, | 
| 30 | 
            +
                    _places(url_part: 'text', query: query, location: location, radius: radius,
         | 
| 31 | 
            +
                            language: language, min_price: min_price, max_price: max_price,
         | 
| 32 32 | 
             
                            open_now: open_now, type: type, page_token: page_token)
         | 
| 33 33 | 
             
                  end
         | 
| 34 34 |  | 
| @@ -49,15 +49,15 @@ module GoogleMaps | |
| 49 49 | 
             
                  # @return [Hash, Nokogiri::XML::Document] Valid JSON or XML response.
         | 
| 50 50 | 
             
                  def nearby(location:, radius: nil, keyword: nil, language: nil, min_price: nil,
         | 
| 51 51 | 
             
                             max_price: nil, name: nil, open_now: false, rank_by: nil, type: nil, page_token: nil)
         | 
| 52 | 
            -
                    if rank_by ==  | 
| 52 | 
            +
                    if rank_by == 'distance'
         | 
| 53 53 | 
             
                      if !(keyword || name || type)
         | 
| 54 | 
            -
                        raise StandardError,  | 
| 54 | 
            +
                        raise StandardError, 'either a keyword, name or type arg is required when rank_by is set to distance.'
         | 
| 55 55 | 
             
                      elsif radius
         | 
| 56 | 
            -
                        raise StandardError,  | 
| 56 | 
            +
                        raise StandardError, 'radius cannot be specified when rank_by is set to distance.'
         | 
| 57 57 | 
             
                      end
         | 
| 58 58 | 
             
                    end
         | 
| 59 59 |  | 
| 60 | 
            -
                    _places(url_part:  | 
| 60 | 
            +
                    _places(url_part: 'nearby', location: location, radius: radius, keyword: keyword, language: language,
         | 
| 61 61 | 
             
                            min_price: min_price, max_price: max_price, name: name, open_now: open_now, rank_by: rank_by,
         | 
| 62 62 | 
             
                            type: type, page_token: page_token)
         | 
| 63 63 | 
             
                  end
         | 
| @@ -76,13 +76,13 @@ module GoogleMaps | |
| 76 76 | 
             
                  # @return [Hash, Nokogiri::XML::Document] Valid JSON or XML response.
         | 
| 77 77 | 
             
                  def radar(location:, radius:, keyword: nil, min_price: nil,
         | 
| 78 78 | 
             
                                 max_price: nil, name: nil, open_now: false, type: nil)
         | 
| 79 | 
            -
                     | 
| 80 | 
            -
                      raise StandardError,  | 
| 79 | 
            +
                    unless keyword || name || type
         | 
| 80 | 
            +
                      raise StandardError, 'either a keyword, name, or type arg is required.'
         | 
| 81 81 | 
             
                    end
         | 
| 82 82 |  | 
| 83 | 
            -
                    _places(url_part:  | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 83 | 
            +
                    _places(url_part: 'radar', location: location, radius: radius,
         | 
| 84 | 
            +
                            keyword: keyword, min_price: min_price, max_price: max_price,
         | 
| 85 | 
            +
                            name: name, open_now: open_now, type: type)
         | 
| 86 86 | 
             
                  end
         | 
| 87 87 |  | 
| 88 88 | 
             
                  # Handler for "places", "places_nearby" and "places_radar" queries.
         | 
| @@ -90,52 +90,51 @@ module GoogleMaps | |
| 90 90 | 
             
                  def _places(url_part:, query: nil, location: nil, radius: nil, keyword: nil, language: nil,
         | 
| 91 91 | 
             
                              min_price: 0, max_price: 4, name: nil, open_now: false, rank_by: nil, type: nil,
         | 
| 92 92 | 
             
                              page_token: nil)
         | 
| 93 | 
            -
                    params = { | 
| 93 | 
            +
                    params = {'minprice' => min_price, 'maxprice' => max_price }
         | 
| 94 94 |  | 
| 95 95 | 
             
                    if query
         | 
| 96 | 
            -
                      params[ | 
| 96 | 
            +
                      params['query'] = query
         | 
| 97 97 | 
             
                    end
         | 
| 98 98 |  | 
| 99 99 | 
             
                    if location
         | 
| 100 | 
            -
                      params[ | 
| 100 | 
            +
                      params['location'] = Convert.to_latlng(location)
         | 
| 101 101 | 
             
                    end
         | 
| 102 102 |  | 
| 103 103 | 
             
                    if radius
         | 
| 104 | 
            -
                      params[ | 
| 104 | 
            +
                      params['radius'] = radius
         | 
| 105 105 | 
             
                    end
         | 
| 106 106 |  | 
| 107 107 | 
             
                    if keyword
         | 
| 108 | 
            -
                      params[ | 
| 108 | 
            +
                      params['keyword'] = keyword
         | 
| 109 109 | 
             
                    end
         | 
| 110 110 |  | 
| 111 111 | 
             
                    if language
         | 
| 112 | 
            -
                      params[ | 
| 112 | 
            +
                      params['language'] = language
         | 
| 113 113 | 
             
                    end
         | 
| 114 114 |  | 
| 115 115 | 
             
                    if name
         | 
| 116 | 
            -
                      params[ | 
| 116 | 
            +
                      params['name'] = Convert.join_array(' ', name)
         | 
| 117 117 | 
             
                    end
         | 
| 118 118 |  | 
| 119 119 | 
             
                    if open_now
         | 
| 120 | 
            -
                      params[ | 
| 120 | 
            +
                      params['opennow'] = 'true'
         | 
| 121 121 | 
             
                    end
         | 
| 122 122 |  | 
| 123 123 | 
             
                    if rank_by
         | 
| 124 | 
            -
                      params[ | 
| 124 | 
            +
                      params['rankby'] = rank_by
         | 
| 125 125 | 
             
                    end
         | 
| 126 126 |  | 
| 127 127 | 
             
                    if type
         | 
| 128 | 
            -
                      params[ | 
| 128 | 
            +
                      params['type'] = type
         | 
| 129 129 | 
             
                    end
         | 
| 130 130 |  | 
| 131 131 | 
             
                    if page_token
         | 
| 132 | 
            -
                      params[ | 
| 132 | 
            +
                      params['pagetoken'] = page_token
         | 
| 133 133 | 
             
                    end
         | 
| 134 134 |  | 
| 135 135 | 
             
                    self.client.get(url: "/maps/api/place/#{url_part}search/#{self.client.response_format}", params: params)
         | 
| 136 136 | 
             
                  end
         | 
| 137 137 |  | 
| 138 | 
            -
             | 
| 139 138 | 
             
                  # Comprehensive details for an individual place.
         | 
| 140 139 | 
             
                  #
         | 
| 141 140 | 
             
                  # @param [String] place_id A textual identifier that uniquely identifies a place, returned from a Places search.
         | 
| @@ -143,9 +142,9 @@ module GoogleMaps | |
| 143 142 | 
             
                  #
         | 
| 144 143 | 
             
                  # @return [Hash, Nokogiri::XML::Document] Valid JSON or XML response.
         | 
| 145 144 | 
             
                  def place_details(place_id:, language: nil)
         | 
| 146 | 
            -
                    params = { | 
| 145 | 
            +
                    params = {'placeid' => place_id }
         | 
| 147 146 | 
             
                    if language
         | 
| 148 | 
            -
                      params[ | 
| 147 | 
            +
                      params['language'] = language
         | 
| 149 148 | 
             
                    end
         | 
| 150 149 |  | 
| 151 150 | 
             
                    self.client.get(url: "/maps/api/place/details/#{self.client.response_format}", params: params)
         | 
| @@ -159,21 +158,21 @@ module GoogleMaps | |
| 159 158 | 
             
                  #
         | 
| 160 159 | 
             
                  # @return [String] URL of the photo.
         | 
| 161 160 | 
             
                  def place_photo(photo_reference:, max_width: nil, max_height: nil)
         | 
| 162 | 
            -
                     | 
| 163 | 
            -
                      raise StandardError,  | 
| 161 | 
            +
                    unless max_width || max_height
         | 
| 162 | 
            +
                      raise StandardError, 'a max_width or max_height arg is required'
         | 
| 164 163 | 
             
                    end
         | 
| 165 164 |  | 
| 166 | 
            -
                    params = { | 
| 165 | 
            +
                    params = {'photoreference' => photo_reference}
         | 
| 167 166 |  | 
| 168 167 | 
             
                    if max_width
         | 
| 169 | 
            -
                      params[ | 
| 168 | 
            +
                      params['maxwidth'] = max_width
         | 
| 170 169 | 
             
                    end
         | 
| 171 170 |  | 
| 172 171 | 
             
                    if max_height
         | 
| 173 | 
            -
                      params[ | 
| 172 | 
            +
                      params['maxheight'] = max_height
         | 
| 174 173 | 
             
                    end
         | 
| 175 174 |  | 
| 176 | 
            -
                    self.client.get(url:  | 
| 175 | 
            +
                    self.client.get(url: '/maps/api/place/photo', params: params)
         | 
| 177 176 | 
             
                  end
         | 
| 178 177 |  | 
| 179 178 | 
             
                  # Returns Place predictions given a textual search string and optional geographic bounds.
         | 
| @@ -202,7 +201,7 @@ module GoogleMaps | |
| 202 201 | 
             
                  #
         | 
| 203 202 | 
             
                  # @return [Array, Nokogiri::XML::NodeSet] Array of predictions.
         | 
| 204 203 | 
             
                  def autocomplete_query(input_text:, offset: nil, location: nil, radius: nil, language: nil)
         | 
| 205 | 
            -
                    _autocomplete(url_part:  | 
| 204 | 
            +
                    _autocomplete(url_part: 'query', input_text: input_text, offset: offset,
         | 
| 206 205 | 
             
                                  location: location, radius: radius, language: language)
         | 
| 207 206 | 
             
                  end
         | 
| 208 207 |  | 
| @@ -210,37 +209,37 @@ module GoogleMaps | |
| 210 209 | 
             
                  # @private
         | 
| 211 210 | 
             
                  def _autocomplete(url_part:, input_text:, offset: nil, location: nil,
         | 
| 212 211 | 
             
                                   radius: nil, language: nil, type: nil, components: nil)
         | 
| 213 | 
            -
                    params = { | 
| 212 | 
            +
                    params = {'input' => input_text }
         | 
| 214 213 |  | 
| 215 214 | 
             
                    if offset
         | 
| 216 | 
            -
                      params[ | 
| 215 | 
            +
                      params['offset'] = offset
         | 
| 217 216 | 
             
                    end
         | 
| 218 217 |  | 
| 219 218 | 
             
                    if location
         | 
| 220 | 
            -
                      params[ | 
| 219 | 
            +
                      params['location'] = Convert.to_latlng(location)
         | 
| 221 220 | 
             
                    end
         | 
| 222 221 |  | 
| 223 222 | 
             
                    if radius
         | 
| 224 | 
            -
                      params[ | 
| 223 | 
            +
                      params['radius'] = radius
         | 
| 225 224 | 
             
                    end
         | 
| 226 225 |  | 
| 227 226 | 
             
                    if language
         | 
| 228 | 
            -
                      params[ | 
| 227 | 
            +
                      params['language'] = language
         | 
| 229 228 | 
             
                    end
         | 
| 230 229 |  | 
| 231 230 | 
             
                    if type
         | 
| 232 | 
            -
                      params[ | 
| 231 | 
            +
                      params['type'] = type
         | 
| 233 232 | 
             
                    end
         | 
| 234 233 |  | 
| 235 234 | 
             
                    if components
         | 
| 236 | 
            -
                      params[ | 
| 235 | 
            +
                      params['components'] = Convert.components(components)
         | 
| 237 236 | 
             
                    end
         | 
| 238 237 |  | 
| 239 238 | 
             
                    case self.client.response_format
         | 
| 240 239 | 
             
                    when :xml
         | 
| 241 | 
            -
                      self.client.get(url: "/maps/api/place/#{url_part}autocomplete/xml", params: params).xpath( | 
| 240 | 
            +
                      self.client.get(url: "/maps/api/place/#{url_part}autocomplete/xml", params: params).xpath('//prediction')
         | 
| 242 241 | 
             
                    else
         | 
| 243 | 
            -
                      self.client.get(url: "/maps/api/place/#{url_part}autocomplete/json", params: params)[ | 
| 242 | 
            +
                      self.client.get(url: "/maps/api/place/#{url_part}autocomplete/json", params: params)['predictions']
         | 
| 244 243 | 
             
                    end
         | 
| 245 244 | 
             
                  end
         | 
| 246 245 |  | 
| @@ -1,11 +1,10 @@ | |
| 1 | 
            -
            require  | 
| 2 | 
            -
            require  | 
| 3 | 
            -
            require  | 
| 1 | 
            +
            require 'googlemaps/services/exceptions'
         | 
| 2 | 
            +
            require 'googlemaps/services/util'
         | 
| 3 | 
            +
            require 'json'
         | 
| 4 4 |  | 
| 5 5 | 
             
            module GoogleMaps
         | 
| 6 6 | 
             
              module Services
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                $ROADS_BASE_URL = "https://roads.googleapis.com"
         | 
| 7 | 
            +
                ROADS_BASE_URL = 'https://roads.googleapis.com'
         | 
| 9 8 |  | 
| 10 9 | 
             
                # Performs requests to the Google Maps Roads API.
         | 
| 11 10 | 
             
                class Roads
         | 
| @@ -17,19 +16,19 @@ module GoogleMaps | |
| 17 16 | 
             
                    begin
         | 
| 18 17 | 
             
                      body = JSON.parse(resp.body)
         | 
| 19 18 | 
             
                    rescue JSON::ParserError
         | 
| 20 | 
            -
                      raise APIError.new(status_code),  | 
| 19 | 
            +
                      raise APIError.new(status_code), 'Received malformed response.'
         | 
| 21 20 | 
             
                    end
         | 
| 22 21 |  | 
| 23 | 
            -
                    if body.key?( | 
| 24 | 
            -
                      error = body[ | 
| 25 | 
            -
                      status = error[ | 
| 22 | 
            +
                    if body.key?('error')
         | 
| 23 | 
            +
                      error = body['error']
         | 
| 24 | 
            +
                      status = error['status']
         | 
| 26 25 |  | 
| 27 | 
            -
                      if status ==  | 
| 26 | 
            +
                      if status == 'RESOURCE_EXHAUSTED'
         | 
| 28 27 | 
             
                        raise RetriableRequest
         | 
| 29 28 | 
             
                      end
         | 
| 30 29 |  | 
| 31 | 
            -
                      if error.key?( | 
| 32 | 
            -
                        raise APIError.new(status), error[ | 
| 30 | 
            +
                      if error.key?('message')
         | 
| 31 | 
            +
                        raise APIError.new(status), error['message']
         | 
| 33 32 | 
             
                      else
         | 
| 34 33 | 
             
                        raise APIError.new(status)
         | 
| 35 34 | 
             
                      end
         | 
| @@ -59,14 +58,14 @@ module GoogleMaps | |
| 59 58 | 
             
                  #
         | 
| 60 59 | 
             
                  # @return [Array] Array of snapped points.
         | 
| 61 60 | 
             
                  def snap_to_roads(path:, interpolate: false)
         | 
| 62 | 
            -
                    params = { | 
| 61 | 
            +
                    params = {'path' => Convert.piped_location(path) }
         | 
| 63 62 |  | 
| 64 63 | 
             
                    if interpolate
         | 
| 65 | 
            -
                      params[ | 
| 64 | 
            +
                      params['interpolate'] = 'true'
         | 
| 66 65 | 
             
                    end
         | 
| 67 66 |  | 
| 68 | 
            -
                    self.client.get(url:  | 
| 69 | 
            -
                                    accepts_clientid: false, extract_body: @@_roads_extract)[ | 
| 67 | 
            +
                    self.client.get(url: '/v1/snapToRoads', params: params, base_url: ROADS_BASE_URL,
         | 
| 68 | 
            +
                                    accepts_clientid: false, extract_body: @@_roads_extract)['snappedPoints']
         | 
| 70 69 | 
             
                  end
         | 
| 71 70 |  | 
| 72 71 | 
             
                  # Returns the posted speed limit (in km/h) for given road segments.
         | 
| @@ -78,10 +77,10 @@ module GoogleMaps | |
| 78 77 | 
             
                  def speed_limits(place_ids:)
         | 
| 79 78 | 
             
                    raise StandardError, "#{__method__.to_s} expected an Array for place_ids." unless place_ids.is_a? Array
         | 
| 80 79 |  | 
| 81 | 
            -
                    params = { | 
| 80 | 
            +
                    params = {'placeId' => place_ids}
         | 
| 82 81 |  | 
| 83 | 
            -
                    self.client.get(url:  | 
| 84 | 
            -
                                    accepts_clientid: false, extract_body: @@_roads_extract)[ | 
| 82 | 
            +
                    self.client.get(url: '/v1/speedLimits', params: params, base_url: ROADS_BASE_URL,
         | 
| 83 | 
            +
                                    accepts_clientid: false, extract_body: @@_roads_extract)['speedLimits']
         | 
| 85 84 | 
             
                  end
         | 
| 86 85 |  | 
| 87 86 | 
             
                  # Returns the posted speed limit (in km/h) for given road segments.
         | 
| @@ -91,9 +90,9 @@ module GoogleMaps | |
| 91 90 | 
             
                  #
         | 
| 92 91 | 
             
                  # @return [Hash] Hash with an array of speed limits and an array of the snapped points.
         | 
| 93 92 | 
             
                  def snapped_speed_limits(path:)
         | 
| 94 | 
            -
                    params = { | 
| 93 | 
            +
                    params = {'path' => Convert.piped_location(path)}
         | 
| 95 94 |  | 
| 96 | 
            -
                    self.client.get(url:  | 
| 95 | 
            +
                    self.client.get(url: '/v1/speedLimits', params: params, base_url: ROADS_BASE_URL,
         | 
| 97 96 | 
             
                                    accepts_clientid: false, extract_body: @@_roads_extract)
         | 
| 98 97 | 
             
                  end
         | 
| 99 98 |  | 
| @@ -105,11 +104,12 @@ module GoogleMaps | |
| 105 104 | 
             
                  #
         | 
| 106 105 | 
             
                  # @return [Array] An array of snapped points.
         | 
| 107 106 | 
             
                  def nearest_roads(points:)
         | 
| 108 | 
            -
                    params = { | 
| 107 | 
            +
                    params = {'points' => Convert.piped_location(points)}
         | 
| 109 108 |  | 
| 110 | 
            -
                    self.client.get(url:  | 
| 111 | 
            -
                                    accepts_clientid: false, extract_body: @@_roads_extract)[ | 
| 109 | 
            +
                    self.client.get(url: '/v1/nearestRoads', params: params, base_url: ROADS_BASE_URL,
         | 
| 110 | 
            +
                                    accepts_clientid: false, extract_body: @@_roads_extract)['snappedPoints']
         | 
| 112 111 | 
             
                  end
         | 
| 113 112 | 
             
                end
         | 
| 113 | 
            +
             | 
| 114 114 | 
             
              end
         | 
| 115 115 | 
             
            end
         | 
| @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require 'googlemaps/services/util'
         | 
| 2 2 |  | 
| 3 3 | 
             
            module GoogleMaps
         | 
| 4 4 | 
             
              module Services
         | 
| @@ -27,12 +27,12 @@ module GoogleMaps | |
| 27 27 | 
             
                  # @return [Hash] Valid JSON or XML response.
         | 
| 28 28 | 
             
                  def query(location:, timestamp: nil, language: nil)
         | 
| 29 29 | 
             
                    params = {
         | 
| 30 | 
            -
             | 
| 31 | 
            -
             | 
| 30 | 
            +
                        'location' => Convert.to_latlng(location),
         | 
| 31 | 
            +
                        'timestamp' => Convert.unix_time(timestamp || Util.current_utctime)
         | 
| 32 32 | 
             
                    }
         | 
| 33 33 |  | 
| 34 34 | 
             
                    if language
         | 
| 35 | 
            -
                      params[ | 
| 35 | 
            +
                      params['language'] = language
         | 
| 36 36 | 
             
                    end
         | 
| 37 37 |  | 
| 38 38 | 
             
                    self.client.get(url: "/maps/api/timezone/#{self.client.response_format}", params: params)
         | 
| @@ -1,8 +1,8 @@ | |
| 1 | 
            -
            require  | 
| 2 | 
            -
            require  | 
| 3 | 
            -
            require  | 
| 4 | 
            -
            require  | 
| 5 | 
            -
            require  | 
| 1 | 
            +
            require 'net/http'
         | 
| 2 | 
            +
            require 'openssl'
         | 
| 3 | 
            +
            require 'base64'
         | 
| 4 | 
            +
            require 'date'
         | 
| 5 | 
            +
            require 'erb'
         | 
| 6 6 |  | 
| 7 7 | 
             
            module GoogleMaps
         | 
| 8 8 | 
             
              module Services
         | 
| @@ -12,7 +12,7 @@ module GoogleMaps | |
| 12 12 | 
             
                    if has_key?(meth.to_s)
         | 
| 13 13 | 
             
                      self[meth.to_s]
         | 
| 14 14 | 
             
                    else
         | 
| 15 | 
            -
                      raise NoMethodError,  | 
| 15 | 
            +
                      raise NoMethodError, "undefined method #{meth} for #{self}"
         | 
| 16 16 | 
             
                    end
         | 
| 17 17 | 
             
                  end
         | 
| 18 18 | 
             
                end
         | 
| @@ -102,11 +102,12 @@ module GoogleMaps | |
| 102 102 | 
             
                  #
         | 
| 103 103 | 
             
                  # @return [String] seconds since unix epoch.
         | 
| 104 104 | 
             
                  def self.unix_time(val)
         | 
| 105 | 
            -
                     | 
| 105 | 
            +
                    case val
         | 
| 106 | 
            +
                    when Integer
         | 
| 106 107 | 
             
                      val.to_s
         | 
| 107 | 
            -
                     | 
| 108 | 
            +
                    when Time
         | 
| 108 109 | 
             
                      val.to_i.to_s
         | 
| 109 | 
            -
                     | 
| 110 | 
            +
                    when Date
         | 
| 110 111 | 
             
                      val.to_time.to_i.to_s
         | 
| 111 112 | 
             
                    else
         | 
| 112 113 | 
             
                      raise TypeError, "#{__method__.to_s} expected value to be Integer, Time or Date."
         | 
| @@ -123,9 +124,10 @@ module GoogleMaps | |
| 123 124 | 
             
                  #
         | 
| 124 125 | 
             
                  # @return [String] comma-separated string.
         | 
| 125 126 | 
             
                  def self.to_latlng(arg)
         | 
| 126 | 
            -
                     | 
| 127 | 
            +
                    case arg
         | 
| 128 | 
            +
                    when String
         | 
| 127 129 | 
             
                      arg
         | 
| 128 | 
            -
                     | 
| 130 | 
            +
                    when Hash
         | 
| 129 131 | 
             
                      "#{self.format_float(arg[:lat])},#{self.format_float(arg[:lng])}"
         | 
| 130 132 | 
             
                    else
         | 
| 131 133 | 
             
                      raise TypeError, "#{__method__.to_s} expected location to be String or Hash."
         | 
| @@ -140,7 +142,7 @@ module GoogleMaps | |
| 140 142 | 
             
                  #
         | 
| 141 143 | 
             
                  # @return [String] formatted value of lat or lng float
         | 
| 142 144 | 
             
                  def self.format_float(arg)
         | 
| 143 | 
            -
                    arg.to_s.chomp( | 
| 145 | 
            +
                    arg.to_s.chomp('0').chomp('.')
         | 
| 144 146 | 
             
                  end
         | 
| 145 147 |  | 
| 146 148 | 
             
                  # Joins an array of locations into a pipe separated string, handling
         | 
| @@ -153,8 +155,8 @@ module GoogleMaps | |
| 153 155 | 
             
                  #
         | 
| 154 156 | 
             
                  # @return [String] pipe-separated string.
         | 
| 155 157 | 
             
                  def self.piped_location(arg)
         | 
| 156 | 
            -
                    raise TypeError, "#{__method__.to_s} expected argument to be an Array." unless arg.instance_of?  | 
| 157 | 
            -
                    arg.map { |location| to_latlng(location) }.join( | 
| 158 | 
            +
                    raise TypeError, "#{__method__.to_s} expected argument to be an Array." unless arg.instance_of? Array
         | 
| 159 | 
            +
                    arg.map { |location| to_latlng(location) }.join('|')
         | 
| 158 160 | 
             
                  end
         | 
| 159 161 |  | 
| 160 162 | 
             
                  # If arg is array-like, then joins it with sep
         | 
| @@ -179,9 +181,8 @@ module GoogleMaps | |
| 179 181 | 
             
                    raise TypeError, "#{__method__.to_s} expected a Hash of components." unless arg.is_a? Hash
         | 
| 180 182 |  | 
| 181 183 | 
             
                    arg.map { |c, val|
         | 
| 182 | 
            -
                      ArrayBox.wrap(val).map {|elem| "#{c}:#{elem}"}
         | 
| 183 | 
            -
             | 
| 184 | 
            -
                    }.join("|")
         | 
| 184 | 
            +
                      ArrayBox.wrap(val).map {|elem| "#{c}:#{elem}"}.sort_by(&:downcase)
         | 
| 185 | 
            +
                    }.join('|')
         | 
| 185 186 | 
             
                  end
         | 
| 186 187 |  | 
| 187 188 | 
             
                  # Converts a lat/lng bounds to a comma- and pipe-separated string.
         | 
| @@ -212,7 +213,7 @@ module GoogleMaps | |
| 212 213 | 
             
                  def self.encode_polyline(points)
         | 
| 213 214 | 
             
                    raise TypeError, "#{__method__.to_s} expected an Array of points." unless points.is_a? Array
         | 
| 214 215 | 
             
                    last_lat, last_lng = 0, 0
         | 
| 215 | 
            -
                    result =  | 
| 216 | 
            +
                    result = ''
         | 
| 216 217 | 
             
                    points.each { |point|
         | 
| 217 218 | 
             
                      lat = (point[:lat] * 1e5).round.to_i
         | 
| 218 219 | 
             
                      lng = (point[:lng] * 1e5).round.to_i
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: googlemaps-services
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.2. | 
| 4 | 
            +
              version: 1.2.5
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Faissal Elamraoui
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2016- | 
| 11 | 
            +
            date: 2016-11-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: nokogiri
         | 
| @@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 111 111 | 
             
                  version: '0'
         | 
| 112 112 | 
             
            requirements: []
         | 
| 113 113 | 
             
            rubyforge_project: 
         | 
| 114 | 
            -
            rubygems_version: 2. | 
| 114 | 
            +
            rubygems_version: 2.5.1
         | 
| 115 115 | 
             
            signing_key: 
         | 
| 116 116 | 
             
            specification_version: 4
         | 
| 117 117 | 
             
            summary: Ruby Client library for Google Maps API Web Services
         |