o
    Pf[                     @   sH  d Z ddlZddlmZ ddlmZmZmZmZm	Z	m
Z
mZ ddlmZmZmZmZ ddlmZ ddlmZmZ ddlmZmZmZmZmZmZmZ G d	d
 d
eZG dd deZG dd deZ G dd deZ!G dd deZ"G dd deZ#G dd deZ$G dd deZ%G dd deZ&G dd deZ'G dd deZ(dS )z
Classes for drawing maps.

    N)OrderedDict)DictListOptionalSequenceTupleTypeUnion)ElementFigureHtmlMacroElement)Template)ElementAddToElementEventHandler)JsCode
TypeBoundsTypeJsonValuecamelizeescape_backticksparse_optionsvalidate_locationc                   @   s   e Zd ZdZdefddZdS )Eventeda:  The base class for Layer and Map

    Adds the `on` method for event handling capabilities.

    See https://leafletjs.com/reference.html#evented for
    more in depth documentation. Please note that we have
    only added the `on(<Object> eventMap)` variant of this
    method using python keyword arguments.
    	event_mapc                 K   s&   |  D ]\}}| t|| qd S N)items	add_childr   )selfr   
event_typehandler r    V/home/deployuser/azure_apps/autowriter/venv/lib/python3.10/site-packages/folium/map.pyon$   s   z
Evented.onN)__name__
__module____qualname____doc__r   r"   r    r    r    r!   r      s    
r   c                	       sL   e Zd ZdZ				ddee dededef fd	d
Z fddZ  Z	S )Layera:  An abstract class for everything that is a Layer on the map.
    It will be used to define whether an object will be included in
    LayerControls.

    Parameters
    ----------
    name : string, default None
        The name of the Layer, as it will appear in LayerControls
    overlay : bool, default False
        Adds the layer as an optional overlay (True) or the base layer (False).
    control : bool, default True
        Whether the Layer will be included in LayerControls.
    show: bool, default True
        Whether the layer will be shown on opening.
    NFTnameoverlaycontrolshowc                    s6   t    |d ur|n|  | _|| _|| _|| _d S r   )super__init__get_name
layer_namer)   r*   r+   )r   r(   r)   r*   r+   	__class__r    r!   r-   :   s
   

zLayer.__init__c                    sD   | j r| jt|  | j d|  d d t jdi | d S )N)element_nameelement_parent_name_addr(   r    )r+   r   r   r.   _parentr,   render)r   kwargsr0   r    r!   r7   G   s   
zLayer.render)NFTT)
r#   r$   r%   r&   r   strboolr-   r7   __classcell__r    r    r0   r!   r'   )   s     r'   c                       sL   e Zd ZdZedZ				ddee dededed	e	f
 fd
dZ
  ZS )FeatureGroupau  
    Create a FeatureGroup layer ; you can put things in it and handle them
    as a single layer.  For example, you can add a LayerControl to
    tick/untick the whole group.

    Parameters
    ----------
    name : str, default None
        The name of the featureGroup layer.
        It will be displayed in the LayerControl.
        If None get_name() will be called to get the technical (ugly) name.
    overlay : bool, default True
        Whether your layer will be an overlay (ticked with a check box in
        LayerControls) or a base layer (ticked with a radio button).
    control: bool, default True
        Whether the layer will be included in LayerControls.
    show: bool, default True
        Whether the layer will be shown on opening.
    **kwargs
        Additional (possibly inherited) options. See
        https://leafletjs.com/reference.html#featuregroup

    z
        {% macro script(this, kwargs) %}
            var {{ this.get_name() }} = L.featureGroup(
                {{ this.options|tojson }}
            );
        {% endmacro %}
        NTr(   r)   r*   r+   r8   c                    sD   t  j||||d d| _|d ur|n|  | _tdi || _d S )N)r(   r)   r*   r+   r<   r    )r,   r-   _namer.   	tile_namer   options)r   r(   r)   r*   r+   r8   r0   r    r!   r-   v   s   zFeatureGroup.__init__)NTTT)r#   r$   r%   r&   r   	_templater   r9   r:   r   r-   r;   r    r    r0   r!   r<   S   s(    r<   c                       s`   e Zd ZdZedZ				ddededed	ed
ef
 fddZ	dddZ
