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): # 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 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, ): """ 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 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 _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, 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 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=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. """ try: lat, lon = [ x.strip() for x in 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 _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): """ 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 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 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, 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 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 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 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 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, 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, 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=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, bounds=None, region=None, # pylint: disable=W0221,R0913 components=None, language=None, sensor=False, exactly_one=True, timeout=None): """ Geocode a location query. :param string query: The address or query you wish to geocode. :param bounds: The bounding box of the viewport within which to bias geocode results more prominently. :type bounds: list or tuple :param string region: The region code, specified as a ccTLD ("top-level domain") two-character value. :param dict components: Restricts to an area. Can use any combination of: route, locality, administrative_area, postal_code, country. .. versionadded:: 0.97.1 :param string language: The language in which to return results. :param bool sensor: Whether the geocoding request comes from a device with a location sensor. :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, 'sensor': str(sensor).lower() } if self.api_key: params['key'] = self.api_key if bounds: params['bounds'] = bounds if region: params['region'] = region if components: params['components'] = self._format_components_param(components) if language: params['language'] = language if self.premier is False: url = "?".join((self.api, urlencode(dict([k, v.encode('utf-8')] for k, v in params.items())))) else: url = self._get_signed_url(dict([k, v.encode('utf-8')] for k, v in params.items())) 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, 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 geocode( self, query, exactly_one=True, timeout=DEFAULT_SENTINEL, ): """ Return a location point by address. :param str query: The address, query or structured query to geocode 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 = {'text': self.format_string % query} if self.api_key: params.update({ 'api_key': self.api_key }) if self.boundary_rect: boundary_rect = self.boundary_rect if len(boundary_rect) == 4: warnings.warn( '%s `boundary_rect` format of ' '`[longitude, latitude, longitude, latitude]` is now ' 'deprecated and will be not supported in geopy 2.0. ' 'Use `[Point(latitude, longitude), Point(latitude, longitude)]` ' 'instead.' % type(self).__name__, UserWarning ) lon1, lat1, lon2, lat2 = boundary_rect boundary_rect = [[lat1, lon1], [lat2, lon2]] lon1, lat1, lon2, lat2 = self._format_bounding_box( boundary_rect, "%(lon1)s,%(lat1)s,%(lon2)s,%(lat2)s").split(',') params['boundary.rect.min_lon'] = lon1 params['boundary.rect.min_lat'] = lat1 params['boundary.rect.max_lon'] = lon2 params['boundary.rect.max_lat'] = lat2 if self.country_bias: params['boundary.country'] = self.country_bias url = "?".join((self.geocode_api, urlencode(params))) logger.debug("%s.geocode_api: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(url, timeout=timeout), exactly_one )
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 ) if self.username: auth_url = self.auth_api token_request_arguments = { 'username': self.username, 'password': self.password, 'expiration': self.token_lifetime, 'f': 'json' } elif self.client_id: auth_url = self.oauth_api token_request_arguments = { 'client_id': self.client_id, 'client_secret': self.client_secret, # User/pass method takes token lifetime in seconds, # OAuth method takes token lifetime in minutes 'expiration': self.token_lifetime / 60, 'grant_type': 'client_credentials', } else: raise ConfigurationError("Invalid authentication configuration.") token_request_arguments = "&".join([ "%s=%s" % (key, val) for key, val in token_request_arguments.items() ]) url = "&".join(( "?".join((auth_url, 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 or 'access_token' in response): raise GeocoderAuthenticationFailure( 'Missing token in auth request. ' 'Request URL: %s; response JSON: %s' % (url, json.dumps(response)) ) self.retry = 0 if 'token' in response: self.token = response['token'] else: self.token = response['access_token']
def _construct_url(self, params): query_string = urlencode(params) if self.security_key is None: return "%s?%s" % (self.api, query_string) else: # http://lbsyun.baidu.com/index.php?title=lbscloud/api/appendix raw = "%s?%s%s" % (self.api_path, query_string, self.security_key) sn = hashlib.md5(quote_plus(raw).encode('utf-8')).hexdigest() return "%s?%s&sn=%s" % (self.api, query_string, sn)
def reverse( self, query, exactly_one=DEFAULT_SENTINEL, timeout=DEFAULT_SENTINEL, kind=None, ): """ 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. .. versionchanged:: 1.14.0 Default value for ``exactly_one`` was ``False``, which differs from the conventional default across geopy. Please always pass this argument explicitly, otherwise you would get a warning. In geopy 2.0 the default value will become ``True``. :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 kind: Type of toponym. Allowed values: `house`, `street`, `metro`, `district`, `locality`. .. versionadded:: 1.14.0 :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ if exactly_one is DEFAULT_SENTINEL: warnings.warn( '%s.reverse: default value for `exactly_one` ' 'argument will become True in geopy 2.0. ' 'Specify `exactly_one=False` as the argument ' 'explicitly to get rid of this warning.' % type(self).__name__, DeprecationWarning) exactly_one = False try: point = self._coerce_point_to_string(query, "%(lon)s,%(lat)s") except ValueError: raise ValueError("Must be a coordinate pair or Point") params = {'geocode': point, 'format': 'json'} if self.api_key: params['apikey'] = self.api_key if self.lang: params['lang'] = self.lang if kind: params['kind'] = kind url = "?".join((self.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=DEFAULT_SENTINEL, timeout=DEFAULT_SENTINEL, feature_code=None, lang=None, find_nearby_type='findNearbyPlaceName', ): """ Return an address by location point. .. versionadded:: 1.2.0 :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. .. versionchanged:: 1.14.0 Default value for ``exactly_one`` was ``False``, which differs from the conventional default across geopy. Please always pass this argument explicitly, otherwise you would get a warning. In geopy 2.0 the default value will become ``True``. :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 feature_code: A GeoNames feature code .. versionadded:: 1.18.0 :param str lang: language of the returned ``name`` element (the pseudo language code 'local' will return it in local language) Full list of supported languages can be found here: https://www.geonames.org/countries/ .. versionadded:: 1.18.0 :param str find_nearby_type: A flag to switch between different GeoNames API endpoints. The default value is ``findNearbyPlaceName`` which returns the closest populated place. Another currently implemented option is ``findNearby`` which returns the closest toponym for the lat/lng query. .. versionadded:: 1.18.0 :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ if exactly_one is DEFAULT_SENTINEL: warnings.warn('%s.reverse: default value for `exactly_one` ' 'argument will become True in geopy 2.0. ' 'Specify `exactly_one=False` as the argument ' 'explicitly to get rid of this warning.' % type(self).__name__, DeprecationWarning, stacklevel=2) exactly_one = False try: lat, lng = self._coerce_point_to_string(query).split(',') except ValueError: raise ValueError("Must be a coordinate pair or Point") if find_nearby_type == 'findNearbyPlaceName': # default if feature_code: raise ValueError( "find_nearby_type=findNearbyPlaceName doesn't support " "the `feature_code` param") params = self._reverse_find_nearby_place_name_params( lat=lat, lng=lng, lang=lang, ) url = "?".join((self.api_reverse, urlencode(params))) elif find_nearby_type == 'findNearby': if lang: raise ValueError( "find_nearby_type=findNearby doesn't support the `lang` param" ) params = self._reverse_find_nearby_params( lat=lat, lng=lng, feature_code=feature_code, ) url = "?".join((self.api_reverse_nearby, urlencode(params))) else: raise GeocoderQueryError( '`%s` find_nearby_type is not supported by geopy' % find_nearby_type) 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, country=None, country_bias=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 country: Limit records to the specified countries. Two letter country code ISO-3166 (e.g. ``FR``). Might be a single string or a list of strings. .. versionadded:: 1.19.0 :type country: str or list :param str country_bias: Records from the country_bias are listed first. Two letter country code ISO-3166. .. versionadded:: 1.19.0 :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = [ ('q', self.format_string % query), ('username', self.username), ] if country_bias is None: country_bias = self.country_bias if country_bias: params.append(('countryBias', country_bias)) if not country: country = [] if isinstance(country, string_compare): country = [country] for country_item in country: params.append(('country', country_item)) if exactly_one: params.append(('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, exactly_one=True, user_location=None, timeout=None, culture=None, include_neighborhood=None, include_country_code=False): # pylint: disable=W0221 """ Geocode an address. :param string query: The address or query you wish to geocode. For a structured query, provide a dictionary whose keys are one of: `addressLine`, `locality` (city), `adminDistrict` (state), `countryRegion`, or `postalcode`. :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 :type user_location: :class:`geopy.point.Point` :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 culture: Affects the language of the response, must be a two-letter country code. .. versionadded:: 1.4.0 :param boolean include_neighborhood: Sets whether to include the neighborhood field in the response. .. versionadded:: 1.4.0 :param boolean include_country_code: Sets whether to include the two-letter ISO code of the country in the response (field name 'countryRegionIso2'). .. versionadded:: 1.4.0 """ if isinstance(query, dict): params = { key: val for key, val in query.items() if key in self.structured_query_params } params['key'] = self.api_key else: params = {'query': self.format_string % query, 'key': self.api_key} if user_location: params['userLocation'] = ",".join( (str(user_location.latitude), str(user_location.longitude))) if exactly_one is True: params['maxResults'] = 1 if culture: params['culture'] = culture if include_neighborhood is not None: params['includeNeighborhood'] = include_neighborhood if include_country_code: params['include'] = 'ciso2' # the only acceptable value 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, reverse_geocode_preference=('StreetAddress', ), maximum_responses=25, filtering='', exactly_one=DEFAULT_SENTINEL, 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 list reverse_geocode_preference: Enable to set expected results type. It can be `StreetAddress` or `PositionOfInterest`. Default is set to `StreetAddress`. :param int maximum_responses: The maximum number of responses to ask to the API in the query body. :param str filtering: Provide string that help setting geocoder filter. It contains an XML string. See examples in documentation and ignfrance.py file in directory tests. :param bool exactly_one: Return one result or a list of results, if available. .. versionchanged:: 1.14.0 Default value for ``exactly_one`` was ``False``, which differs from the conventional default across geopy. Please always pass this argument explicitly, otherwise you would get a warning. In geopy 2.0 the default value will become ``True``. :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 exactly_one is DEFAULT_SENTINEL: warnings.warn( '%s.reverse: default value for `exactly_one` ' 'argument will become True in geopy 2.0. ' 'Specify `exactly_one=False` as the argument ' 'explicitly to get rid of this warning.' % type(self).__name__, DeprecationWarning) exactly_one = False sub_request = """ <ReverseGeocodeRequest> {reverse_geocode_preference} <Position> <gml:Point> <gml:pos>{query}</gml:pos> </gml:Point> {filtering} </Position> </ReverseGeocodeRequest> """ xml_request = self.xml_request.format( method_name='ReverseGeocodeRequest', sub_request=sub_request, maximum_responses=maximum_responses) for pref in reverse_geocode_preference: if pref not in ('StreetAddress', 'PositionOfInterest'): raise GeocoderQueryError( '`reverse_geocode_preference` must contain ' 'one or more of: StreetAddress, PositionOfInterest') point = self._coerce_point_to_string(query).replace(',', ' ') reverse_geocode_preference = '\n'.join( ('<ReverseGeocodePreference>%s</ReverseGeocodePreference>' % pref for pref in reverse_geocode_preference)) request_string = xml_request.format( maximum_responses=maximum_responses, query=point, reverse_geocode_preference=reverse_geocode_preference, filtering=filtering) url = "?".join((self.api, urlencode({'xls': request_string}))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) raw_xml = self._request_raw_content(url, timeout) return self._parse_xml(raw_xml, exactly_one=exactly_one, is_reverse=True, is_freeform='false')
def reverse( self, query, exactly_one=DEFAULT_SENTINEL, timeout=DEFAULT_SENTINEL, language=None, sensor=False, ): """ 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. .. versionchanged:: 1.14.0 Default value for ``exactly_one`` was ``False``, which differs from the conventional default across geopy. Please always pass this argument explicitly, otherwise you would get a warning. In geopy 2.0 the default value will become ``True``. :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: The language in which to return results. :param bool sensor: Whether the geocoding request comes from a device with a location sensor. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ if exactly_one is DEFAULT_SENTINEL: warnings.warn( '%s.reverse: default value for `exactly_one` ' 'argument will become True in geopy 2.0. ' 'Specify `exactly_one=False` as the argument ' 'explicitly to get rid of this warning.' % type(self).__name__, DeprecationWarning) exactly_one = False params = { 'latlng': self._coerce_point_to_string(query), 'sensor': str(sensor).lower() } if language: params['language'] = language if self.api_key: params['key'] = self.api_key if not self.premier: url = "?".join((self.api, urlencode(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, timeout=timeout), exactly_one)
def geocode( self, query, bounds=None, country=None, language=None, exactly_one=True, timeout=DEFAULT_SENTINEL, ): """ Return a location point by address. :param str query: The address or query you wish to geocode. :param str 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. :type bounds: list or tuple of 2 items of :class:`geopy.point.Point` or ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``. :param 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 2 coordinate points -- corners of a bounding box. Example: ``[Point(22, 180), Point(-22, -180)]``. .. versionchanged:: 1.17.0 Previously the only supported format for bounds was a string of ``"longitude,latitude,longitude,latitude"``. This format is now deprecated in favor of a list/tuple of a pair of geopy Points and will be removed in geopy 2.0. :param country: Restricts the results to the specified country or countries. The country code is a 2 character code as defined by the ISO 3166-1 Alpha 2 standard (e.g. ``fr``). Might be a Python list of strings. .. versionchanged:: 1.19.0 This parameter didn't seem to be respected previously. Also, previously only a single string could be specified. Now a Python list of individual countries is supported. :type country: str or list :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 = { 'key': self.api_key, 'q': self.format_string % query, } if bounds: if isinstance(bounds, string_compare): warnings.warn( 'OpenCage `bounds` format of ' '`"longitude,latitude,longitude,latitude"` is now ' 'deprecated and will not be supported in geopy 2.0. ' 'Use `[Point(latitude, longitude), Point(latitude, longitude)]` ' 'instead.', DeprecationWarning, stacklevel=2) lon1, lat1, lon2, lat2 = bounds.split(',') bounds = [[lat1, lon1], [lat2, lon2]] params['bounds'] = self._format_bounding_box( bounds, "%(lon1)s,%(lat1)s,%(lon2)s,%(lat2)s") if language: params['language'] = language if not country: country = [] if isinstance(country, string_compare): country = [country] if country: params['countrycode'] = ",".join(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, timeout=None, distance=100, wkid=DEFAULT_WKID): """ 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. :param int distance: Search radius from query location, in meters. Default 100 meters if not specified. :param string wkid: WKID to use for both input and output coordinates. Default 4326 matching Brown ArcGIS server. """ # ArcGIS is lon,lat; maintain lat,lon convention of geopy point = self._coerce_point_to_string(query).split(",") if wkid != DEFAULT_WKID: location = {"x": point[1], "y": point[0], "spatialReference": wkid} else: location = ",".join((point[1], point[0])) params = { 'location': location, 'f': 'json', 'distance': distance, 'outSR': wkid } url = "?".join((self.reverse_api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) response = self._call_geocoder(url, timeout=timeout) if not len(response): return None if 'error' in response: if response['error']['code'] == self._TOKEN_EXPIRED: self.retry += 1 self._refresh_authentication_token() return self.reverse(query, timeout=timeout, distance=distance, wkid=wkid) raise GeocoderServiceError(str(response['error'])) address = { 'match_addr': ('%(Street)s, %(City)s, %(State)s, %(ZIP)s' % response['address']), 'location': { 'x': response['location']['x'], 'y': response['location']['y'] } } return address
def geocode( self, query=None, exactly_one=True, timeout=DEFAULT_SENTINEL, bounds=None, region=None, components=None, language=None, sensor=False, ): """ Return a location point by address. :param str query: The address or query you wish to geocode. Optional, if ``components`` param is set:: >>> g = GoogleV3() >>> g.geocode(components={"city": "Paris", "country": "FR"}) Location(France, (46.227638, 2.213749, 0.0)) .. versionchanged:: 1.14.0 Now ``query`` is optional if ``components`` param is set. :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 bounds: The bounding box of the viewport within which to bias geocode results more prominently. :type bounds: list or tuple :param str region: The region code, specified as a ccTLD ("top-level domain") two-character value. :param dict components: Restricts to an area. Can use any combination of: route, locality, administrative_area, postal_code, country. :param str language: The language in which to return results. :param bool sensor: Whether the geocoding request comes from a device with a location sensor. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = {'sensor': str(sensor).lower()} if query is None and not components: raise ValueError('Either `query` or `components` must be set.`') if query is not None: params['address'] = self.format_string % query if self.api_key: params['key'] = self.api_key if bounds: if len(bounds) != 4: raise GeocoderQueryError( "bounds must be a four-item iterable of lat,lon,lat,lon") params['bounds'] = self._format_bounds_param(bounds) if region: params['region'] = region if components: params['components'] = self._format_components_param(components) if language: params['language'] = language if self.premier: url = self._get_signed_url(params) else: 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=None, exactly_one=True, timeout=DEFAULT_SENTINEL, bounds=None, region=None, components=None, language=None, sensor=False, ): """ Return a location point by address. :param str query: The address or query you wish to geocode. Optional, if ``components`` param is set:: >>> g.geocode(components={"city": "Paris", "country": "FR"}) Location(France, (46.227638, 2.213749, 0.0)) .. versionchanged:: 1.14.0 Now ``query`` is optional if ``components`` param is set. :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. :type bounds: list or tuple of 2 items of :class:`geopy.point.Point` or ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``. :param bounds: The bounding box of the viewport within which to bias geocode results more prominently. Example: ``[Point(22, 180), Point(-22, -180)]``. .. versionchanged:: 1.17.0 Previously the only supported format for bounds was a list like ``[latitude, longitude, latitude, longitude]``. This format is now deprecated in favor of a list/tuple of a pair of geopy Points and will be removed in geopy 2.0. :param str region: The region code, specified as a ccTLD ("top-level domain") two-character value. :param dict components: Restricts to an area. Can use any combination of: route, locality, administrative_area, postal_code, country. :param str language: The language in which to return results. :param bool sensor: Whether the geocoding request comes from a device with a location sensor. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = {'sensor': str(sensor).lower()} if query is None and not components: raise ValueError('Either `query` or `components` must be set.`') if query is not None: params['address'] = self.format_string % query if self.api_key: params['key'] = self.api_key if bounds: if len(bounds) == 4: warnings.warn( 'GoogleV3 `bounds` format of ' '`[latitude, longitude, latitude, longitude]` is now ' 'deprecated and will be not supported in geopy 2.0. ' 'Use `[Point(latitude, longitude), Point(latitude, longitude)]` ' 'instead.', UserWarning, stacklevel=2) lat1, lon1, lat2, lon2 = bounds bounds = [[lat1, lon1], [lat2, lon2]] params['bounds'] = self._format_bounding_box( bounds, "%(lat1)s,%(lon1)s|%(lat2)s,%(lon2)s") if region: params['region'] = region if components: params['components'] = self._format_components_param(components) if language: params['language'] = language if self.premier: url = self._get_signed_url(params) else: 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=DEFAULT_SENTINEL, boundary_rect=None, country_bias=None, language=None): """ Return a location point by address. :param str query: The address, query or structured query to geocode 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. :type boundary_rect: list or tuple of 2 items of :class:`geopy.point.Point` or ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``. :param boundary_rect: Coordinates to restrict search within. Example: ``[Point(22, 180), Point(-22, -180)]``. .. versionadded:: 1.19.0 :param str country_bias: Bias results to this country (ISO alpha-3). .. versionadded:: 1.19.0 :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.21.0 :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = {'text': self.format_string % query} if self.api_key: params.update({'api_key': self.api_key}) if boundary_rect is None: boundary_rect = self.boundary_rect if boundary_rect: if len(boundary_rect) == 4: warnings.warn( '%s `boundary_rect` format of ' '`[longitude, latitude, longitude, latitude]` is now ' 'deprecated and will not be supported in geopy 2.0. ' 'Use `[Point(latitude, longitude), Point(latitude, longitude)]` ' 'instead.' % type(self).__name__, DeprecationWarning, stacklevel=2) lon1, lat1, lon2, lat2 = boundary_rect boundary_rect = [[lat1, lon1], [lat2, lon2]] lon1, lat1, lon2, lat2 = self._format_bounding_box( boundary_rect, "%(lon1)s,%(lat1)s,%(lon2)s,%(lat2)s").split(',') params['boundary.rect.min_lon'] = lon1 params['boundary.rect.min_lat'] = lat1 params['boundary.rect.max_lon'] = lon2 params['boundary.rect.max_lat'] = lat2 if country_bias is None: country_bias = self.country_bias if country_bias: params['boundary.country'] = country_bias if language: params["lang"] = language url = "?".join((self.geocode_api, urlencode(params))) logger.debug("%s.geocode_api: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), exactly_one)
def reverse( self, query, reverse_geocode_preference=('StreetAddress', ), maximum_responses=25, filtering='', exactly_one=False, timeout=None ): # pylint: disable=W0221,R0913 """ 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 list reverse_geocode_preference: Enable to set expected results type. It can be StreetAddress or PositionOfInterest. Default is set to StreetAddress :param int maximum_responses: The maximum number of responses to ask to the API in the query body. :param string filtering: Provide string that help setting geocoder filter. It contains an XML string. See examples in documentation and ignfrance.py file in directory tests. :param boolean 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. """ sub_request = """ <ReverseGeocodeRequest> {reverse_geocode_preference} <Position> <gml:Point> <gml:pos>{query}</gml:pos> </gml:Point> {filtering} </Position> </ReverseGeocodeRequest> """ xml_request = self.xml_request.format( method_name='ReverseGeocodeRequest', sub_request=sub_request, maximum_responses=maximum_responses ) for pref in reverse_geocode_preference: if pref not in ('StreetAddress', 'PositionOfInterest'): raise GeocoderQueryError( '`reverse_geocode_preference` must contain ' 'one or more of: StreetAddress, PositionOfInterest' ) point = self._coerce_point_to_string(query).replace(',', ' ') reverse_geocode_preference = '\n'.join(( '<ReverseGeocodePreference>%s</ReverseGeocodePreference>' % pref for pref in reverse_geocode_preference )) request_string = xml_request.format( maximum_responses=maximum_responses, query=point, reverse_geocode_preference=reverse_geocode_preference, filtering=filtering ) url = "?".join((self.api, urlencode({'xls': request_string}))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) raw_xml = self._request_raw_content(url, timeout) return self._parse_xml( raw_xml, exactly_one=exactly_one, is_reverse=True, is_freeform='false' )
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'} 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 timezone(self, location, at_time=None, timeout=DEFAULT_SENTINEL): """ **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: int or float or datetime :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: pytz timezone. See :func:`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, distance=None, wkid=DEFAULT_WKID): """ 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 int distance: Distance from the query location, in meters, within which to search. ArcGIS has a default of 100 meters, if not specified. :param str wkid: WKID to use for both input and output coordinates. .. deprecated:: 1.14.0 It wasn't working before because it was specified incorrectly in the request parameters, and won't work even if we fix the request, because :class:`geopy.point.Point` normalizes the coordinates according to WKID 4326. Please open an issue in the geopy issue tracker if you believe that custom wkid values should be supported. This parameter is scheduled for removal in geopy 2.0. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ location = self._coerce_point_to_string(query, "%(lon)s,%(lat)s") if wkid != DEFAULT_WKID: warnings.warn( "%s.reverse: custom wkid value has been ignored. " "It wasn't working before because it was specified " "incorrectly in the request parameters, and won't " "work even if we fix the request, because geopy.Point " "normalizes the coordinates according to WKID %s. " "Please open an issue in the geopy issue tracker " "if you believe that custom wkid values should be " "supported." % (type(self).__name__, DEFAULT_WKID), DeprecationWarning, stacklevel=2) wkid = DEFAULT_WKID params = {'location': location, 'f': 'json', 'outSR': wkid} if distance is not None: params['distance'] = distance url = "?".join((self.reverse_api, urlencode(params))) logger.debug("%s.reverse: %s", self.__class__.__name__, url) response = self._call_geocoder(url, timeout=timeout) if not len(response): return None if 'error' in response: if response['error']['code'] == self._TOKEN_EXPIRED: self.retry += 1 self._refresh_authentication_token() return self.reverse(query, exactly_one=exactly_one, timeout=timeout, distance=distance, wkid=wkid) # https://developers.arcgis.com/rest/geocode/api-reference/geocoding-service-output.htm if response['error']['code'] == 400: # 'details': ['Unable to find address for the specified location.']} try: if 'Unable to find' in response['error']['details'][0]: return None except (KeyError, IndexError): pass raise GeocoderServiceError(str(response['error'])) address = ("%(Address)s, %(City)s, %(Region)s %(Postal)s," " %(CountryCode)s" % response['address']) location = Location( address, (response['location']['y'], response['location']['x']), response['address']) if exactly_one: return location else: return [location]
def geocode(self, query='', street='', city='', state='', zip_cd='', n_matches=1, timeout=60): """ Return a ranked list of locations for an address. :param string query: The single-line address you wish to geocode. :param string street: Optional, Street if not using single-line :param string city: Optional, City :param string state: Optional, State :param string zip_cd: Optional, Zip Code :param int n_matches: Return top n matches. :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 = { 'Single Line Input': query, 'Street': street, 'City': city, 'State': state, 'ZIP': zip_cd, 'f': 'json', 'maxLocations': n_matches } if not (len(query) or len(street)): raise ConfigurationError("Street or Full Address must be entered.") url = "?".join((self.api, urlencode(params))) #print(url) #url = url.encode('utf-8') 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, street, city, state, zip_cd, n_matches, timeout) raise GeocoderServiceError(str(response['error'])) if not len(response['candidates']): return None #TODO geocoded = [] candidate_cnt = 1 for candidate in response['candidates']: geocoded.append({ 'candidate': candidate_cnt, 'attributes': { 'score': candidate['score'], 'match_addr': candidate['address'], 'location': { 'x': candidate['location']['x'], 'y': candidate['location']['y'] } } }) candidate_cnt += 1 return {'candidates': geocoded}
def geocode( self, query, exactly_one=True, timeout=DEFAULT_SENTINEL, proximity=None, country=None, bbox=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 proximity: A coordinate to bias local results based on a provided location. :type proximity: :class:`geopy.point.Point`, list or tuple of ``(latitude, longitude)``, or string as ``"%(latitude)s, %(longitude)s"``. :param country: Country to filter result in form of ISO 3166-1 alpha-2 country code (e.g. ``FR``). Might be a Python list of strings. .. versionchanged:: 1.19.0 Previously only a single string could be specified. Now a Python list of individual countries is supported. :type country: str or list :param bbox: The bounding box of the viewport within which to bias geocode results more prominently. Example: ``[Point(22, 180), Point(-22, -180)]``. :type bbox: list or tuple of 2 items of :class:`geopy.point.Point` or ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = {} params['access_token'] = self.api_key query = self.format_string % query if bbox: params['bbox'] = self._format_bounding_box( bbox, "%(lon1)s,%(lat1)s,%(lon2)s,%(lat2)s") if not country: country = [] if isinstance(country, string_compare): country = [country] if country: params['country'] = ",".join(country) if proximity: p = Point(proximity) params['proximity'] = "%s,%s" % (p.longitude, p.latitude) 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) )
def geocode( self, query, exactly_one=True, timeout=DEFAULT_SENTINEL, proximity=None, language=None, bbox=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 proximity: A coordinate to bias local results based on a provided location. :type proximity: :class:`geopy.point.Point`, list or tuple of ``(latitude, longitude)``, or string as ``"%(latitude)s, %(longitude)s"``. :param language: Prefer results in specific languages. Accepts a single string like ``"en"`` or a list like ``["de", "en"]``. :type language: str or list :param bbox: The bounding box of the viewport within which to bias geocode results more prominently. Example: ``[Point(22, 180), Point(-22, -180)]``. :type bbox: list or tuple of 2 items of :class:`geopy.point.Point` or ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = {'key': self.api_key} query = self.format_string % query if bbox: params['bbox'] = self._format_bounding_box( bbox, "%(lon1)s,%(lat1)s,%(lon2)s,%(lat2)s") if isinstance(language, string_compare): language = [language] if language: params['language'] = ','.join(language) if proximity: p = Point(proximity) params['proximity'] = "%s,%s" % (p.longitude, p.latitude) 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 geocode( self, query, query_type='StreetAddress', maximum_responses=25, is_freeform=False, filtering=None, exactly_one=True, timeout=DEFAULT_SENTINEL, ): """ Return a location point by address. :param str query: The query string to be geocoded. :param str query_type: The type to provide for geocoding. It can be `PositionOfInterest`, `StreetAddress` or `CadastralParcel`. `StreetAddress` is the default choice if none provided. :param int maximum_responses: The maximum number of responses to ask to the API in the query body. :param str is_freeform: Set if return is structured with freeform structure or a more structured returned. By default, value is False. :param str filtering: Provide string that help setting geocoder filter. It contains an XML string. See examples in documentation and ignfrance.py file in directory tests. :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``. """ query = self.format_string % query # Check if acceptable query type if query_type not in [ 'PositionOfInterest', 'StreetAddress', 'CadastralParcel' ]: raise GeocoderQueryError("""You did not provided a query_type the webservice can consume. It should be PositionOfInterest, 'StreetAddress or CadastralParcel""") # Check query validity for CadastralParcel if query_type == 'CadastralParcel' and len(query.strip()) != 14: raise GeocoderQueryError("""You must send a string of fourteen characters long to match the cadastre required code""") sub_request = """ <GeocodeRequest returnFreeForm="{is_freeform}"> <Address countryCode="{query_type}"> <freeFormAddress>{query}</freeFormAddress> {filtering} </Address> </GeocodeRequest> """ xml_request = self.xml_request.format( method_name='LocationUtilityService', sub_request=sub_request, maximum_responses=maximum_responses) # Manage type change for xml case sensitive if is_freeform: is_freeform = 'true' else: is_freeform = 'false' # Manage filtering value if filtering is None: filtering = '' # Create query using parameters request_string = xml_request.format(is_freeform=is_freeform, query=query, query_type=query_type, filtering=filtering) params = {'xls': request_string} url = "?".join((self.api, urlencode(params))) logger.debug("%s.geocode: %s", self.__class__.__name__, url) raw_xml = self._request_raw_content(url, timeout) return self._parse_xml(raw_xml, is_freeform=is_freeform, exactly_one=exactly_one)
def geocode(self, query, exactly_one=True, timeout=None, addressdetails=False, language=False, geometry=None): # pylint: disable=R0913,W0221 """ Geocode a location query. :param query: The address, query or structured query to geocode you wish to geocode. For a structured query, provide a dictionary whose keys are one of: `street`, `city`, `county`, `state`, `country`, or `postalcode`. For more information, see Nominatim's documentation for "structured requests": https://wiki.openstreetmap.org/wiki/Nominatim :type query: dict or string .. versionchanged:: 1.0.0 :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 addressdetails: If you want in *Location.raw* to include addressdetails such as city_district, etc set it to True :type addressdetails: bool :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 :param string geometry: If present, specifies whether the geocoding service should return the result's geometry in `wkt`, `svg`, `kml`, or `geojson` formats. This is available via the `raw` attribute on the returned :class:`geopy.location.Location` object. .. versionadded:: 1.3.0 """ if isinstance(query, dict): params = { key: val for key, val in query.items() if key in self.structured_query_params } else: params = {'q': self.format_string % query} params.update({ # `viewbox` apparently replaces `view_box` 'viewbox': self.view_box, 'format': 'json' }) if self.country_bias: params['countrycodes'] = self.country_bias if addressdetails: params['addressdetails'] = 1 if language: params['accept-language'] = language if geometry is not None: geometry = geometry.lower() if geometry == 'wkt': params['polygon_text'] = 1 elif geometry == 'svg': params['polygon_svg'] = 1 elif geometry == 'kml': params['polygon_kml'] = 1 elif geometry == 'geojson': params['polygon_geojson'] = 1 else: raise GeocoderQueryError( "Invalid geometry format. Must be one of: " "wkt, svg, kml, geojson.") 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, bounds=None, region=None, components=None, language=None, sensor=False, userlocation=None): # pylint: disable=W0221,R0913 """ 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 :param bounds: The bounding box of the viewport within which to bias geocode results more prominently. :type bounds: list or tuple :param string region: The region code, specified as a ccTLD ("top-level domain") two-character value. :param dict components: Restricts to an area. Can use any combination of: route, locality, administrative_area, postal_code, country. .. versionadded:: 0.97.1 :param string language: The language in which to return results. :param bool sensor: Whether the geocoding request comes from a device with a location sensor. """ params = { 'address': self.format_string % query, 'sensor': str(sensor).lower() } if self.api_key: params['key'] = self.api_key if bounds: if len(bounds) != 4: raise GeocoderQueryError( "bounds must be a four-item iterable of lat,lon,lat,lon") params['bounds'] = self._format_bounds_param(bounds) if region: params['region'] = region if components: params['components'] = self._format_components_param(components) if language: params['language'] = language if self.premier is False: url = "?".join((self.api, urlencode(params))) else: url = self._get_signed_url(params) logger.debug("%s.geocode: %s", self.__class__.__name__, url) return self._parse_json(self._call_geocoder(url, timeout=timeout), userlocation, 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 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. The country code is a 2 character code as defined by the ISO-3166-1 alpha-2 standard (e.g. ``FR``). Multiple countries can be specified with a Python list. .. versionchanged:: 1.19.0 Previously only a Python list of countries could be specified. Now a single country as a string can be specified as well. :type country_codes: str or list :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 not country_codes: country_codes = [] if isinstance(country_codes, string_compare): country_codes = [country_codes] if 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 )
def geocode( self, query, max_results=25, set_back=0, location_descriptor='any', exactly_one=True, timeout=None, ): """ Geocode a location query. :param string query: The address or query you wish to geocode. :param int max_results: The maximum number of resutls to request. :param float set_back: The distance to move the accessPoint away from the curb (in meters) and towards the interior of the parcel. location_descriptor must be set to accessPoint for set_back to take effect. :param string location_descriptor: The type of point requested. It can be any, accessPoint, frontDoorPoint, parcelPoint, rooftopPoint and routingPoint. :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 = {'addressString': query} if set_back != 0: params['setBack'] = set_back if location_descriptor not in ['any', 'accessPoint', 'frontDoorPoint', 'parcelPoint', 'rooftopPoint', 'routingPoint']: raise GeocoderQueryError( "You did not provided a location_descriptor " "the webservice can consume. It should be any, accessPoint, " "frontDoorPoint, parcelPoint, rooftopPoint or routingPoint." ) params['locationDescriptor'] = location_descriptor if exactly_one is True: max_results = 1 params['maxResults'] = max_results 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 GeoJSON if not len(response['features']): return None geocoded = [] for feature in response['features']: geocoded.append(self._parse_feature(feature)) if exactly_one is True: return geocoded[0] return geocoded
def geocode_batch(self, addresses, timeout=None, wkid=DEFAULT_WKID): """ Process address dict returning top match only. :param list addresses: List of tuples (uid, address) uid = int, address = sting. :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. """ if not len(addresses): raise ConfigurationError( "Must pass a list of tuples with uid and address.") geocoded = [] for i in xrange(0, len(addresses), 300): records = [] for a in addresses[i:i + 300]: attributes_dict = { "attributes": { "OBJECTID": a[0], "Single Line Input": a[1] } } records.append(attributes_dict) query = {"records": records} params = {'addresses': query, 'outSR': wkid, 'f': 'json'} url = "?".join((self.batch_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(timeout=timeout) raise GeocoderServiceError(str(response['error'])) #add code for parsing output here for location in response['locations']: geocoded.append({ 'uid': location['attributes']['ResultID'], 'attributes': { 'score': location['score'], 'match_addr': location['attributes']['Match_addr'], 'location': { 'x': location['location']['x'], 'y': location['location']['y'] } } }) return {'geocoded': geocoded}
def geocode(self, query, bbox=None, mapview=None, exactly_one=True, maxresults=None, pageinformation=None, language=None, additional_data=False, timeout=DEFAULT_SENTINEL): """ Return a location point by address. This implementation supports only a subset of all available parameters. A list of all parameters of the pure REST API is available here: https://developer.here.com/documentation/geocoder/topics/resource-geocode.html :param str query: The address or query you wish to geocode. For a structured query, provide a dictionary whose keys are one of: `city`, `county`, `district`, `country`, `state`, `street`, `housenumber`, or `postalcode`. :param bbox: A type of spatial filter, limits the search for any other attributes in the request. Specified by two coordinate (lat/lon) pairs -- corners of the box. `The bbox search is currently similar to mapview but it is not extended` (cited from the REST API docs). Relevant global results are also returned. Example: ``[Point(22, 180), Point(-22, -180)]``. :type bbox: list or tuple of 2 items of :class:`geopy.point.Point` or ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``. :param mapview: The app's viewport, given as two coordinate pairs, specified by two lat/lon pairs -- corners of the bounding box, respectively. Matches from within the set map view plus an extended area are ranked highest. Relevant global results are also returned. Example: ``[Point(22, 180), Point(-22, -180)]``. :type mapview: list or tuple of 2 items of :class:`geopy.point.Point` or ``(latitude, longitude)`` or ``"%(latitude)s, %(longitude)s"``. :param bool exactly_one: Return one result or a list of results, if available. :param int maxresults: Defines the maximum number of items in the response structure. If not provided and there are multiple results the HERE API will return 10 results by default. This will be reset to one if ``exactly_one`` is True. :param int pageinformation: A key which identifies the page to be returned when the response is separated into multiple pages. Only useful when ``maxresults`` is also provided. :param str language: Affects the language of the response, must be a RFC 4647 language code, e.g. 'en-US'. :param str additional_data: A string with key-value pairs as described on https://developer.here.com/documentation/geocoder/topics/resource-params-additional.html. These will be added as one query parameter to the URL. :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['app_id'] = self.app_id params['app_code'] = self.app_code else: params = { 'searchtext': self.format_string % query, 'app_id': self.app_id, 'app_code': self.app_code } if bbox: params['bbox'] = self._format_bounding_box( bbox, "%(lat2)s,%(lon1)s;%(lat1)s,%(lon2)s") if mapview: params['mapview'] = self._format_bounding_box( mapview, "%(lat2)s,%(lon1)s;%(lat1)s,%(lon2)s") if pageinformation: params['pageinformation'] = pageinformation if maxresults: params['maxresults'] = maxresults if exactly_one: params['maxresults'] = 1 if language: params['language'] = language if additional_data: params['additionaldata'] = additional_data 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, 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. The order of the coordinates is `longitude,latitude,longitude,latitude`. 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 geocode( self, query, exactly_one=True, timeout=DEFAULT_SENTINEL, type=None, restrict_searchable_attributes=None, limit=None, language=None, countries=None, around=None, around_via_ip=None, around_radius=None, x_forwarded_for=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 str type: Restrict the search results to a specific type. Available types are defined in documentation: https://community.algolia.com/places/api-clients.html#api-options-type :param str restrict_searchable_attributes: Restrict the fields in which the search is done. :param int limit: Limit the maximum number of items in the response. If not provided and there are multiple results Algolia API will return 20 results by default. This will be reset to one if ``exactly_one`` is True. :param str language: If specified, restrict the search results to a single language. You can pass two letters country codes (ISO 639-1). :param list countries: If specified, restrict the search results to a specific list of countries. You can pass two letters country codes (ISO 3166-1). :param around: Force to first search around a specific latitude longitude. :type around: :class:`geopy.point.Point`, list or tuple of ``(latitude, longitude)``, or string as ``"%(latitude)s, %(longitude)s"``. :param bool around_via_ip: Whether or not to first search around the geolocation of the user found via his IP address. This is true by default. :param around_radius: Radius in meters to search around the latitude/longitude. Otherwise a default radius is automatically computed given the area density. :param str x_forwarded_for: Override the HTTP header X-Forwarded-For. With this you can control the source IP address used to resolve the geo-location of the user. This is particularly useful when you want to use the API from your backend as if it was from your end-users' locations. :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = { 'query': self.format_string % query, } if type is not None: params['type'] = type if restrict_searchable_attributes is not None: params[ 'restrictSearchableAttributes'] = restrict_searchable_attributes if limit is not None: params['hitsPerPage'] = limit if exactly_one: params["hitsPerPage"] = 1 if language is not None: params['language'] = language.lower() if countries is not None: params['countries'] = ','.join([c.lower() for c in countries]) if around is not None: p = Point(around) params['aroundLatLng'] = "%s,%s" % (p.latitude, p.longitude) if around_via_ip is not None: params['aroundLatLngViaIP'] = \ 'true' if around_via_ip else 'false' if around_radius is not None: params['aroundRadius'] = around_radius url = '?'.join((self.geocode_api, urlencode(params))) request = Request(url) if x_forwarded_for is not None: request.add_header('X-Forwarded-For', x_forwarded_for) if self.app_id is not None and self.api_key is not None: request.add_header('X-Algolia-Application-Id', self.app_id) request.add_header('X-Algolia-API-Key', self.api_key) logger.debug('%s.geocode: %s', self.__class__.__name__, url) return self._parse_json( self._call_geocoder(request, timeout=timeout), exactly_one, language=language, )
def reverse(self, query, radius=None, exactly_one=True, maxresults=None, pageinformation=None, language=None, mode='retrieveAddresses', timeout=DEFAULT_SENTINEL): """ Return an address by location point. This implementation supports only a subset of all available parameters. A list of all parameters of the pure REST API is available here: https://developer.here.com/documentation/geocoder/topics/resource-reverse-geocode.html :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 float radius: Proximity radius in meters. :param bool exactly_one: Return one result or a list of results, if available. :param int maxresults: Defines the maximum number of items in the response structure. If not provided and there are multiple results the HERE API will return 10 results by default. This will be reset to one if ``exactly_one`` is True. :param int pageinformation: A key which identifies the page to be returned when the response is separated into multiple pages. Only useful when ``maxresults`` is also provided. :param str language: Affects the language of the response, must be a RFC 4647 language code, e.g. 'en-US'. :param str mode: Affects the type of returned response items, must be one of: 'retrieveAddresses' (default), 'retrieveAreas', 'retrieveLandmarks', 'retrieveAll', or 'trackPosition'. See online documentation for more information. :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``. """ point = self._coerce_point_to_string(query) params = { 'app_id': self.app_id, 'app_code': self.app_code, 'mode': mode, 'prox': point, } if radius is not None: params['prox'] = '%s,%s' % (params['prox'], float(radius)) if pageinformation: params['pageinformation'] = pageinformation if maxresults: params['maxresults'] = maxresults if exactly_one: params['maxresults'] = 1 if language: params['language'] = language url = "%s?%s" % (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, query, exactly_one=True, timeout=DEFAULT_SENTINEL, location_bias=None, language=False, limit=None, osm_tag=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 location_bias: The coordinates to used as location bias. :param str language: Preferred language in which to return results. :param int limit: Limit the number of returned results, defaults to no limit. .. versionadded:: 1.12.0 :param osm_tag: The expression to filter (include/exclude) by key and/ or value, str as ``'key:value'`` or list/set of str if multiple filters are required as ``['key:!val', '!key', ':!value']``. :type osm_tag: str or list or set :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ params = {'q': self.format_string % query} if limit: params['limit'] = int(limit) if exactly_one: params['limit'] = 1 if language: params['lang'] = language if location_bias: try: lat, lon = [ x.strip() for x in self._coerce_point_to_string( location_bias).split(',') ] params['lon'] = lon params['lat'] = lat except ValueError: raise ValueError(("Location bias must be a" " coordinate pair or Point")) if osm_tag: if isinstance(osm_tag, string_compare): params['osm_tag'] = [osm_tag] else: if not isinstance(osm_tag, (list, set)): raise ValueError("osm_tag must be a string expression or " "a set/list of string expressions") params['osm_tag'] = osm_tag url = "?".join((self.api, urlencode(params, doseq=True))) 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, limit=None, language=None, ): """ 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 int limit: Limit the maximum number of items in the response. If not provided and there are multiple results Algolia API will return 20 results by default. This will be reset to one if ``exactly_one`` is True. :param str language: If specified, restrict the search results to a single language. You can pass two letters country codes (ISO 639-1). :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if ``exactly_one=False``. """ location = self._coerce_point_to_string(query) params = { 'aroundLatLng': location, } if limit is not None: params['hitsPerPage'] = limit if language is not None: params['language'] = language url = '?'.join((self.reverse_api, urlencode(params))) request = Request(url) if self.app_id is not None and self.api_key is not None: request.add_header('X-Algolia-Application-Id', self.app_id) request.add_header('X-Algolia-API-Key', self.api_key) logger.debug("%s.reverse: %s", self.__class__.__name__, url) return self._parse_json( self._call_geocoder(request, timeout=timeout), exactly_one, language=language, )