o
    4cB                     @   s~   d dl Z d dlm  m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 d dlmZ dZG d	d
 d
eZdS )    N)partial)	urlencode)GeocoderQueryError)DEFAULT_SENTINELGeocoder)Location)logger)	IGNFrancec                       s   e Zd ZdZdZdZ	ddddddeededd
 fddZd	d
dddedddZdd
ddedddZ				dddZ
dddZdd ZdddZ  ZS ) r	   zGeocoder using the IGN France GeoCoder OpenLS API.

    Documentation at:
        https://geoservices.ign.fr/services-web-essentiels
    aK  <?xml version="1.0" encoding="UTF-8"?>
    <XLS version="1.2"
        xmlns="http://www.opengis.net/xls"
        xmlns:gml="http://www.opengis.net/gml"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.opengis.net/xls
        http://schemas.opengis.net/ols/1.2/olsAll.xsd">
        <RequestHeader srsName="epsg:4326"/>
        <Request methodName="{method_name}"
                 maximumResponses="{maximum_responses}"
                 requestID=""
                 version="1.2">
            {sub_request}
        </Request>
    </XLS>z/essentiels/geoportail/olsNz
wxs.ign.fr)
usernamepasswordrefererdomainschemetimeoutproxies
user_agentssl_contextadapter_factoryc       
            sb   t  j||||	|
|d |s|s|s|rtjdtdd |d| _| j}d| j| j|f | _	dS )a=  

        :param str api_key: Not used.

            .. deprecated:: 2.3
                IGNFrance geocoding methods no longer accept or require
                authentication, see `<https://geoservices.ign.fr/actualites/2021-10-04-evolution-des-modalites-dacces-aux-services-web>`_.
                This parameter is scheduled for removal in geopy 3.0.

        :param str username: Not used.

            .. deprecated:: 2.3
                See the `api_key` deprecation note.

        :param str password: Not used.

            .. deprecated:: 2.3
                See the `api_key` deprecation note.

        :param str referer: Not used.

            .. deprecated:: 2.3
                See the `api_key` deprecation note.

        :param str domain: Currently it is ``'wxs.ign.fr'``, can
            be changed for testing purposes for developer API
            e.g ``'gpp3-wxs.ign.fr'`` at the moment.

        :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
        )r   r   r   r   r   r   zIGNFrance no longer accepts or requires authentication, so api_key, username, password and referer are not used anymore. These arguments should be removed. In geopy 3 these options will be removed, causing an error instead of this warning.   )
stacklevel/z	%s://%s%sN)
super__init__warningswarnDeprecationWarningstripr   api_pathr   api)selfapi_keyr
   r   r   r   r   r   r   r   r   r   r   	__class__ O/var/www/html/gps/gps/lib/python3.10/site-packages/geopy/geocoders/ignfrance.pyr   '   s"   @	
zIGNFrance.__init__StreetAddress   FT)
query_typemaximum_responsesis_freeform	filteringexactly_oner   c                C   s   |dvrt d|dkrt| dkrt dd}| jjd||d}	|r(d	}nd
}|du r0d}|	j||||d}
d|
i}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 query string to be geocoded.

        :param str query_type: The type to provide for geocoding. It can be
            `PositionOfInterest`, `StreetAddress` or `CadastralParcel`.
            `StreetAddress` is the default choice if none provided.

        :param int maximum_responses: The maximum number of responses
            to ask to the API in the query body.

        :param str is_freeform: Set if return is structured with
            freeform structure or a more structured returned.
            By default, value is False.

        :param str filtering: Provide string that help setting geocoder
            filter. It contains an XML string. See examples in documentation
            and ignfrance.py file in directory tests.

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

        )PositionOfInterestr%   CadastralParcelzYou did not provided a query_type the
            webservice can consume. It should be PositionOfInterest,
            'StreetAddress or CadastralParcelr-      zfYou must send a string of fourteen
                characters long to match the cadastre required codea*  
                <GeocodeRequest returnFreeForm="{is_freeform}">
                    <Address countryCode="{query_type}">
                        <freeFormAddress>{query}</freeFormAddress>
                        {filtering}
                    </Address>
                </GeocodeRequest>
        LocationUtilityServicemethod_namesub_requestr(   truefalseN )r)   queryr'   r*   xls?z%s.geocode: %s)r)   r+   r   )r   lenr   xml_requestformatjoinr   r   r   debugr"   __name__r   
_parse_xml_request_raw_content)r   r6   r'   r(   r)   r*   r+   r   r2   r;   request_stringparamsurlcallbackr#   r#   r$   geocode   s:   -	zIGNFrance.geocode)r%   r5   )reverse_geocode_preferencer(   r*   r+   r   c                C   s   d}| j jd||d}|D ]
}	|	dvrtdq| |d}
ddd	 |D }|j||
||d
}d| jtd|if}td| j	j
| t| j|ddd}| j|||dS )aU  
        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 list reverse_geocode_preference: Enable to set expected results
            type. It can be `StreetAddress` or `PositionOfInterest`.
            Default is set to `StreetAddress`.

        :param int maximum_responses: The maximum number of responses
            to ask to the API in the query body.

        :param str filtering: Provide string that help setting geocoder
            filter. It contains an XML string. See examples in documentation
            and ignfrance.py file in directory tests.

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

        a@  
            <ReverseGeocodeRequest>
                {reverse_geocode_preference}
                <Position>
                  <gml:Point>
                    <gml:pos>{query}</gml:pos>
                  </gml:Point>
                  {filtering}
                </Position>
            </ReverseGeocodeRequest>
        ReverseGeocodeRequestr0   )r%   r,   z[`reverse_geocode_preference` must contain one or more of: StreetAddress, PositionOfInterestz%(lat)s %(lon)s
c                 s   s    | ]}d | V  qdS )z7<ReverseGeocodePreference>%s</ReverseGeocodePreference>Nr#   ).0prefr#   r#   r$   	<genexpr>)  s
    