d fddZ  ZS )LayerControla  
    Creates a LayerControl object to be added on a folium map.

    This object should be added to a Map object. Only Layer children
    of Map are included in the layer control.

    Note
    ----
    The LayerControl should be added last to the map.
    Otherwise, the LayerControl and/or the controlled layers may not appear.

    Parameters
    ----------
    position : str
          The position of the control (one of the map corners), can be
          'topleft', 'topright', 'bottomleft' or 'bottomright'
          default: 'topright'
    collapsed : bool, default True
          If true the control will be collapsed into an icon and expanded on
          mouse hover or touch.
    autoZIndex : bool, default True
          If true the control assigns zIndexes in increasing order to all of
          its layers so that the order is preserved when switching them on/off.
    draggable: bool, default False
          By default the layer control has a fixed position. Set this argument
          to True to allow dragging the control around.
    **kwargs
        Additional (possibly inherited) options. See
        https://leafletjs.com/reference.html#control-layers

    a  
        {% macro script(this,kwargs) %}
            var {{ this.get_name() }}_layers = {
                base_layers : {
                    {%- for key, val in this.base_layers.items() %}
                    {{ key|tojson }} : {{val}},
                    {%- endfor %}
                },
                overlays :  {
                    {%- for key, val in this.overlays.items() %}
                    {{ key|tojson }} : {{val}},
                    {%- endfor %}
                },
            };
            let {{ this.get_name() }} = L.control.layers(
                {{ this.get_name() }}_layers.base_layers,
                {{ this.get_name() }}_layers.overlays,
                {{ this.options|tojson }}
            ).addTo({{this._parent.get_name()}});

            {%- if this.draggable %}
            new L.Draggable({{ this.get_name() }}.getContainer()).enable();
            {%- endif %}

        {% endmacro %}
        toprightTFposition	collapsed
autoZIndex	draggabler8   c                    sB   t    d| _td|||d|| _|| _t | _t | _d S )NrA   )rC   rD   rE   r    )	r,   r-   r=   r   r?   rF   r   base_layersoverlays)r   rC   rD   rE   rF   r8   r0   r    r!   r-      s   
zLayerControl.__init__returnNc                 C   s   t  | _t  | _d S r   )r   rG   rH   r   r    r    r!   reset   s   zLayerControl.resetc                    sd   |    | jj D ] }t|tr|jsq
|j}|js#|	 | j
|< q
|	 | j|< q
t   dS )/Renders the HTML representation of the element.N)rK   r6   	_childrenvalues
isinstancer'   r*   r/   r)   r.   rG   rH   r,   r7   )r   r8   itemkeyr0   r    r!   r7      s   zLayerControl.render)rB   TTFrI   N)r#   r$   r%   r&   r   r@   r9   r:   r   r-   rK   r7   r;   r    r    r0   r!   rA      s,     
rA   c                       sV   e Zd ZdZedZh dZ					dd	ed
edededede	f fddZ
  ZS )Icona]  
    Creates an Icon object that will be rendered
    using Leaflet.awesome-markers.

    Parameters
    ----------
    color : str, default 'blue'
        The color of the marker. You can use:

            ['red', 'blue', 'green', 'purple', 'orange', 'darkred',
             'lightred', 'beige', 'darkblue', 'darkgreen', 'cadetblue',
             'darkpurple', 'white', 'pink', 'lightblue', 'lightgreen',
             'gray', 'black', 'lightgray']

    icon_color : str, default 'white'
        The color of the drawing on the marker. You can use colors above,
        or an html color code.
    icon : str, default 'info-sign'
        The name of the marker sign.
        See Font-Awesome website to choose yours.
        Warning : depending on the icon you choose you may need to adapt
        the `prefix` as well.
    angle : int, default 0
        The icon will be rotated by this amount of degrees.
    prefix : str, default 'glyphicon'
        The prefix states the source of the icon. 'fa' for font-awesome or
        'glyphicon' for bootstrap 3.

    https://github.com/lvoogdt/Leaflet.awesome-markers

    a  
        {% macro script(this, kwargs) %}
            var {{ this.get_name() }} = L.AwesomeMarkers.icon(
                {{ this.options|tojson }}
            );
            {{ this._parent.get_name() }}.setIcon({{ this.get_name() }});
        {% endmacro %}
        >   redbluegraypinkbeigeblackgreenwhiteorangepurpledarkreddarkbluelightred	cadetblue	darkgreen	lightblue	lightgray
