a
    î}cº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(|r8t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)ÚselfZapi_keyr
   r   r   r   r   r   r   r   r   r   r   ©Ú	__class__© úU/var/www/html/django/DPS/env/lib/python3.9/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r0t| ¡ ƒdkr0t dƒ‚d}| jjd||d}	|rPd	}nd
}|du r`d}|	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>
        Z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   r4   r&   r'   r(   r)   r*   r   r0   r9   Úrequest_stringÚparamsÚurlÚcallbackr"   r"   r#   Úgeocode   s:    -	ýüÿÿzIGNFrance.geocode)r$   r3   )Ú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>
        ZReverseGeocodeRequestr.   )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'   r4   rE   r)   r6   r5   z%s.reverse: %sTr2   )r*   Ú
is_reverser(   r7   )r9   r:   r   Z_coerce_point_to_stringr;   r   r   r   r<   r!   r=   r   r>   r?   )r   r4   rE   r'   r)   r*   r   r0   r9   rH   Úpointr@   rB   rC   r"   r"   r#   Úreverseå   s<    *ýÿ
ýüüzIGNFrance.reversec                    sz   t  | d¡¡}dd„ }||dƒ ||dƒ ||dƒ ˆj||d}|sLdS |rbˆj|d	 ˆ d
S ‡ ‡fdd„|D ƒS 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)r8   ÚiterÚtagÚ
startswith)ÚdocÚ	namespaceÚnsZ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)rJ   Nr   ©r(   c                    s   g | ]}ˆj |ˆ d ‘qS )rU   )Ú_parse_place)rG   Úplace©r(   r   r"   r#   Ú
<listcomp>b  s
   ýþz(IGNFrance._parse_xml.<locals>.<listcomp>)ÚETZ
fromstringÚencodeÚ_xml_to_json_placesrV   )r   ÚpagerJ   r(   r*   ÚtreerT   Úplacesr"   rX   r#   r>   A  s    



üzIGNFrance._parse_xmlc                 C   s‚  |sdnd}|  d| ¡}g }d}|D ]T}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|	|< nd7|	|< qö|	d rV|	d  d8¡\}}| ¡ |	d9< | ¡ |	d:< nd7 |	d9< |	d:< |	 dd7¡ | 	|	¡ q&|S );zT
        Transform the xml ElementTree due to XML webservice return to json
        ZGeocodedAddressZReverseGeocodedLocationz.//z.//Address/Place[@type="{}"]z./Point/posÚposz.//Address/StreetAddress/StreetÚstreetz.//Address/freeFormAddressÚfreeformaddressZMunicipalityZmunicipalityZNumeroÚnumeroZFeuilleZfeuilleZSectionÚsectionZDepartementZdepartementZCommuneAbsorbeeZcommune_absorbeeZCommuneÚcommuneZINSEEZinseeZQualiteZqualiteZ
TerritoireZ
territoireZIDÚidZID_TRZid_trZBboxZbboxZNatureZnaturez.//Address/PostalCodeÚpostal_codez.//ExtendedGeocodeMatchCodeZ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)ZattribÚget)ÚselectorÚkeyr"   r"   r#   ÚtestContentAttrib’  s    ýþýz8IGNFrance._xml_to_json_places.<locals>.testContentAttribz.//GeocodeMatchCodeZaccuracyZ	matchTypeZ
match_typez!.//Address/StreetAddress/BuildingÚnumberÚbuildingz.//SearchCentreDistanceÚvalueZsearch_centre_distanceNú ÚlatÚlng)
ÚfindallÚfindr:   rM   ÚitemsÚtextÚsplitr   ÚpopÚappend)r   r^   rJ   Zselect_multiZadressesr_   Zsel_plZadrÚelrW   rk   rj   rn   rp   rq   r"   r"   r#   r\   i  sp    ÿý
ÿ

ÿ
ÿ
ÿ
ÿ

zIGNFrance._xml_to_json_placesc                C   s   | j |||ddS )z6
        Send the request to get raw content.
        F)r   Zis_json)Z_call_geocoder)r   rB   rC   r   r"   r"   r#   r?   ¼  s    üzIGNFrance._request_raw_contentc                 C   sž   |dkr|  d¡}nn|  d¡r*|  d¡}nXd|  dd¡|  dd¡f }|  d¡rdd	|  dd¡|f }|  d
¡r‚d|  d
d¡|f }t||  d¡|  d¡f|ƒS )zP
        Get the location, lat, lng and place from a single json place.
        r1   rb   rc   ra   z%s %srg   r3   re   z%s, %srm   rp   rq   )rh   r   )r   rW   r(   Úlocationr"   r"   r#   rV   Ç  s&    


þ

þ

þzIGNFrance._parse_place)N)FFT)F)N)r=   Ú
__module__Ú__qualname__Ú__doc__r9   r   r   r   rD   rL   r>   r\   r?   rV   Ú__classcell__r"   r"   r    r#   r	      sH    þó\÷jø^   ü
(
Sr	   )r   Zxml.etree.ElementTreeÚetreeZElementTreerZ   Ú	functoolsr   Úurllib.parser   Z	geopy.excr   Zgeopy.geocoders.baser   r   Zgeopy.locationr   Z
geopy.utilr   Ú__all__r	   r"   r"   r"   r#   Ú<module>   s   