o
    ÔèFhºB  ã                   @   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	   z‰Geocoder 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   zïIGNFrance 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__© úR/var/www/html/loop/nvenv/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%   ÚCadastralParcelz˜You 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|	|< qûd7|	|< 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    