a
    }cS0                     @   s   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m	Z	 d dl
mZmZmZ d dlmZ d dlmZ d	Zd
ZG dd deZdS )    N)partial)time)	urlencode)ConfigurationErrorGeocoderAuthenticationFailureGeocoderServiceError)DEFAULT_SENTINELGeocoder_synchronized)Location)logger)ArcGISi  c                       s   e Zd ZdZdZdZdZdZddddeededdd	d

 fddZ	deddddZ
dd ZdeddddZdd ZedddZedd Z  ZS )r   zGeocoder using the ERSI ArcGIS API.

    Documentation at:
        https://developers.arcgis.com/rest/geocode/api-reference/overview-world-geocoding-service.htm
    i  z/sharing/generateTokenz?/arcgis/rest/services/World/GeocodeServer/findAddressCandidatesz8/arcgis/rest/services/World/GeocodeServer/reverseGeocodeN<   zwww.arcgis.comzgeocode.arcgis.com)
referertoken_lifetimeschemetimeoutproxies
user_agentssl_contextadapter_factoryauth_domaindomainc       
            s   t  j|||||	|
d |s$|s$|rJ|r0|r0|s8td| jdkrJtd|| _|| _|| _|d| _d| j| j| j	f | _
|d | _|d| _d| j| j| jf | _d| j| j| jf | _d| _d| _dS )	a  

        :param str username: ArcGIS username. Required if authenticated
            mode is desired.

        :param str password: ArcGIS password. Required if authenticated
            mode is desired.

        :param str referer: Required if authenticated mode is desired.
            `Referer` HTTP header to send with each request,
            e.g., ``'http://www.example.com'``. This is tied to an issued token,
            so fielding queries for multiple referrers should be handled by
            having multiple ArcGIS geocoder instances.

        :param int token_lifetime: Desired lifetime, in minutes, of an
            ArcGIS-issued token.

        :param str scheme:
            See :attr:`geopy.geocoders.options.default_scheme`.
            If authenticated mode is in use, it must be ``'https'``.

        :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 auth_domain: Domain where the target ArcGIS auth service
            is hosted. Used only in authenticated mode (i.e. username,
            password and referer are set).

        :param str domain: Domain where the target ArcGIS service
            is hosted.
        )r   r   r   r   r   r   z;Authenticated mode requires username, password, and refererhttpsz-Authenticated mode requires scheme of 'https'/z	%s://%s%sr   N)super__init__r   r   usernamepasswordr   stripr   	auth_pathauth_apir   r   geocode_pathapireverse_pathreverse_apitokentoken_expiry)selfr   r   r   r   r   r   r   r   r   r   r   r   	__class__ R/var/www/html/django/DPS/env/lib/python3.9/site-packages/geopy/geocoders/arcgis.pyr   !   s>    >

zArcGIS.__init__T)exactly_oner   
out_fieldsc                C   s   |dd}|rd|d< |dur@t |tr2||d< nd||d< d| jt|f}td	| jj| t	| j
|d
}| j|||dS )am  
        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 out_fields: A list of output fields to be returned in the
            attributes field of the raw data. This can be either a python
            list/tuple of fields or a comma-separated string. See
            https://developers.arcgis.com/rest/geocode/api-reference/geocoding-service-output.htm
            for a list of supported output fields. If you want to return all
            supported output fields, set ``out_fields="*"``.
        :type out_fields: str or iterable

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.
        json)Z
singleLinef   ZmaxLocationsNZ	outFields,?z%s.geocode: %sr-   r   )
isinstancestrjoinr#   r   r   debugr*   __name__r   _parse_geocode_authenticated_call_geocoder)r(   queryr-   r   r.   paramsurlcallbackr+   r+   r,   geocode   s    


