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 |
) |