def _read_http_error_body(self, error): try: return decode_page(error) except Exception: logger.debug('Unable to fetch body for a non-successful HTTP response', exc_info=True) return None
def reverse(self, query, timeout=None): # pylint: disable=W0221 """ Given a point, find an address. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ params = { 'ak': self.api_key, 'output': 'json', 'location': self._coerce_point_to_string(query), } url = "?".join((self.api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_reverse_json( self._call_geocoder(url, timeout=timeout))
def geocode(self, query, exactly_one=True): # pylint: disable=W0613,W0221 """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. """ query_str = self.format_string % query url = "?".join((self._get_url(), urlencode({'address': query_str}))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) page = self._call_geocoder(url, raw=True) page = page.read().decode("utf-8") if py3k else page.read() places = [ r for r in csv.reader([ page, ] if not isinstance(page, list) else page) ] if not len(places): return None if exactly_one is True: return self._parse_result(places[0]) else: return [self._parse_result(res) for res in places]
def reverse(self, query, exactly_one=True, timeout=None): """ Returns a reverse geocoded location. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param bool exactly_one: Return one result or a list of results, if available. GeocodeFarm's API will always return at most one result. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ lat, lon = self._coerce_point_to_string(query).split(',') url = "".join(( self.reverse_api, quote(("%s/%s" % (lat, lon)).encode('utf8')) )) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one )
def reverse(self, query, exactly_one=True, timeout=None): # pylint: disable=W0221 """ Reverse geocode a point. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s". :param bool exactly_one: Return one result, or a list? :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ point = self._coerce_point_to_string(query) params = {'key': self.api_key} url = "%s/%s?%s" % (self.api, point, urlencode(params)) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def geocode(self, query, exactly_one=True, timeout=DEFAULT_SENTINEL): """ Return a location point by address. :param str query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = { 'addr': self.format_string % query, } if self.api_key: params['key'] = self.api_key url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one )
def geocode(self, query, lang='en', exactly_one=True, timeout=None): """ Geocode a "3 words" or "OneWord" query. :param str query: The 3-word or OneWord-address you wish to geocode. :param str lang: two character language codes as supported by the API (http://what3words.com/api/reference/languages). :param bool exactly_one: Parameter has no effect for this geocoder. Due to the address scheme there is always exactly one result. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ if not self._check_query(query): raise exc.GeocoderQueryError("Search string must be either like " "'word.word.word' or '*word' ") params = { 'string': self.format_string % query, 'lang': self.format_string % lang.lower(), 'key': self.api_key, } url = "?".join(((self.api + "w3w"), urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def geocode(self, query, exactly_one=True, timeout=None): params = {'text': query, 'f': 'json'} if exactly_one is True: params['maxLocations'] = 1 url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) response = self._call_geocoder(url, timeout=timeout) # Handle any errors; recursing in the case of an expired token. if 'error' in response: if response['error']['code'] == self._TOKEN_EXPIRED: # Authentication token is expired or old; make a new one. self.retry += 1 self._refresh_authentication_token() return self.geocode(query, exactly_one=exactly_one, timeout=timeout) raise GeocoderError( 'Got unknown error from ArcGIS. ' 'Request URL: %s; response JSON: %s' % (url, json.dumps(response)) ) # Success; convert from the ArcGIS JSON format. if not len(response['locations']): return None geocoded = [] for resource in response['locations']: geometry = resource['feature']['geometry'] geocoded.append((resource['name'], (geometry['y'], geometry['x']))) if exactly_one is True: return geocoded[0] return geocoded
def geocode(self, query, *, exactly_one=True, timeout=DEFAULT_SENTINEL): """ Return a location point by address. :param str query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = { 'ak': self.api_key, 'output': 'json', 'address': query, } url = self._construct_url(self.api, self.api_path, params) logger.debug("%s.geocode: %s", self.__class__.__name__, url) callback = partial(self._parse_json, exactly_one=exactly_one) return self._call_geocoder(url, callback, timeout=timeout)
def _refresh_authentication_token(self): """ POST to ArcGIS requesting a new token. """ if self.retry == self._MAX_RETRIES: raise GeocoderAuthenticationFailure( 'Too many retries for auth: %s' % self.retry ) token_request_arguments = { 'username': self.username, 'password': self.password, 'referer': self.referer, 'expiration': self.token_lifetime, 'f': 'json' } url = "?".join((self.auth_api, urlencode(token_request_arguments))) logger.debug( "%s._refresh_authentication_token: %s", self.__class__.__name__, url ) self.token_expiry = int(time()) + self.token_lifetime response = self._base_call_geocoder(url) if 'token' not in response: raise GeocoderAuthenticationFailure( 'Missing token in auth request.' 'Request URL: %s; response JSON: %s' % (url, json.dumps(response)) ) self.retry = 0 self.token = response['token']
def geocode(self, query, exactly_one=True, timeout=DEFAULT_SENTINEL, out_fields=None): """ Return a location point by address. :param str query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :param out_fields: A list of output fields to be returned in the attributes field of the raw data. This can be either a python list/tuple of fields or a comma-separated string. See https://developers.arcgis.com/rest/geocode/api-reference/geocoding-service-output.htm for a list of supported output fields. If you want to return all supported output fields, set ``out_fields="*"``. .. versionadded:: 1.14.0 :type out_fields: str or iterable :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = {'singleLine': self.format_string % query, 'f': 'json'} params['sourceCountry'] = "SG" if exactly_one: params['maxLocations'] = 1 if out_fields is not None: if isinstance(out_fields, string_compare): params['outFields'] = out_fields else: params['outFields'] = ",".join(out_fields) url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) response = self._call_geocoder(url, timeout=timeout) # Handle any errors; recursing in the case of an expired token. if 'error' in response: if response['error']['code'] == self._TOKEN_EXPIRED: self.retry += 1 self._refresh_authentication_token() return self.geocode(query, exactly_one=exactly_one, timeout=timeout) raise GeocoderServiceError(str(response['error'])) # Success; convert from the ArcGIS JSON format. if not len(response['candidates']): return None geocoded = [] for resource in response['candidates']: geometry = resource['location'] geocoded.append( Location(resource['address'], (geometry['y'], geometry['x']), resource)) if exactly_one: return geocoded[0] return geocoded
def reverse(self, query, language=None, # pylint: disable=W0221 sensor=False, exactly_one=False): """ Given a point, find an address. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param string language: The language in which to return results. Default None. :param boolean sensor: Whether the geocoding request comes from a device with a location sensor. Default False. :param boolean exactly_one: Return one result or a list of results, if available. """ params = { 'latlng': self._coerce_point_to_string(query), 'sensor': str(sensor).lower() } if language: params['language'] = language if not self.premier: url = self._get_url(params) else: url = self._get_signed_url(params) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url), exactly_one)
def _refresh_authentication_token(self): """ POST to ArcGIS requesting a new token. """ if self.retry == self._MAX_RETRIES: logger.debug('Maximum retries (%s) reached; giving up.', self._MAX_RETRIES) raise GeocoderAuthenticationFailure( 'Too many retries for auth: %s' % self.retry) token_request_arguments = { 'username': self.username, 'password': self.password, 'expiration': self.token_lifetime, 'f': 'json' } token_request_arguments = "&".join([ "%s=%s" % (key, val) for key, val in token_request_arguments.items() ]) url = "&".join(("?".join((self.auth_api, token_request_arguments)), urlencode({'referer': self.referer}))) logger.debug("%s._refresh_authentication_token: %s", self.__class__.__name__, url) self.token_expiry = int(time()) + self.token_lifetime response = self._base_call_geocoder(url) if not 'token' in response: raise GeocoderAuthenticationFailure( 'Missing token in auth request.' 'Request URL: %s; response JSON: %s' % (url, json.dumps(response))) self.retry = 0 self.token = response['token']
def geocode(self, query, exactly_one=True, timeout=None): params = {'text': query, 'f': 'json'} if exactly_one is True: params['maxLocations'] = 1 url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) response = self._call_geocoder(url, timeout=timeout) # Handle any errors; recursing in the case of an expired token. if 'error' in response: if response['error']['code'] == self._TOKEN_EXPIRED: # Authentication token is expired or old; make a new one. self.retry += 1 self._refresh_authentication_token() return self.geocode(query, exactly_one=exactly_one, timeout=timeout) raise GeocoderError('Got unknown error from ArcGIS. ' 'Request URL: %s; response JSON: %s' % (url, json.dumps(response))) # Success; convert from the ArcGIS JSON format. if not len(response['locations']): return None geocoded = [] for resource in response['locations']: geometry = resource['feature']['geometry'] geocoded.append((resource['name'], (geometry['y'], geometry['x']))) if exactly_one is True: return geocoded[0] return geocoded
def geocode(self, query, lang="en", exactly_one=True, timeout=None): """ Geocode a "3 words" or "OneWord" query. :param string query: The 3-word or OneWord-address you wish to geocode. :param string lang: two character language codes as supported by the API (http://what3words.com/api/reference/languages). :param bool exactly_one: Parameter has no effect for this geocoder. Due to the address scheme there is always exactly one result. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ if not self._check_query(query): raise exc.GeocoderQueryError("Search string must be either like " "'word.word.word' or '*word' ") params = {"string": self.format_string % query, "lang": self.format_string % lang.lower()} url = "?".join(((self.api + "w3w"), "&".join(("=".join(("key", self.api_key)), urlencode(params))))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def geocode( self, query, exactly_one=True, timeout=None, ): """ Geocode a location query. :param string query: The query string to be geocoded; this must be URL encoded. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ params = { 'q': self.format_string % query, } if self.api_key is not None: params["api_key"] = self.api_key url = "?".join((self.geocode_api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json_geocode( self._call_geocoder(url, timeout=timeout), exactly_one )
def reverse(self, query, exactly_one=True, timeout=DEFAULT_SENTINEL): """ Return an address by location point. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of ``(latitude, longitude)``, or string as ``"%(latitude)s, %(longitude)s"``. :param bool exactly_one: Return one result or a list of results, if available. Baidu's API will always return at most one result. .. versionadded:: 1.14.0 :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = { 'ak': self.api_key, 'output': 'json', 'location': self._coerce_point_to_string(query), } url = self._construct_url(self.reverse_api, self.reverse_path, params) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_reverse_json( self._call_geocoder(url, timeout=timeout), exactly_one=exactly_one )
def reverse(self, query, lang='en', exactly_one=True, timeout=None): """ Given a point, find the 3 word address. :param query: The coordinates for which you wish to obtain the 3 word address. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param str lang: two character language codes as supported by the API (http://what3words.com/api/reference/languages). :param bool exactly_one: Parameter has no effect for this geocoder. Due to the address scheme there is always exactly one result. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ lang = lang.lower() params = { 'position': self._coerce_point_to_string(query), 'lang': self.format_string % lang, 'key': self.api_key, } url = "?".join(((self.api + "position"), urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_reverse_json( self._call_geocoder(url, timeout=timeout), )
def geocode(self, query, exactly_one=True, timeout=None): # pylint: disable=W0221 """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ params = {'geocode': query, 'format': 'json'} if not self.api_key is None: params['key'] = self.api_key if not self.lang is None: params['lang'] = self.lang if exactly_one is True: params['results'] = 1 url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one, )
def geocode(self, query, exactly_one=True, timeout=None): # pylint: disable=W0221 """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ params = { 'location' : query } if exactly_one: params['maxResults'] = 1 # don't urlencode MapQuest API keys url = "?".join(( self.api, "&".join(("=".join(('key', self.api_key)), urlencode(params))) )) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def reverse(self, query, exactly_one=True, timeout=DEFAULT_SENTINEL): """ Return an address by location point. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of ``(latitude, longitude)``, or string as ``"%(latitude)s, %(longitude)s"``. :param bool exactly_one: Return one result or a list of results, if available. GeocodeFarm's API will always return at most one result. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ try: lat, lon = self._coerce_point_to_string(query).split(',') except ValueError: raise ValueError("Must be a coordinate pair or Point") params = {'lat': lat, 'lon': lon} if self.api_key: params['key'] = self.api_key url = "?".join((self.reverse_api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def reverse(self, query, *, exactly_one=True, timeout=DEFAULT_SENTINEL): """ Return an address by location point. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of ``(latitude, longitude)``, or string as ``"%(latitude)s, %(longitude)s"``. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = {} params['key'] = self.api_key point = self._coerce_point_to_string(query, "%(lat)s,%(lon)s") params['location'] = point url = '?'.join((self.reverse_api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) callback = partial(self._parse_json, exactly_one=exactly_one) return self._call_geocoder(url, callback, timeout=timeout)
def geocode(self, query, exactly_one=True, timeout=None): # TODO: dict as query for parameterized query # TODO: SRID params = {'text': query, 'f': 'json'} if exactly_one is True: params['maxLocations'] = 1 url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) response = self._call_geocoder(url, timeout=timeout) # Handle any errors; recursing in the case of an expired token. if 'error' in response: if response['error']['code'] == self._TOKEN_EXPIRED: self.retry += 1 self._refresh_authentication_token() return self.geocode(query, exactly_one=exactly_one, timeout=timeout) raise GeocoderServiceError(str(response['error'])) # Success; convert from the ArcGIS JSON format. if not len(response['locations']): return None geocoded = [] for resource in response['locations']: geometry = resource['feature']['geometry'] geocoded.append((resource['name'], (geometry['y'], geometry['x']))) if exactly_one is True: return geocoded[0] return geocoded
def geocode(self, query, exactly_one=True, timeout=None): """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ params = { 'ak': self.api_key, 'output': 'json', 'address': self.format_string % query, } url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one=exactly_one)
def geocode(self, query, exactly_one=True, timeout=None): """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ url = "".join(( self.api, "?addr=", quote((self.format_string % query).encode('utf8')) )) if self.api_key: url += "&key=%s" % self.api_key logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one )
def geocode(self, query, city=None, exactly_one=True, timeout=None): """ Geocode an address. :param string query: The address or query you wish to geocode. :param string city: The city of the address you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ params = { 'address': self.format_string % query, 'output': 'json', 'ak': self.ak } if city: params['city'] = city url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def _refresh_authentication_token(self, callback_success, *, timeout, from_token): if from_token != self.token: # Token has already been updated by a concurrent call. return callback_success() token_request_arguments = { 'username': self.username, 'password': self.password, 'referer': self.referer, 'expiration': self.token_lifetime, 'f': 'json' } url = "?".join((self.auth_api, urlencode(token_request_arguments))) logger.debug("%s._refresh_authentication_token: %s", self.__class__.__name__, url) def cb(response): if "token" not in response: raise GeocoderAuthenticationFailure( "Missing token in auth request." "Request URL: %s; response JSON: %s" % (url, json.dumps(response))) self.token = response["token"] self.token_expiry = int(time()) + self.token_lifetime return callback_success() return self._call_geocoder(url, cb, timeout=timeout)
def geocode(self, query, exactly_one=True, timeout=None): # pylint: disable=W0221 """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ super(GeoNames, self).geocode(query) params = { 'q': query, 'username': self.username } if self.country_bias: params['countryBias'] = self.country_bias if exactly_one is True: params['maxRows'] = 1 url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def _parse_json(self, response, exactly_one=True): # pylint: disable=W0221 """ Parse a location name, latitude, and longitude from an JSON response. """ logger.debug(response) result = response.get('result', []) if not len(result): # pragma: no cover self._check_status(response.get('status')) return None def parse_result(result): """ Parse each return object. """ result = result['result'] address = result.get('formatted_address') latitude = result['location']['lat'] or None longitude = result['location']['lng'] or None if latitude and longitude: latitude = float(latitude) longitude = float(longitude) return Location(address, (latitude, longitude), result) return parse_result(response)
def reverse(self, query, lang="en", exactly_one=True, timeout=None): """ Given a point, find the 3 word address. :param query: The coordinates for which you wish to obtain the 3 word address. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param string lang: two character language codes as supported by the API (http://what3words.com/api/reference/languages). :param bool exactly_one: Parameter has no effect for this geocoder. Due to the address scheme there is always exactly one result. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ lang = lang.lower() params = {"position": self._coerce_point_to_string(query), "lang": self.format_string % lang} url = "?".join(((self.api + "position"), "&".join(("=".join(("key", self.api_key)), urlencode(params))))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_reverse_json(self._call_geocoder(url, timeout=timeout))
def geocode(self, query, exactly_one=True, timeout=None): # pylint: disable=W0613,W0221 """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ query_str = self.format_string % query url = "?".join((self._get_url(), urlencode({'address': query_str}))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) page = self._call_geocoder(url, timeout=timeout, raw=True) content = page.read().decode("utf-8") if py3k else page.read() places = [ r for r in csv.reader([ content, ] if not isinstance(content, list) else content) ] if not len(places): return None if exactly_one is True: return self._parse_result(places[0]) else: return [self._parse_result(res) for res in places]
def reverse(self, query, exactly_one=True, timeout=None): """ Returns a reverse geocoded location. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ lat, lon = [x.strip() for x in self._coerce_point_to_string(query).split(',')] # doh params = { 'lat': lat, 'lon' : lon, 'format' : 'json', } url = "?".join((self.reverse_api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one, True)
def reverse(self, query, timeout=None): """ Given a point, find an address. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. """ params = { 'ak': self.ak, 'location': self._coerce_point_to_string(query), 'output': 'json' } url = "?".join((self.api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_reverse_json( self._call_geocoder(url, timeout=timeout) )
def reverse(self, query, exactly_one=True, timeout=DEFAULT_SENTINEL): """ Return an address by location point. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of ``(latitude, longitude)``, or string as ``"%(latitude)s, %(longitude)s"``. :param bool exactly_one: Return one result or a list of results, if available. Baidu's API will always return at most one result. .. versionadded:: 1.14.0 :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = { 'ak': self.api_key, 'output': 'json', 'location': self._coerce_point_to_string(query), } url = self._construct_url(params) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_reverse_json( self._call_geocoder(url, timeout=timeout), exactly_one=exactly_one )
def place_search(self, query, field_params, tag=None, scope=2, filter=None, page_size=10, page_num=0, timeout=10, recursive=False): """ Place API 是一套免费使用的API接口,调用次数限制为10万次/天。 百度地图Place API服务地址: http://api.map.baidu.com/place/v2/search //v2 place区域检索POI服务 :param field_params: dict 检索的区域类型,三种检索方法 城市内: {'region': '济南'} 矩形 : {'bounds': '38.76623,116.43213,39.54321,116.46773'} 圆形 : {'location':'38.76623,116.43213', 'radius': 2000} http://api.map.baidu.com/place/v2/detail //v2 POI详情服务 http://api.map.baidu.com/place/v2/eventsearch //v2 团购信息检索服务 http://api.map.baidu.com/place/v2/eventdetail //v2 商家团购信息查询 """ params = { 'query': query, 'ak' : self.ak, 'output' : self.output, 'page_num' : page_num, 'scope' : scope } params = dict(params, **field_params) if tag: params['tag'] = tag url = "?".join((self.place_api + 'search', urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) page = self._call_geocoder(url, timeout=timeout) for poi in self.place_parse(query, field_params, page, tag, page_size, page_num, recursive): yield poi
def _refresh_authentication_token(self): """ POST to ArcGIS requesting a new token. """ if self.retry == self._MAX_RETRIES: logger.debug('Maximum retries (%s) reached; giving up.', self._MAX_RETRIES) raise GeocoderAuthenticationFailure( 'Too many retries for auth: %s' % self.retry ) token_request_arguments = { 'username': self.username, 'password': self.password, 'expiration': self.token_lifetime, 'f': 'json' } token_request_arguments = "&".join( ["%s=%s" % (key, val) for key, val in token_request_arguments.items()] ) url = "&".join(( "?".join((self.auth_api, token_request_arguments)), urlencode({'referer': self.referer}) )) logger.debug( "%s._refresh_authentication_token: %s", self.__class__.__name__, url ) self.token_expiry = int(time()) + self.token_lifetime response = self._base_call_geocoder(url) if not 'token' in response: raise GeocoderAuthenticationFailure( 'Missing token in auth request.' 'Request URL: %s; response JSON: %s' % (url, json.dumps(response)) ) self.retry = 0 self.token = response['token']
def geocode(self, query, exactly_one=True, timeout=None, **kwargs): """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ params = { 'addr': self.format_string % query, } self._add_optional_params(params, **kwargs) if self.api_key: params['key'] = self.api_key url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one )
def geocode(self, query, exactly_one=True, timeout=None): # pylint: disable=W0613,W0221 """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ query_str = self.format_string % query url = "?".join((self._get_url(), urlencode({'address':query_str}))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) page = self._call_geocoder(url, timeout=timeout, raw=True) content = page.read().decode("utf-8") if py3k else page.read() places = [r for r in csv.reader([content, ] if not isinstance(content, list) else content)] if not len(places): return None if exactly_one is True: return self._parse_result(places[0]) else: return [self._parse_result(res) for res in places]
def geocode(self, query, exactly_one=True, timeout=None, extra={}): # pylint: disable=W0221 """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ params = { 'q': query, 'username': self.username } for key in extra.keys(): params[key] = extra[key] if self.country_bias: params['countryBias'] = self.country_bias if exactly_one is True: params['maxRows'] = 1 url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one, )
def geocode( self, query, timeout=None, exactly_one=True, ): # pylint: disable=R0913,W0221 """ Geocode a location query. """ params = {'q': self.format_string % query} params.update({ 'format': 'json' }) url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) response = self._call_geocoder(url, timeout=timeout) # Success; convert from the ArcGIS JSON format. if not len(response['candidates']): return None geocoded = [] for resource in response['candidates']: geocoded.append( Location( resource['address'], (resource['location']['y'], resource['location']['x']), resource ) ) if exactly_one is True: return geocoded[0] return geocoded
def geocode(self, query, exactly_one=True, timeout=None): # pylint: disable=W0221 """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ params = { 'geocode': query, 'format': 'json' } if not self.api_key is None: params['key'] = self.api_key if not self.lang is None: params['lang'] = self.lang if exactly_one is True: params['results'] = 1 url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one, )
def reverse(self, location, coordtype='bd09ll', pois=0, timeout=None): """ Given a point, find an address. :param location: The coordinates for which you wish to obtain the closest human-readable addresses. 根据经纬度坐标获取地址 :type location: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param coordtype:坐标的类型 目前支持的坐标类型包括:bd09ll(百度经纬度坐标)、gcj02ll(国测局经纬度坐标)、wgs84ll( GPS经纬度) :param pois:是否显示指定位置周边的poi,0为不显示,1为显示。当值为1时,显示周边100米内的poi。 :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. """ params = { 'location': self._coerce_point_to_string(location), 'ak' : self.ak, 'output' : self.output } if pois: params['pois'] = pois url = "?".join((self.geocoding_api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_reverse_json(self._call_geocoder(url, timeout=timeout), pois)
def geocode(self, query, exactly_one=True, timeout=None): """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ super(Nominatim, self).geocode(query) params = { 'q': self.format_string % query, 'view_box' : self.view_box, 'format' : 'json', } if self.country_bias: params['countrycodes'] = self.country_bias url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def geocode(self, query, exactly_one=True, user_location=None): # pylint: disable=W0221 """ Geocode an address. :param string query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param user_location: Prioritize results closer to this location. .. versionadded:: 0.96.0 :type user_location: :class:`geopy.point.Point` """ params = { 'query': self.format_string % query, 'key': self.api_key } if user_location: params['userLocation'] = ",".join( (user_location.latitude, user_location.longitude) ) if exactly_one is True: params['maxResults'] = 1 url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url), exactly_one)
def geocode( self, query, bounds=None, country=None, language=None, exactly_one=True, timeout=None, ): # pylint: disable=W0221,R0913 """ Geocode a location query. :param string query: The query string to be geocoded; this must be URL encoded. :param string language: an IETF format language code (such as `es` for Spanish or pt-BR for Brazilian Portuguese); if this is omitted a code of `en` (English) will be assumed by the remote service. :param string bounds: Provides the geocoder with a hint to the region that the query resides in. This value will help the geocoder but will not restrict the possible results to the supplied region. The bounds parameter should be specified as 4 coordinate points forming the south-west and north-east corners of a bounding box. For example, `bounds=-0.563160,51.280430,0.278970,51.683979`. :param string country: Provides the geocoder with a hint to the country that the query resides in. This value will help the geocoder but will not restrict the possible results to the supplied country. The country code is a 3 character code as defined by the ISO 3166-1 Alpha 3 standard. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ params = { 'key': self.api_key, 'q': self.format_string % query, } if bounds: params['bounds'] = bounds if bounds: params['language'] = language if bounds: params['country'] = country url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one )
def reverse(self, query, exactly_one=True, timeout=None): # pylint: disable=W0221 """ Reverse geocode a point. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param bool exactly_one: Return one result, or a list? :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 """ point = self._coerce_point_to_string(query) params = {'key': self.api_key} url = "%s/%s?%s" % ( self.api, point, urlencode(params)) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def geocode( self, query, bounds=None, country=None, language=None, exactly_one=True, timeout=None, ): # pylint: disable=W0221,R0913 """ Geocode a location query. :param string query: The query string to be geocoded; this must be URL encoded. :param string language: an IETF format language code (such as `es` for Spanish or pt-BR for Brazilian Portuguese); if this is omitted a code of `en` (English) will be assumed by the remote service. :param string bounds: Provides the geocoder with a hint to the region that the query resides in. This value will help the geocoder but will not restrict the possible results to the supplied region. The bounds parameter should be specified as 4 coordinate points forming the south-west and north-east corners of a bounding box. For example, `bounds=-0.563160,51.280430,0.278970,51.683979`. :param string country: Provides the geocoder with a hint to the country that the query resides in. This value will help the geocoder but will not restrict the possible results to the supplied country. The country code is a 3 character code as defined by the ISO 3166-1 Alpha 3 standard. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. """ params = { 'key': self.api_key, 'q': self.format_string % query, } if bounds: params['bounds'] = bounds if language: params['language'] = language if country: params['country'] = country url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def reverse( self, query, exactly_one=True, timeout=None, language=False, ): # pylint: disable=W0221 """ Returns a reverse geocoded location. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. .. versionadded:: 0.97 :param string language: Preferred language in which to return results. Either uses standard `RFC2616 <http://www.ietf.org/rfc/rfc2616.txt>`_ accept-language string or a simple comma-separated list of language codes. :type addressdetails: string .. versionadded:: 1.0.0 """ try: lat, lon = [ x.strip() for x in self._coerce_point_to_string(query).split(',') ] # doh except ValueError: raise ValueError("Must be a coordinate pair or Point") params = { 'lat': lat, 'lon': lon, 'format': 'json', } if self.api_key: params['key'] = self.api_key if language: params['accept-language'] = language url = "?".join((self.reverse_api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one )
def geocode(self, string, exactly_one=True): params = {'q': self.format_string % string} url = self.url % urlencode(params) logger.debug("Fetching %s..." % url) page = urlopen(url) return self.parse_json(page, exactly_one)
def geocode( self, query, exactly_one=True, timeout=DEFAULT_SENTINEL, limit=None, typeahead=False, language=None, ): """ Return a location point by address. :param str query: The address or query you wish to geocode. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :param int limit: Maximum amount of results to return from the service. Unless exactly_one is set to False, limit will always be 1. :param bool typeahead: If the "typeahead" flag is set, the query will be interpreted as a partial input and the search will enter predictive mode. :param str language: Language in which search results should be returned. When data in specified language is not available for a specific field, default language is used. List of supported languages (case-insensitive): https://developer.tomtom.com/online-search/online-search-documentation/supported-languages :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ query = self.format_string % query params = self._geocode_params(query) params['typeahead'] = self._boolean_value(typeahead) if limit: params['limit'] = str(int(limit)) if exactly_one: params['limit'] = '1' if language: params['language'] = language quoted_query = quote(query.encode('utf-8')) url = "?".join((self.api % dict(query=quoted_query), urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one )
def timezone(self, location, at_time=None, timeout=None): """ **This is an unstable API.** Finds the timezone a `location` was in for a specified `at_time`, and returns a pytz timezone object. .. versionadded:: 1.2.0 :param location: The coordinates for which you want a timezone. :type location: :class:`geopy.point.Point`, list or tuple of (latitude, longitude), or string as "%(latitude)s, %(longitude)s" :param at_time: The time at which you want the timezone of this location. This is optional, and defaults to the time that the function is called in UTC. :type at_time integer, long, float, datetime: :rtype: pytz timezone """ if not pytz_available: raise ImportError( 'pytz must be installed in order to locate timezones. ' ' Install with `pip install geopy -e ".[timezone]"`.') location = self._coerce_point_to_string(location) if isinstance(at_time, Number): timestamp = at_time elif isinstance(at_time, datetime): timestamp = timegm(at_time.utctimetuple()) elif at_time is None: timestamp = timegm(datetime.utcnow().utctimetuple()) else: raise GeocoderQueryError("`at_time` must be an epoch integer or " "datetime.datetime object") params = { "location": location, "timestamp": timestamp, } if self.api_key: params['key'] = self.api_key url = "?".join((self.tz_api, urlencode(params))) logger.debug("%s.timezone: %s", self.__class__.__name__, url) response = self._call_geocoder(url, timeout=timeout) try: tz = timezone(response["timeZoneId"]) except UnknownTimeZoneError: raise GeocoderParseError( "pytz could not parse the timezone identifier (%s) " "returned by the service." % response["timeZoneId"]) except KeyError: raise GeocoderParseError( "geopy could not find a timezone in this response: %s" % response) return tz
def reverse(self, query, exactly_one=True, timeout=DEFAULT_SENTINEL, language=False, addressdetails=True): """ Return an address by location point. :param query: The coordinates for which you wish to obtain the closest human-readable addresses. :type query: :class:`geopy.point.Point`, list or tuple of ``(latitude, longitude)``, or string as ``"%(latitude)s, %(longitude)s"``. :param bool exactly_one: Return one result or a list of results, if available. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :param str language: Preferred language in which to return results. Either uses standard `RFC2616 <http://www.ietf.org/rfc/rfc2616.txt>`_ accept-language string or a simple comma-separated list of language codes. .. versionadded:: 1.0.0 :param bool addressdetails: Whether or not to include address details, such as city, county, state, etc. in *Location.raw* .. versionadded:: 1.14.0 :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ try: lat, lon = self._coerce_point_to_string(query).split(',') except ValueError: raise ValueError("Must be a coordinate pair or Point") params = { 'lat': lat, 'lon': lon, 'format': 'json', } if language: params['accept-language'] = language params['addressdetails'] = 1 if addressdetails else 0 url = self._construct_url(self.reverse_api, params) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def geocode( self, query, country_codes=None, exactly_one=True, timeout=DEFAULT_SENTINEL, ): """ Return a location point by address. :param str query: The address or query you wish to geocode. For a structured query, provide a dictionary whose keys are one of: `country`, `state`, `city`, `zipcode`, `street`, `address`, `houseNumber` or `subNumber`. :param str country_codes: Provides the geocoder with a list of country codes that the query may reside in. This value will limit the geocoder to the supplied countries. Te country code is a 2 character code as defined by the ISO-3166-1 alpha-2 standard. :param bool exactly_one: Return one result or a list of one result. :param int timeout: Time, in seconds, to wait for the geocoding service to respond before raising a :class:`geopy.exc.GeocoderTimedOut` exception. Set this only if you wish to override, on this call only, the value set during the geocoder's initialization. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ if isinstance(query, dict): params = { key: val for key, val in query.items() if key in self.structured_query_params } params['api_key'] = self.api_key else: params = { 'api_key': self.api_key, 'q': self.format_string % query, } if country_codes is None: country_codes = [] if len(country_codes): params['countryCodes'] = ",".join(country_codes) url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)