1+ from pyowm .commons .http_client import HttpClient
2+ from pyowm .commons .uris import ROOT_GEOCODING_API_URL , DIRECT_GEOCODING_URI , REVERSE_GEOCODING_URI
3+ from pyowm .constants import GEOCODING_API_VERSION
4+ from pyowm .utils import geo
5+ from pyowm .weatherapi25 .location import Location
6+
7+
8+ class GeocodingManager :
9+
10+ """
11+ A manager objects that provides a full interface to OWM Geocoding API.
12+
13+ :param API_key: the OWM API key
14+ :type API_key: str
15+ :param config: the configuration dictionary
16+ :type config: dict
17+ :returns: an *GeocodingManager* instance
18+ :raises: *AssertionError* when no API Key is provided
19+
20+ """
21+
22+ def __init__ (self , API_key , config ):
23+ assert API_key is not None , 'You must provide a valid API Key'
24+ self .API_key = API_key
25+ assert isinstance (config , dict )
26+ self .http_client = HttpClient (API_key , config , ROOT_GEOCODING_API_URL )
27+
28+ def geocoding_api_version (self ):
29+ return GEOCODING_API_VERSION
30+
31+ def geocode (self , toponym , country = None , state_code = None , limit = None ):
32+ """
33+ Invokes the direct geocoding API endpoint
34+
35+ :param toponym: the name of the location
36+ :type toponym: `str`
37+ :param country: the 2-chars ISO symbol of the country
38+ :type country: `str` or `None`
39+ :param state_code: the 2-chars ISO symbol of state (only useful in case the country is US)
40+ :type state_code: `str` or `None`
41+ :param limit: the max number of results to be returned in case of multiple matchings (no limits by default)
42+ :type limit: `int` or `None`
43+ :returns: a list of *Location* instances
44+ :raises: *AssertionError*, *ValueError*, *APIRequestError*
45+
46+ """
47+ assert toponym , 'Toponym must be specified'
48+ if country is not None and len (country ) != 2 :
49+ raise ValueError ("Country must be a 2-char string" )
50+ if state_code is not None and len (state_code ) != 2 :
51+ raise ValueError ("State Code must be a 2-char string" )
52+ if limit is not None :
53+ assert isinstance (limit , int )
54+ assert limit > 0
55+
56+ query = toponym
57+ if state_code is not None :
58+ query += ',' + state_code
59+ if country is not None :
60+ query += ',' + country
61+
62+ params = {'q' : query }
63+
64+ if limit is not None :
65+ params ['limit' ] = limit
66+
67+ _ , json_data = self .http_client .get_json (DIRECT_GEOCODING_URI , params = params )
68+ return [Location .from_dict (item ) for item in json_data ]
69+
70+ def reverse_geocode (self , lat , lon , limit = None ):
71+ geo .assert_is_lon (lon )
72+ geo .assert_is_lat (lat )
73+ if limit is not None :
74+ assert isinstance (limit , int )
75+ assert limit > 0
76+
77+ params = {'lat' : lat , 'lon' : lon }
78+ if limit is not None :
79+ params ['limit' ] = limit
80+
81+ _ , json_data = self .http_client .get_json (REVERSE_GEOCODING_URI , params = params )
82+ return [Location .from_dict (item ) for item in json_data ]
83+
84+ def __repr__ (self ):
85+ return '<%s.%s>' % (__name__ , self .__class__ .__name__ )
0 commit comments