usse/scrape/venv/lib/python3.10/site-packages/geopy/geocoders/geolake.py
2023-12-22 15:26:01 +01:00

184 lines
5.4 KiB
Python

import collections.abc
from functools import partial
from urllib.parse import urlencode
from geopy.geocoders.base import DEFAULT_SENTINEL, Geocoder
from geopy.location import Location
from geopy.util import join_filter, logger
__all__ = ("Geolake", )
class Geolake(Geocoder):
"""Geocoder using the Geolake API.
Documentation at:
https://geolake.com/docs/api
Terms of Service at:
https://geolake.com/terms-of-use
"""
structured_query_params = {
'country',
'state',
'city',
'zipcode',
'street',
'address',
'houseNumber',
'subNumber',
}
api_path = '/v1/geocode'
def __init__(
self,
api_key,
*,
domain='api.geolake.com',
scheme=None,
timeout=DEFAULT_SENTINEL,
proxies=DEFAULT_SENTINEL,
user_agent=None,
ssl_context=DEFAULT_SENTINEL,
adapter_factory=None
):
"""
:param str api_key: The API key required by Geolake
to perform geocoding requests. You can get your key here:
https://geolake.com/
:param str domain: Currently it is ``'api.geolake.com'``, can
be changed for testing purposes.
:param str scheme:
See :attr:`geopy.geocoders.options.default_scheme`.
:param int timeout:
See :attr:`geopy.geocoders.options.default_timeout`.
:param dict proxies:
See :attr:`geopy.geocoders.options.default_proxies`.
:param str user_agent:
See :attr:`geopy.geocoders.options.default_user_agent`.
:type ssl_context: :class:`ssl.SSLContext`
:param ssl_context:
See :attr:`geopy.geocoders.options.default_ssl_context`.
:param callable adapter_factory:
See :attr:`geopy.geocoders.options.default_adapter_factory`.
.. versionadded:: 2.0
"""
super().__init__(
scheme=scheme,
timeout=timeout,
proxies=proxies,
user_agent=user_agent,
ssl_context=ssl_context,
adapter_factory=adapter_factory,
)
self.api_key = api_key
self.domain = domain.strip('/')
self.api = '%s://%s%s' % (self.scheme, self.domain, self.api_path)
def geocode(
self,
query,
*,
country_codes=None,
exactly_one=True,
timeout=DEFAULT_SENTINEL
):
"""
Return a location point by address.
:param 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`.
:type query: str or dict
: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.
: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, collections.abc.Mapping):
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': query,
}
if not country_codes:
country_codes = []
if isinstance(country_codes, str):
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)
callback = partial(self._parse_json, exactly_one=exactly_one)
return self._call_geocoder(url, callback, timeout=timeout)
def _parse_json(self, page, exactly_one):
"""Returns location, (latitude, longitude) from json feed."""
if not page.get('success'):
return None
latitude = page['latitude']
longitude = page['longitude']
address = self._get_address(page)
result = Location(address, (latitude, longitude), page)
if exactly_one:
return result
else:
return [result]
def _get_address(self, page):
"""
Returns address string from page dictionary
:param page: dict
:return: str
"""
place = page.get('place')
address_city = place.get('city')
address_country_code = place.get('countryCode')
address = join_filter(', ', [address_city, address_country_code])
return address