o
    ÔèFhc1  ã                   @   sˆ   d dl mZ d dlmZ d dlmZmZmZmZm	Z	 d dl
mZmZ d dlmZ d dlmZmZmZ d dlmZ dZG d	d
„ d
eƒZdS )é    )Úpartial)Ú	urlencode)ÚGeocoderAuthenticationFailureÚGeocoderInsufficientPrivilegesÚGeocoderQueryErrorÚGeocoderQuotaExceededÚGeocoderServiceError)ÚDEFAULT_SENTINELÚGeocoder)ÚLocation)Úensure_pytz_is_installedÚfrom_fixed_gmt_offsetÚfrom_timezone_name)Úlogger)ÚGeoNamesc                       s¢   e Zd ZdZdZdZdZdZeededddd	œ‡ fd
d„
Z	dedddœdd„Z
deddddœdd„Zdd„ Zdd„ Zedœdd„Zdd„ Zdd„ Zdd „ Z‡  ZS )!r   zàGeoNames geocoder.

    Documentation at:
        http://www.geonames.org/export/geonames-search.html

    Reverse geocoding documentation at:
        http://www.geonames.org/export/web-services.html#findNearbyPlaceName
    z/searchJSONz/findNearbyPlaceNameJSONz/findNearbyJSONz/timezoneJSONNÚhttpzapi.geonames.org)ÚtimeoutÚproxiesÚ
user_agentÚssl_contextÚadapter_factoryÚschemeÚdomainc          	         sr   t ƒ j||||||d� || _d| j|| jf | _d| j|| jf | _d| j|| jf | _	d| j|| j
f | _dS )aÇ  

        :param str username: GeoNames username, required. Sign up here:
            http://www.geonames.org/login

        :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

        :param str scheme:
            See :attr:`geopy.geocoders.options.default_scheme`. Note that
            at the time of writing GeoNames doesn't support `https`, so
            the default scheme is `http`. The value of
            :attr:`geopy.geocoders.options.default_scheme` is not respected.
            This parameter is present to make it possible to switch to
            `https` once GeoNames adds support for it.

        :param str domain: base api domain

            .. versionadded:: 2.4
        )r   r   r   r   r   r   z	%s://%s%sN)ÚsuperÚ__init__Úusernamer   Úgeocode_pathÚapiÚreverse_pathÚapi_reverseÚreverse_nearby_pathÚapi_reverse_nearbyÚtimezone_pathÚapi_timezone)	Úselfr   r   r   r   r   r   r   r   ©Ú	__class__© úQ/var/www/html/loop/nvenv/lib/python3.10/site-packages/geopy/geocoders/geonames.pyr   &   s"   /úÿÿÿÿzGeoNames.__init__T)Úexactly_oner   ÚcountryÚcountry_biasc          
      C   s¦   d|fd| j fg}|r| d|f¡ |sg }t|tƒr|g}|D ]	}| d|f¡ q |r1| d¡ d | jt|ƒf¡}t d| j	j
|¡ t| j|d�}	| j||	|d	�S )
aÞ  
        Return a location point by address.

        :param str query: The address or query you wish to geocode.

        :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 country: Limit records to the specified countries.
            Two letter country code ISO-3166 (e.g. ``FR``). Might be
            a single string or a list of strings.
        :type country: str or list

        :param str country_bias: Records from the country_bias are listed first.
            Two letter country code ISO-3166.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.
        Úqr   ÚcountryBiasr*   )ÚmaxRowsé   ú?z%s.geocode: %s©r)   ©r   )r   ÚappendÚ
isinstanceÚstrÚjoinr   r   r   Údebugr&   Ú__name__r   Ú_parse_jsonÚ_call_geocoder)
r$   Úqueryr)   r   r*   r+   ÚparamsÚcountry_itemÚurlÚcallbackr'   r'   r(   Úgeocodel   s"   "þ

zGeoNames.geocodeÚfindNearbyPlaceName)r)   r   Úfeature_codeÚlangÚfind_nearby_typec                C   sà   z|   |¡ d¡\}}W n ty   tdƒ‚w |dkr5|r"tdƒ‚| j|||d�}	d | jt|	ƒf¡}
n#|dkrR|r?tdƒ‚| j|||d	�}	d | jt|	ƒf¡}
nt	d
| ƒ‚t
 d| jj|
¡ t| j|d�}| j|
||d�S )aä  
        Return an address by location point.

        :param query: The coordinates for which you wish to obtain the
            closest human-readable addresses.
        :type query: :class:`geopy.point.Point`, list or tuple of ``(latitude,
            longitude)``, or string as ``"%(latitude)s, %(longitude)s"``.

        :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 str feature_code: A GeoNames feature code

        :param str lang: language of the returned ``name`` element (the pseudo
            language code 'local' will return it in local language)
            Full list of supported languages can be found here:
            https://www.geonames.org/countries/

        :param str find_nearby_type: A flag to switch between different
            GeoNames API endpoints. The default value is ``findNearbyPlaceName``
            which returns the closest populated place. Another currently
            implemented option is ``findNearby`` which returns
            the closest toponym for the lat/lng query.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.

        ú,ú"Must be a coordinate pair or PointrA   zMfind_nearby_type=findNearbyPlaceName doesn't support the `feature_code` param)ÚlatÚlngrC   r0   Ú
