o
    4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|r%|r|r|std| jdkr%t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__ L/var/www/html/gps/gps/lib/python3.10/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r||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)
singleLinef   maxLocationsN	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| q|r8|d S |S )Nerror
candidateslocationaddressyxr   )r   r:   lenappendr   )r(   responser-   geocodedresource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/   )rG   r1   outSRNrQ   r6   z%s.reverse: %sr7   r8   )_coerce_point_to_stringDEFAULT_WKIDr;   r%   r   r   r<   r*   r=   r   _parse_reverser?   )
r(   r@   r-   r   rQ   rG   wkidrA   rB   rC   r+   r+   r,   reverse   s   zArcGIS.reversec              	   C   s   t |sd S d|v r5|d d dkr-zd|d d d v r W d S W n ttfy,   Y nw tt|d |d drCd	|d  }n|d d
 }t||d d |d d f|d }|r_|S |gS )NrE   codei  zUnable to finddetailsr   rH   Addressz=%(Address)s, %(City)s, %(Region)s %(Postal)s, %(CountryCode)s	LongLabelrG   rI   rJ   )rK   KeyError
IndexErrorr   r:   getr   )r(   rM   r-   rH   rG   r+   r+   r,   rU      s4   zArcGIS._parse_reverser8   c                   s~   j sjdS  fdd}fdd fddjd u s3tt jkr<j|jdS | S )	Nr8   c                     s>   d tdjif} dji}j| t jd|dS )N&r&   Referer)
from_tokenr   headers)r;   r   r&   r   _call_geocoderr   call_urlrc   )maybe_reauthenticate_callbackr(   r   rB   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 )NrE   rX   r   ra   )_TOKEN_EXPIRED_refresh_authentication_token)rM   ra   )parse_callbackquery_retry_callbackr(   r   r+   r,   rg     s   zJArcGIS._authenticated_call_geocoder.<locals>.maybe_reauthenticate_callbackc                     s4   d tdjif} dji}j|  |dS )Nr_   r&   r`   rb   )r;   r   r&   r   rd   re   )rl   r(   r   rB   r+   r,   rm     s
   
zAArcGIS._authenticated_call_geocoder.<locals>.query_retry_callbackri   )r   rd   r&   intr   r'   rk   )r(   rB   rl   r   rh   r+   )rg   rl   rm   r(   r   rB   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   
expirationr1   r6   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&   rn   r   r   r'   )rM   callback_successr(   rB   r+   r,   cb>  s   
z0ArcGIS._refresh_authentication_token.<locals>.cbr8   )r&   r   r   r   r   r;   r!   r   r   r<   r*   r=   rd   )r(   rr   r   ra   token_request_argumentsrs   r+   rq   r,   rk   +  s   

z$ArcGIS._refresh_authentication_token)NN)r=   
__module____qualname____doc__rj   r    r"   r$   r   r   rD   r>   rW   rU   r?   r
   rk   __classcell__r+   r+   r)   r,   r      s@    g'#!&r   )r/   	functoolsr   r   urllib.parser   	geopy.excr   r   r   geopy.geocoders.baser   r	   r
   geopy.locationr   
geopy.utilr   __all__rT   r   r+   r+   r+   r,   <module>   s    