darkpurple
lightgreenrU   r[   	info-signr   	glyphiconcolor
icon_coloriconangleprefixr8   c                    sX   t    d| _|| jvrtjd| j ddd td||||d| d|| _d S )	NrS   z)color argument of Icon should be one of: .   )
stacklevelz
fa-rotate-)marker_colorrj   rk   rm   extra_classesr    )r,   r-   r=   color_optionswarningswarnr   r?   )r   ri   rj   rk   rl   rm   r8   r0   r    r!   r-   &  s    
	
zIcon.__init__)rU   r[   rg   r   rh   )r#   r$   r%   r&   r   r@   rs   r9   intr   r-   r;   r    r    r0   r!   rS      s0     
rS   c                       s   e Zd ZdZedZ					ddeee  de	de
df de	d	e
df d
ee dedef fddZdeee  fddZd fddZ  ZS )Markera]  
    Create a simple stock Leaflet marker on the map, with optional
    popup text or Vincent visualization.

    Parameters
    ----------
    location: tuple or list
        Latitude and Longitude of Marker (Northing, Easting)
    popup: string or folium.Popup, default None
        Label for the Marker; either an escaped HTML string to initialize
        folium.Popup or a folium.Popup instance.
    tooltip: str or folium.Tooltip, default None
        Display a text when hovering over the object.
    icon: Icon plugin
        the Icon plugin to use to render the marker.
    draggable: bool, default False
        Set to True to be able to drag the marker around the map.

    Returns
    -------
    Marker names and HTML in obj.template_vars

    Examples
    --------
    >>> Marker(location=[45.5, -122.3], popup="Portland, OR")
    >>> Marker(location=[45.5, -122.3], popup=Popup("Portland, OR"))
    # If the popup label has characters that need to be escaped in HTML
    >>> Marker(
    ...     location=[45.5, -122.3],
    ...     popup=Popup("Mom & Pop Arrow Shop >>", parse_html=True),
    ... )
    a  
        {% macro script(this, kwargs) %}
            var {{ this.get_name() }} = L.marker(
                {{ this.location|tojson }},
                {{ this.options|tojson }}
            ).addTo({{ this._parent.get_name() }});
        {% endmacro %}
        NFlocationpopupPopuptooltipTooltiprk   rF   r8   c                    s   t    d| _|d urt|nd | _td|pd |pd d|| _|d ur.| | || _|d urB| t	|t
r;|nt
t| |d urX| t	|trO|ntt| d S d S )Nrw   )rF   autoPanr    )r,   r-   r=   r   rx   r   r?   r   rk   rO   rz   r9   r|   )r   rx   ry   r{   rk   rF   r8   r0   r    r!   r-   m  s$   
	
 zMarker.__init__rI   c                 C   s   | j dusJ | j | j gS )zyComputes the bounds of the object itself.

        Because a marker has only single coordinates, we repeat them.
        N)rx   rJ   r    r    r!   _get_self_bounds  s   zMarker._get_self_boundsc                    s(   | j d u rt| j dt   d S )Nz6 location must be assigned when added directly to map.)rx   
ValueErrorr=   r,   r7   rJ   r0   r    r!   r7     s
   

zMarker.render)NNNNFrR   )r#   r$   r%   r&   r   r@   r   r   floatr	   r9   rS   r:   r   r-   r   r~   r7   r;   r    r    r0   r!   rw   @  s2    !
rw   c                       sp   e Zd ZdZedZ						ddeeedf de	deee
f d	e	d
e	de	def fddZdddZ  ZS )rz   a  Create a Popup instance that can be linked to a Layer.

    Parameters
    ----------
    html: string or Element
        Content of the Popup.
    parse_html: bool, default False
        True if the popup is a template that needs to the rendered first.
    max_width: int for pixels or text for percentages, default '100%'
        The maximal width of the popup.
    show: bool, default False
        True renders the popup open on page load.
    sticky: bool, default False
        True prevents map and other popup clicks from closing.
    lazy: bool, default False
        True only loads the Popup content when clicking on the Marker.
    aG  
        var {{this.get_name()}} = L.popup({{ this.options|tojson }});

        {% for name, element in this.html._children.items() %}
            {% if this.lazy %}
                {{ this._parent.get_name() }}.once('click', function() {
                    {{ this.get_name() }}.setContent($(`{{ element.render(**kwargs).replace('\n',' ') }}`)[0]);
                });
            {% else %}
                var {{ name }} = $(`{{ element.render(**kwargs).replace('\n',' ') }}`)[0];
                {{ this.get_name() }}.setContent({{ name }});
            {% endif %}
        {% endfor %}

        {{ this._parent.get_name() }}.bindPopup({{ this.get_name() }})
        {% if this.show %}.openPopup(){% endif %};

        {% for name, element in this.script._children.items() %}
            {{element.render()}}
        {% endfor %}
    NF100%html
