예제 #1
0
    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)
예제 #2
0
파일: arcgis.py 프로젝트: GeoRab/geopy
    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
예제 #3
0
    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), )
예제 #4
0
    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
        )
예제 #5
0
파일: arcgis.py 프로젝트: azizur77/geopy
    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
예제 #6
0
파일: arcgis.py 프로젝트: jmb/geopy
 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']
예제 #7
0
파일: baiduv2.py 프로젝트: AdamsLee/geopy
    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)
예제 #8
0
파일: mapquest.py 프로젝트: Kaoring/geopy
    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)
예제 #9
0
 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
     )
예제 #10
0
파일: arcgis.py 프로젝트: akimc/geopy
 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']
예제 #11
0
파일: osm.py 프로젝트: joshz/geopy
    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)
예제 #12
0
파일: osm.py 프로젝트: joshz/geopy
    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)
예제 #13
0
    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
        )
예제 #14
0
파일: opencage.py 프로젝트: TristanH/geopy
    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
        )
예제 #15
0
파일: bing.py 프로젝트: Libermentix/geopy
    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)
예제 #16
0
파일: baidu.py 프로젝트: wangjinlu/geopy
    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
예제 #18
0
파일: yandex.py 프로젝트: mwtoews/geopy
    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,
        )
예제 #19
0
파일: baidu.py 프로젝트: wangjinlu/geopy
    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)
예제 #20
0
파일: baidu.py 프로젝트: risent/geopy
    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)
        )
예제 #21
0
    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,
        )
예제 #22
0
    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)
예제 #23
0
파일: dot_us.py 프로젝트: Libermentix/geopy
    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]
예제 #24
0
파일: geocodefarm.py 프로젝트: jmb/geopy
    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
        )
예제 #25
0
    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
        )
예제 #26
0
파일: osm.py 프로젝트: romaintha/geopy
    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
        )
예제 #27
0
파일: tomtom.py 프로젝트: jmb/geopy
    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
        )
예제 #28
0
파일: pelias.py 프로젝트: jmb/geopy
    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
        )
예제 #29
0
파일: arcgis.py 프로젝트: nh-cadmus/geopy
    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']
예제 #30
0
파일: baidu.py 프로젝트: jmb/geopy
 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)
예제 #31
0
    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)
예제 #32
0
    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)
예제 #33
0
    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)
예제 #35
0
    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')
예제 #36
0
    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)
예제 #37
0
    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)
예제 #38
0
    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
예제 #39
0
    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)
예제 #40
0
    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)
예제 #41
0
    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)
예제 #42
0
    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'
        )
예제 #43
0
    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
예제 #44
0
    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
예제 #45
0
    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]
예제 #46
0
    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}
예제 #47
0
    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)
        )
예제 #48
0
    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)
예제 #49
0
    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)
예제 #50
0
    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)
예제 #51
0
    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)
예제 #52
0
    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
        )
예제 #53
0
    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
예제 #54
0
    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}
예제 #55
0
    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)
예제 #56
0
파일: opencage.py 프로젝트: umbe1987/geopy
    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)
예제 #57
0
    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,
        )
예제 #58
0
    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)
예제 #59
0
    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)
예제 #60
0
    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,
        )