z$IGNFrance.reverse.<locals>.<genexpr>)r(   r6   rG   r*   r8   r7   z%s.reverse: %sTr4   )r+   
is_reverser)   r9   )r;   r<   r   _coerce_point_to_stringr=   r   r   r   r>   r"   r?   r   r@   rA   )r   r6   rG   r(   r*   r+   r   r2   r;   rK   pointrB   rD   rE   r#   r#   r$   reverse   s>   *
zIGNFrance.reversec                    sv   t |d}dd }||d ||d ||d j||d}|s&dS |r1j|d	  d
S  fdd|D S )ze
        Returns location, (latitude, longitude) from XML feed
        and transform to json
        zutf-8c                 S   s>   d| }t |}|  D ]}|j|r|j|d |_qdS )z*Remove namespace in the document in place.z{%s}N)r:   itertag
startswith)doc	namespacensnslelemr#   r#   r$   remove_namespaceN  s   z.IGNFrance._parse_xml.<locals>.remove_namespacezhttp://www.opengis.net/gmlzhttp://www.opengis.net/xlszhttp://www.opengis.net/xlsext)rM   Nr   r)   c                    s   g | ]	}j | d qS )rZ   )_parse_place)rJ   placer)   r   r#   r$   
<listcomp>b  s    z(IGNFrance._parse_xml.<locals>.<listcomp>)ET
fromstringencode_xml_to_json_placesr[   )r   pagerM   r)   r+   treerY   placesr#   r]   r$   r@   A  s   



zIGNFrance._parse_xmlc                 C   s  |sdnd}| d| }g }d}|D ])}i }|d|d< |d|d< |d	|d
< ||d|d< ||d|d< ||d|d< ||d|d< ||d|d< ||d|d< ||d|d< ||d|d< ||d|d< ||d|d< ||d|d < ||d!|d"< ||d#|d$< ||d%|d&< |d'|d(< |d)|d*< i }	d+d, }
|
|d-d.|	d.< |
|d-d/|	d0< |
|d1d2|	d3< |
|d4d5|	d6< t| D ]\}}|d7ur
|j|	|< qd7|	|< q|	d r*|	d d8\}}| |	d9< | |	d:< nd7 |	d9< |	d:< |	dd7 |	|	 q|S );zT
        Transform the xml ElementTree due to XML webservice return to json
        GeocodedAddressReverseGeocodedLocationz.//z.//Address/Place[@type="{}"]z./Point/posposz.//Address/StreetAddress/Streetstreetz.//Address/freeFormAddressfreeformaddressMunicipalitymunicipalityNumeronumeroFeuillefeuilleSectionsectionDepartementdepartementCommuneAbsorbeecommune_absorbeeCommunecommuneINSEEinseeQualitequalite
Territoire
territoireIDidID_TRid_trBboxbboxNaturenaturez.//Address/PostalCodepostal_codez.//ExtendedGeocodeMatchCodeextended_geocode_match_codec                 S   s   | dur| j |dS dS )z
                Helper to select by attribute and if not attribute,
                value set to empty string
                N)attribget)selectorkeyr#   r#   r$   testContentAttrib  s   z8IGNFrance._xml_to_json_places.<locals>.testContentAttribz.//GeocodeMatchCodeaccuracy	matchType
match_typez!.//Address/StreetAddress/Buildingnumberbuildingz.//SearchCentreDistancevaluesearch_centre_distanceN latlng)
findallfindr<   rQ   itemstextsplitr   popappend)r   rd   rM   select_multiadressesre   sel_pladrelr\   r   r   r   r   r   r#   r#   r$   rb   i  sp   








zIGNFrance._xml_to_json_placesc                C   s   | j |||ddS )z6
        Send the request to get raw content.
        F)r   is_json)_call_geocoder)r   rD   rE   r   r#   r#   r$   rA     s   zIGNFrance._request_raw_contentc                 C   s   |dkr
| d}n7| dr| d}n,d| dd| ddf }| dr2d	| dd|f }| d
rAd| d
d|f }t|| d| df|S )zP
        Get the location, lat, lng and place from a single json place.
        r3   rj   rn   ri   z%s %sr   r5   rx   z%s, %sr   r   r   )r   r   )r   r\   r)   locationr#   r#   r$   r[     s&   






zIGNFrance._parse_place)N)FFT)F)r?   
__module____qualname____doc__r;   r   r   r   rF   rP   r@   rb   rA   r[   __classcell__r#   r#   r!   r$   r	      sJ    \j^

(Sr	   )r   xml.etree.ElementTreeetreeElementTreer_   	functoolsr   urllib.parser   	geopy.excr   geopy.geocoders.baser   r   geopy.locationr   
geopy.utilr   __all__r	   r#   r#   r#   r$   <module>   s    