Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / geopy / geocoders / smartystreets.py @ 545

History | View | Annotate | Download (4.27 KB)

1
"""
2
:class:`.LiveAddress` geocoder.
3
"""
4

    
5
from geopy.geocoders.base import Geocoder, DEFAULT_TIMEOUT, DEFAULT_SCHEME
6
from geopy.compat import urlencode
7
from geopy.location import Location
8
from geopy.exc import GeocoderQuotaExceeded
9
from geopy.util import logger
10

    
11

    
12
__all__ = ("LiveAddress", )
13

    
14

    
15
class LiveAddress(Geocoder):  # pylint: disable=W0223
16
    """
17
    Initialize a customized LiveAddress geocoder provided by SmartyStreets.
18
    More information regarding the LiveAddress API can be found here:
19
        https://smartystreets.com/products/liveaddress-api
20
    """
21
    def __init__(
22
            self,
23
            auth_id,
24
            auth_token,
25
            candidates=1,
26
            scheme=DEFAULT_SCHEME,
27
            timeout=DEFAULT_TIMEOUT,
28
            proxies=None
29
        ):  # pylint: disable=R0913
30
        """
31
        Initialize a customized SmartyStreets LiveAddress geocoder.
32

33
        :param string auth_id: Valid `Auth ID` from SmartyStreets.
34

35
            .. versionadded:: 1.5.0
36

37
        :param string auth_token: Valid `Auth Token` from SmartyStreets.
38

39
        :param int candidates: An integer between 1 and 10 indicating the max
40
            number of candidate addresses to return if a valid address
41
            could be found.
42

43
        :param string scheme: Use 'https' or 'http' as the API URL's scheme.
44
            Default is https. Note that SSL connections' certificates are not
45
            verified.
46

47
            .. versionadded:: 0.97
48

49
        :param int timeout: Time, in seconds, to wait for the geocoding service
50
            to respond before raising an :class:`geopy.exc.GeocoderTimedOut`
51
            exception.
52

53
            .. versionadded:: 0.97
54

55
        :param dict proxies: If specified, routes this geocoder's requests
56
            through the specified proxy. E.g., {"https": "192.0.2.0"}. For
57
            more information, see documentation on
58
            :class:`urllib2.ProxyHandler`.
59

60
            .. versionadded:: 0.96
61
        """
62
        super(LiveAddress, self).__init__(
63
            scheme=scheme, timeout=timeout, proxies=proxies
64
        )
65
        self.auth_id = auth_id
66
        self.auth_token = auth_token
67
        if candidates:
68
            if not 1 <= candidates <= 10:
69
                raise ValueError('candidates must be between 1 and 10')
70
        self.candidates = candidates
71
        self.api = '%s://api.smartystreets.com/street-address' % self.scheme
72

    
73
    def geocode(self, query, exactly_one=True, timeout=None):  # pylint: disable=W0221
74
        """
75
        Geocode a location query.
76

77
        :param string query: The address or query you wish to geocode.
78

79
        :param bool exactly_one: Return one result or a list of results, if
80
            available.
81
        """
82
        url = self._compose_url(query)
83
        logger.debug("%s.geocode: %s", self.__class__.__name__, url)
84
        return self._parse_json(self._call_geocoder(url, timeout=timeout),
85
                                exactly_one)
86

    
87
    def _geocoder_exception_handler(self, error, message): # pylint: disable=R0201,W0613
88
        """
89
        LiveStreets-specific exceptions.
90
        """
91
        if "no active subscriptions found" in message.lower():
92
            raise GeocoderQuotaExceeded(message)
93

    
94
    def _compose_url(self, location):
95
        """
96
        Generate API URL.
97
        """
98
        query = {
99
            'auth-id': self.auth_id,
100
            'auth-token': self.auth_token,
101
            'street': location,
102
            'candidates': self.candidates
103
        }
104
        return '{url}?{query}'.format(url=self.api, query=urlencode(query))
105

    
106
    def _parse_json(self, response, exactly_one=True):
107
        """
108
        Parse responses as JSON objects.
109
        """
110
        if not len(response):
111
            return None
112
        if exactly_one is True:
113
            return self._format_structured_address(response[0])
114
        else:
115
            return [self._format_structured_address(c) for c in response]
116

    
117
    @staticmethod
118
    def _format_structured_address(address):
119
        """
120
        Pretty-print address and return lat, lon tuple.
121
        """
122
        latitude = address['metadata'].get('latitude')
123
        longitude = address['metadata'].get('longitude')
124
        return Location(
125
            ", ".join((address['delivery_line_1'], address['last_line'])),
126
            (latitude, longitude) if latitude and longitude else None,
127
            address
128
        )