o
    4c                     @   s   d dl Zd dlZd dlmZ d dlmZ d dlmZ d dl	m
Z
mZ d dlmZmZmZ d dlmZ d dlmZ d	ZG d
d deZdS )    N)partial)	urlencode)AdapterHTTPError)GeocoderQueryErrorGeocoderQuotaExceeded)DEFAULT_SENTINELNONE_RESULTGeocoder)Location)logger)Geocodioc                       s   e Zd ZdZh dZdZdZdZdeededd fdd	
Z	dd
edddZ
d
eddddZdddZdd Zdd Z  ZS )r   zGeocoder using the Geocod.io API.

    Documentation at:
        https://www.geocod.io/docs/

    Pricing details:
        https://www.geocod.io/pricing/

    .. versionadded:: 2.2
    >   citystatestreetcountrypostal_codezapi.geocod.ioz/v1.6/geocodez/v1.6/reverseNschemetimeoutproxies
user_agentssl_contextadapter_factoryc                   s"   t  j||||||d || _dS )a  
        :param str api_key:
            A valid Geocod.io API key. (https://dash.geocod.io/apikey/create)

        :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`.
        r   N)super__init__api_key)selfr   r   r   r   r   r   r   	__class__ N/var/www/html/gps/gps/lib/python3.10/site-packages/geopy/geocoders/geocodio.pyr   '   s   "
zGeocodio.__init__T)limitexactly_oner   c          	         s   t |tjjr fdd| D }nd|i} j|d< |r"||d< |r(d|d< d j j jf }d	|t
|f}td	 jj| t j|d
} j|||dS )a  
        Return a location point by address.

        :param query: The address, query or a structured query
            you wish to geocode.

            For a structured query, provide a dictionary whose keys
            are one of: `street`, `city`, `state`, `postal_code` or `country`.
        :type query: dict or str

        :param int limit: The maximum number of matches to return. This will be reset
            to 1 if ``exactly_one`` is ``True``.

        :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.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.
        c                    s    i | ]\}}| j v r||qS r   )structured_query_params).0keyvalr   r   r    
<dictcomp>u   s    z$Geocodio.geocode.<locals>.<dictcomp>qr   r!      	%s://%s%s?z%s.geocode: %sr"   r   )
isinstancecollectionsabcMappingitemsr   r   domaingeocode_pathjoinr   r   debugr   __name__r   _parse_json_call_geocoder)	r   queryr!   r"   r   paramsapiurlcallbackr   r'   r    geocodeS   s   !

zGeocodio.geocode)r"   r   r!   c          	      C   s   |  || jd}|rd}|dur||d< d| j| j| jf }d|t|f}td| j	j
| t| j|d}| j|||d	S )
a5  Return an address by location point.

        :param str query: The coordinates for which you wish to obtain the
            closest human-readable addresses

        :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 limit: The maximum number of matches to return. This will be reset
            to 1 if ``exactly_one`` is ``True``.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.
        )r)   r   r*   Nr!   r+   r,   z%s.reverse: %sr-   r.   )_coerce_point_to_stringr   r   r4   reverse_pathr6   r   r   r7   r   r8   r   r9   r:   )	r   r;   r"   r   r!   r<   r=   r>   r?   r   r   r    reverse   s   zGeocodio.reversec                    s>   | dg }|s
dS dd  |r |d S  fdd|D S )z7Returns location, (latitude, longitude) from json feed.resultsNc                 S   s2   |  d}| d d }| d d }t|||f| S )z4Get the location, lat, lng from a single json place.formatted_addresslocationlatlng)getr
   )placerF   latitude	longituder   r   r    parse_place   s   
z)Geocodio._parse_json.<locals>.parse_placer   c                    s   g | ]} |qS r   r   )r$   rJ   rM   r   r    
<listcomp>   s    z(Geocodio._parse_json.<locals>.<listcomp>)rI   )r   pager"   placesr   rN   r    r9      s   zGeocodio._parse_jsonc                 C   s   t |tsdS |jdu s|jdu rdS |jdkr0| |}d| v r+d| v r+tS t|||jdkrE| |}d}||v rGt||dS dS )a  Custom exception handling for invalid queries and exceeded quotas.

        Geocod.io returns a ``422`` status code for invalid queries, which is not mapped
        in :const:`~geopy.geocoders.base.ERROR_CODE_MAP`. The service also returns a
        ``403`` status code for exceeded quotas instead of the ``429`` code mapped in
        :const:`~geopy.geocoders.base.ERROR_CODE_MAP`
        Ni  zcould not geocode addresszpostal code or city requiredi  z>You can't make this request as it is above your daily maximum.)	r/   r   status_codetext_get_error_messagelowerr   r   r   )r   errorerror_messagequota_exceeded_snippetr   r   r    _geocoder_exception_handler   s&   








z$Geocodio._geocoder_exception_handlerc                 C   s8   zt |jd}W n ty   d}Y nw |p|jS )zVTry to extract an error message from the 'error' property of a JSON response.
        rV   N)jsonloadsrS   rI   
ValueError)r   rV   rW   r   r   r    rT      s   
zGeocodio._get_error_message)T)r8   
__module____qualname____doc__r#   r4   r5   rB   r   r   r@   rC   r9   rY   rT   __classcell__r   r   r   r    r      s0    0=
+r   )collections.abcr0   rZ   	functoolsr   urllib.parser   geopy.adaptersr   	geopy.excr   r   geopy.geocoders.baser   r   r	   geopy.locationr
   
geopy.utilr   __all__r   r   r   r   r    <module>   s    