findNearbyz<find_nearby_type=findNearby doesn't support the `lang` param)rG   rH   rB   z/`%s` find_nearby_type is not supported by geopyz%s.reverse: %sr1   r2   )Ú_coerce_point_to_stringÚsplitÚ
ValueErrorÚ&_reverse_find_nearby_place_name_paramsr6   r   r   Ú_reverse_find_nearby_paramsr!   r   r   r7   r&   r8   r   r9   r:   )r$   r;   r)   r   rB   rC   rD   rG   rH   r<   r>   r?   r'   r'   r(   Úreverse£   sB   ,ÿÿýÿýÿzGeoNames.reversec                 C   ó   ||| j dœ}|r||d< |S )N©rG   rH   r   ÚfeatureCode©r   )r$   rG   rH   rB   r<   r'   r'   r(   rN   ô   ó   ýz$GeoNames._reverse_find_nearby_paramsc                 C   rP   )NrQ   rC   rS   )r$   rG   rH   rC   r<   r'   r'   r(   rM   þ   rT   z/GeoNames._reverse_find_nearby_place_name_paramsr2   c                C   s|   t ƒ  z|  |¡ d¡\}}W n ty   tdƒ‚w ||| jdœ}d | jt|ƒf¡}t 	d| j
j|¡ | j|| j|d�S )aO  
        Find the timezone for a point in `query`.

        GeoNames always returns a timezone: if the point being queried
        doesn't have an assigned Olson timezone id, a ``pytz.FixedOffset``
        timezone is used to produce the :class:`geopy.timezone.Timezone`.

        :param query: The coordinates for which you want a timezone.
        :type query: :class:`geopy.point.Point`, list or tuple of (latitude,
            longitude), or string as "%(latitude)s, %(longitude)s"

        :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: :class:`geopy.timezone.Timezone`.
        rE   rF   rQ   r0   z%s.reverse_timezone: %sr2   )r   rJ   rK   rL   r   r6   r#   r   r   r7   r&   r8   r:   Ú_parse_json_timezone)r$   r;   r   rG   rH   r<   r>   r'   r'   r(   Úreverse_timezone  s   ÿýzGeoNames.reverse_timezonec                 C   s\   |  d¡}|r,|d }|d }| d¡rt|ƒ‚|dkr t|ƒ‚|dv r(t|ƒ‚t|ƒ‚d S )NÚstatusÚvalueÚmessagezuser account not enabled to useé
   )é   é   é   )ÚgetÚ
startswithr   r   r   r   )r$   ÚbodyÚerrÚcoderY   r'   r'   r(   Ú_raise_for_error-  s   

özGeoNames._raise_for_errorc                 C   s<   |   |¡ | d¡}|d u r|d }t||d�S t||d�S )NÚ
timezoneIdÚ	rawOffset)Úraw)rc   r^   r   r   )r$   ÚresponseÚtimezone_idÚ
raw_offsetr'   r'   r(   rU   ;  s   

zGeoNames._parse_json_timezonec                    sL   |  dg ¡}|  |¡ t|ƒsdS dd„ ‰ |rˆ |d ƒS ‡ fdd„|D ƒS )z+
        Parse JSON response body.
        ÚgeonamesNc                 S   s‚   |   dd¡}|   dd¡}|r|rt|ƒ}t|ƒ}ndS |   d¡}|   dd¡}|   dd¡}d dd	„ |||fD ƒ¡}t|||f| ƒS )
z,
            Parse each record.
            rG   NrH   ÚnameÚ
adminName1ÚcountryNamez, c                 S   s   g | ]}|r|‘qS r'   r'   )Ú.0Úxr'   r'   r(   Ú
<listcomp>c  ó    z<GeoNames._parse_json.<locals>.parse_code.<locals>.<listcomp>)r^   Úfloatr6   r   )ÚplaceÚlatitudeÚ	longitudeÚ	placenameÚstater*   Úlocationr'   r'   r(   Ú
parse_codeR  s   

ÿz(GeoNames._parse_json.<locals>.parse_coder   c                    s   g | ]}ˆ |ƒ‘qS r'   r'   )rn   rs   ©ry   r'   r(   rp   k  rq   z(GeoNames._parse_json.<locals>.<listcomp>)r^   rc   Úlen)r$   Údocr)   Úplacesr'   rz   r(   r9   I  s   
zGeoNames._parse_json)r8   Ú
__module__Ú__qualname__Ú__doc__r   r   r    r"   r	   r   r@   rO   rN   rM   rV   rc   rU   r9   Ú__classcell__r'   r'   r%   r(   r      s>    	öJù;øQ

%r   N)Ú	functoolsr   Úurllib.parser   Ú	geopy.excr   r   r   r   r   Úgeopy.geocoders.baser	   r
   Úgeopy.locationr   Úgeopy.timezoner   r   r   Ú
geopy.utilr   Ú__all__r   r'   r'   r'   r(   Ú<module>   s    