Example #1
0
 def _parse_reverse_result(self, result):
     latitude, longitude = result['position'].split(',')
     return Location(result['address']['freeformAddress'],
                     (latitude, longitude), result)
Example #2
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
Example #3
0
 def test_location_ne(self):
     loc1 = Location(GRAND_CENTRAL_STR, GRAND_CENTRAL_POINT, {})
     loc2 = Location(GRAND_CENTRAL_STR, Point(0, 0), {})
     self.assertNotEqual(loc1, loc2)
Example #4
0
 def _parse_search_result(self, result):
     latitude = result['position']['lat']
     longitude = result['position']['lon']
     return Location(result['address']['freeformAddress'],
                     (latitude, longitude), result)
Example #5
0
 def test_location_len(self):
     loc = Location(GRAND_CENTRAL_STR, GRAND_CENTRAL_POINT, {})
     self.assertEqual(len(loc), 2)
Example #6
0
 def test_location_eq(self):
     loc1 = Location(GRAND_CENTRAL_STR, GRAND_CENTRAL_POINT, {})
     loc2 = Location(GRAND_CENTRAL_STR, GRAND_CENTRAL_COORDS_TUPLE, {})
     self.assertEqual(loc1, loc2)
Example #7
0
 def test_location_raw(self):
     loc = Location(GRAND_CENTRAL_STR,
                    GRAND_CENTRAL_POINT,
                    raw=GRAND_CENTRAL_RAW)
     self._location_properties_test(loc, GRAND_CENTRAL_RAW)
Example #8
0
def locations(draw):
    resp = draw(googleResponses())
    asPoint = Point(resp['geometry']['location']['lat'],
                    resp['geometry']['location']['lng'])
    return Location(resp['formatted_address'], asPoint, resp)
Example #9
0
 def test_location_array_access(self):
     loc = Location(GRAND_CENTRAL_STR, GRAND_CENTRAL_COORDS_TUPLE, {})
     self.assertEqual(loc[0], GRAND_CENTRAL_STR)
     self.assertEqual(loc[1][0], GRAND_CENTRAL_COORDS_TUPLE[0])
     self.assertEqual(loc[1][1], GRAND_CENTRAL_COORDS_TUPLE[1])
Example #10
0
 def test_location_properties(self):
     loc = Location(GRAND_CENTRAL_STR, GRAND_CENTRAL_POINT, {})
     self._location_properties_test(loc)
Example #11
0
 def test_location_point_typeerror(self):
     with self.assertRaises(TypeError):
         Location(GRAND_CENTRAL_STR, 1, {})
Example #12
0
 def test_location_iter(self):
     loc = Location(GRAND_CENTRAL_STR, GRAND_CENTRAL_COORDS_TUPLE, {})
     self._location_iter_test(loc)
     self.assertEqual(loc.point, GRAND_CENTRAL_POINT)
Example #13
0
 def test_location_none(self):
     with self.assertRaises(TypeError):
         Location(GRAND_CENTRAL_STR, None, {})
Example #14
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)
            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]
Example #15
0
 def test_location_string(self):
     loc = Location(GRAND_CENTRAL_STR, GRAND_CENTRAL_POINT, {})
     self.assertEqual(str(loc), loc.address)
Example #16
0
 def parse_place(place):
     '''Get the location, lat, lng from a single json place.'''
     location = place.get('formatted_address')
     latitude = place['geometry']['location']['lat']
     longitude = place['geometry']['location']['lng']
     return Location(location, (latitude, longitude), place)
Example #17
0
 def _parse_code(self, feature):
     # Parse each resource.
     latitude = feature.get('geometry', {}).get('coordinates', [])[1]
     longitude = feature.get('geometry', {}).get('coordinates', [])[0]
     placename = feature.get('properties', {}).get('name')
     return Location(placename, (latitude, longitude), feature)