parse_html	max_widthr+   stickylazyr8   c           	         s   t    d| _t | _t | _t | _| | j_| | j_| | j_| }t|tr/| j	| nt|t
rBt|}| j	t||d || _|| _td||sO|rQdnd |rVdnd d|| _d S )Nrz   )scriptF)r   	autoClosecloseOnClickr    )r,   r-   r=   r
   headerr   r   r6   rO   r   r9   r   r   r+   r   r   r?   )	r   r   r   r   r+   r   r   r8   r   r0   r    r!   r-     s.   




zPopup.__init__rI   c                 K   sf   | j  D ]\}}|jdi | q|  }t|tsJ d|jjt| j	j| |d| 
 d dS )rL   z8You cannot render this Element if it is not in a Figure.)thisr8   r5   Nr    )rM   r   r7   get_rootrO   r   r   r   r
   r@   r.   )r   r8   r(   childfigurer    r    r!   r7     s   
zPopup.render)NFr   FFFrR   )r#   r$   r%   r&   r   r@   r	   r9   r
   r:   rv   r   r-   r7   r;   r    r    r0   r!   rz     s6    
%rz   c                
       s   e Zd ZU dZedZefefefefefefe	e
fefefd	Zeeeedf f ed< 		dded	ee d
edef fddZdeeef deeef fddZ  ZS )r|   a~  
    Create a tooltip that shows text when hovering over its parent object.

    Parameters
    ----------
    text: str
        String to display as a tooltip on the object. If the argument is of a
        different type it will be converted to str.
    style: str, default None.
        HTML inline style properties like font and colors. Will be applied to
        a div with the text in it.
    sticky: bool, default True
        Whether the tooltip should follow the mouse.
    **kwargs
        These values will map directly to the Leaflet Options. More info
        available here: https://leafletjs.com/reference.html#tooltip

    aK  
        {% macro script(this, kwargs) %}
            {{ this._parent.get_name() }}.bindTooltip(
                `<div{% if this.style %} style={{ this.style|tojson }}{% endif %}>
                     {{ this.text }}
                 </div>`,
                {{ this.options|tojson }}
            );
        {% endmacro %}
        )	paneoffset	direction	permanentr   interactiveopacityattribution	className.valid_optionsNTtextstyler   r8   c                    sX   t    d| _t|| _|d|i | || _|r*t|ts%J d|| _	d S d S )Nr|   r   z8Pass a valid inline HTML style property string to style.)
r,   r-   r=   r9   r   updater   r?   rO   r   )r   r   r   r   r8   r0   r    r!   r-   "  s   


zTooltip.__init__rI   c                 C   sv   dd |  D }| D ]+}|| jv s J d|d| jt|| | j| s8J d| d| j|  dq|S )z?Validate the provided kwargs and return options as json string.c                 S   s   i | ]	\}}t ||qS r    )r   ).0rQ   valuer    r    r!   
<dictcomp>=  s    z)Tooltip.parse_options.<locals>.<dictcomp>z2The option {} is not in the available options: {}.z, zThe option z% must be one of the following types: rn   )r   keysr   formatjoinrO   )r   r8   rQ   r    r    r!   r   8  s   zTooltip.parse_options)NT)r#   r$   r%   r&   r   r@   r9   tupler:   r   rv   r   r   r   r   __annotations__r   r   r-   r   r;   r    r    r0   r!   r|     s>   
 

r|   c                       sd   e Zd ZdZedZ				ddedeee	  deee	  deee	  dee
 f
 fd	d