zArcGIS.geocodec                 C   st   d|v rt t|d t|d s(d S g }|d D ].}|d }|t|d |d |d f| q4|rp|d S |S )Nerror
candidateslocationaddressyxr   )r   r7   lenappendr   )r(   responser-   ZgeocodedresourceZgeometryr+   r+   r,   r;      s    zArcGIS._parse_geocode)r-   r   distancec          
      C   sp   |  |d}t}|d|d}|dur,||d< d| jt|f}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 int distance: Distance from the query location, in meters,
            within which to search. ArcGIS has a default of 100 meters, if not
            specified.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.
        z%(lon)s,%(lat)sr/   )rD   r0   ZoutSRNrL   r3   z%s.reverse: %sr4   r5   )Z_coerce_point_to_stringDEFAULT_WKIDr8   r%   r   r   r9   r*   r:   r   _parse_reverser<   )
r(   r=   r-   r   rL   rD   Zwkidr>   r?   r@   r+   r+   r,   reverse   s    zArcGIS.reversec              	   C   s   t |sd S d|v rj|d d dkrZzd|d d d v r@W d S W n ttfyX   Y n0 tt|d |d drd	|d  }n|d d
 }t||d d |d d f|d }|r|S |gS d S )NrB   codei  zUnable to finddetailsr   rE   ZAddressz=%(Address)s, %(City)s, %(Region)s %(Postal)s, %(CountryCode)sZ	LongLabelrD   rF   rG   )rH   KeyError
IndexErrorr   r7   getr   )r(   rJ   r-   rE   rD   r+   r+   r,   rN      s0    
zArcGIS._parse_reverser5   c                   s   j sjdS  fdd}fdd fddjd u sftt jkrxj|jdS | S d S )	Nr5   c                     s>   d tdjif} dji}j| t jd|dS )N&r&   Referer)
from_tokenr   headers)r8   r   r&   r   _call_geocoderr   Zcall_urlrY   )maybe_reauthenticate_callbackr(   r   r?   r+   r,   query_callback  s    
z;ArcGIS._authenticated_call_geocoder.<locals>.query_callbackc                   s2   d| v r*| d d j kr*j|dS  | S )NrB   rP   r   rW   )_TOKEN_EXPIRED_refresh_authentication_token)rJ   rW   )parse_callbackquery_retry_callbackr(   r   r+   r,   r\     s    zJArcGIS._authenticated_call_geocoder.<locals>.maybe_reauthenticate_callbackc                     s4   d tdjif} dji}j|  |dS )NrU   r&   rV   rX   )r8   r   r&   r   rZ   r[   )ra   r(   r   r?   r+   r,   rb     s
    
zAArcGIS._authenticated_call_geocoder.<locals>.query_retry_callbackr^   )r   rZ   r&   intr   r'   r`   )r(   r?   ra   r   r]   r+   )r\   ra   rb   r(   r   r?   r,   r<     s    
z#ArcGIS._authenticated_call_geocoderc                   sn   |j kr  S jjjjdd}djt|ft	dj
j  fdd}j||dS )Nr/   )r   r   r   Z
expirationr0   r3   z$%s._refresh_authentication_token: %sc                    s@   d| vrt dt| f | d _tt j _  S )Nr&   z@Missing token in auth request.Request URL: %s; response JSON: %s)r   r/   dumpsr&   rc   r   r   r'   )rJ   callback_successr(   r?   r+   r,   cb>  s    
z0ArcGIS._refresh_authentication_token.<locals>.cbr5   )r&   r   r   r   r   r8   r!   r   r   r9   r*   r:   rZ   )r(   rf   r   rW   Ztoken_request_argumentsrg   r+   re   r,   r`   +  s    

z$ArcGIS._refresh_authentication_token)NN)r:   
__module____qualname____doc__r_   r    r"   r$   r   r   rA   r;   rO   rN   r<   r
   r`   __classcell__r+   r+   r)   r,   r      s>     g'#!&r   )r/   	functoolsr   r   urllib.parser   Z	geopy.excr   r   r   Zgeopy.geocoders.baser   r	   r
   Zgeopy.locationr   Z
geopy.utilr   __all__rM   r   r+   r+   r+   r,   <module>   s   