Z  ZS )	FitBoundsa  Fit the map to contain a bounding box with the
    maximum zoom level possible.

    Parameters
    ----------
    bounds: list of (latitude, longitude) points
        Bounding box specified as two points [southwest, northeast]
    padding_top_left: (x, y) point, default None
        Padding in the top left corner. Useful if some elements in
        the corner, such as controls, might obscure objects you're zooming
        to.
    padding_bottom_right: (x, y) point, default None
        Padding in the bottom right corner.
    padding: (x, y) point, default None
        Equivalent to setting both top left and bottom right padding to
        the same value.
    max_zoom: int, default None
        Maximum zoom to be used.
    z
        {% macro script(this, kwargs) %}
            {{ this._parent.get_name() }}.fitBounds(
                {{ this.bounds|tojson }},
                {{ this.options|tojson }}
            );
        {% endmacro %}
        Nboundspadding_top_leftpadding_bottom_rightpaddingmax_zoomc                    s,   t    d| _|| _t||||d| _d S )Nr   )r   r   r   r   )r,   r-   r=   r   r   r?   )r   r   r   r   r   r   r0   r    r!   r-   j  s   
zFitBounds.__init__)NNNN)r#   r$   r%   r&   r   r@   r   r   r   r   rv   r-   r;   r    r    r0   r!   r   J  s(    


r   c                	       sH   e Zd ZdZedZ				ddedee d	ed
ef fddZ	  Z
S )FitOverlaysa  Fit the bounds of the maps to the enabled overlays.

    Parameters
    ----------
    padding: int, default 0
        Amount of padding in pixels applied in the corners.
    max_zoom: int, optional
        The maximum possible zoom to use when fitting to the bounds.
    fly: bool, default False
        Use a smoother, longer animation.
    fit_on_map_load: bool, default True
        Apply the fit when initially loading the map.
    a  
        {% macro script(this, kwargs) %}
        function customFlyToBounds() {
            let bounds = L.latLngBounds([]);
            {{ this._parent.get_name() }}.eachLayer(function(layer) {
                if (typeof layer.getBounds === 'function') {
                    bounds.extend(layer.getBounds());
                }
            });
            if (bounds.isValid()) {
                {{ this._parent.get_name() }}.{{ this.method }}(bounds, {{ this.options|tojson }});
            }
        }
        {{ this._parent.get_name() }}.on('overlayadd', customFlyToBounds);
        {%- if this.fit_on_map_load %}
        customFlyToBounds();
        {%- endif %}
        {% endmacro %}
    r   NFTr   r   flyfit_on_map_loadc                    s:   t    d| _|rdnd| _|| _t||f|d| _d S )Nr   flyToBounds	fitBounds)r   r   )r,   r-   r=   methodr   r   r?   )r   r   r   r   r   r0   r    r!   r-     s
   
zFitOverlays.__init__)r   NFT)r#   r$   r%   r&   r   r@   rv   r   r:   r-   r;   r    r    r0   r!   r   }  s$    r   c                       sD   e Zd ZdZedZ		d
dedeeef de	f fdd	Z
  ZS )
CustomPanean  
    Creates a custom pane to hold map elements.

    Behavior is as in https://leafletjs.com/examples/map-panes/

    Parameters
    ----------
    name: string
        Name of the custom pane. Other map elements can be added
        to the pane by specifying the 'pane' kwarg when constructing
        them.
    z_index: int or string, default 625
        The z-index that will be associated with the pane, and will
        determine which map elements lie over/under it. The default
        (625) corresponds to between markers and tooltips. Default
        panes and z-indexes can be found at
        https://leafletjs.com/reference.html#map-pane
    pointer_events: bool, default False
        Whether or not layers in the pane should interact with the
        cursor. Setting to False will prevent interfering with
        pointer events associated with lower layers.
    a  
        {% macro script(this, kwargs) %}
            var {{ this.get_name() }} = {{ this._parent.get_name() }}.createPane(
                {{ this.name|tojson }});
            {{ this.get_name() }}.style.zIndex = {{ this.z_index|tojson }};
            {% if not this.pointer_events %}
                {{ this.get_name() }}.style.pointerEvents = 'none';
            {% endif %}
        {% endmacro %}
        q  Fr(   z_indexpointer_eventsc                    s&   t    d| _|| _|| _|| _d S )NPane)r,   r-   r=   r(   r   r   )r   r(   r   r   r0   r    r!   r-     s
   

zCustomPane.__init__)r   F)r#   r$   r%   r&   r   r@   r9   r	   rv   r:   r-   r;   r    r    r0   r!   r     s    
r   ))r&   rt   collectionsr   typingr   r   r   r   r   r   r	   branca.elementr
   r   r   r   jinja2r   folium.elementsr   r   folium.utilitiesr   r   r   r   r   r   r   r   r'   r<   rA   rS   rw   rz   r|   r   r   r   r    r    r    r!   <module>   s&    $$*1a[V`T33