o
    Pf.                     @   sZ   d dl mZmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
mZ G dd deeZdS )	    )ElementFigure)Template)
JSCSSMixin)Layer)none_maxnone_minc                       sr   e Zd ZdZedZg dZdgZ								
		
	
									d fdd	Z fddZ	dd Z
  ZS )HeatMapWithTimea	  
    Create a HeatMapWithTime layer

    Parameters
    ----------
    data: list of list of points of the form [lat, lng] or [lat, lng, weight]
        The points you want to plot. The outer list corresponds to the various time
        steps in sequential order. (weight is in (0, 1] range and defaults to 1 if
        not specified for a point)
    index: Index giving the label (or timestamp) of the elements of data. Should have
        the same length as data, or is replaced by a simple count if not specified.
    name : string, default None
        The name of the Layer, as it will appear in LayerControls.
    radius: default 15.
        The radius used around points for the heatmap.
    blur: default 0.8.
        Blur strength used for the heatmap. Must be between 0 and 1.
    min_opacity: default 0
        The minimum opacity for the heatmap.
    max_opacity: default 0.6
        The maximum opacity for the heatmap.
    scale_radius: default False
        Scale the radius of the points based on the zoom level.
    gradient: dict, default None
        Match point density values to colors. Color can be a name ('red'),
        RGB values ('rgb(255,0,0)') or a hex number ('#FF0000').
    use_local_extrema: default False
        Defines whether the heatmap uses a global extrema set found from the input data
        OR a local extrema (the maximum and minimum of the currently displayed view).
    auto_play: default False
        Automatically play the animation across time.
    display_index: default True
        Display the index (usually time) in the time control.
    index_steps: default 1
        Steps to take in the index dimension between animation steps.
    min_speed: default 0.1
        Minimum fps speed for animation.
    max_speed: default 10
        Maximum fps speed for animation.
    speed_step: default 0.1
        Step between different fps speeds on the speed slider.
    position: default 'bottomleft'
        Position string for the time slider. Format: 'bottom/top'+'left/right'.
    overlay : bool, default True
        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.

    a  
        {% macro script(this, kwargs) %}

            var times = {{this.times}};

            {{this._parent.get_name()}}.timeDimension = L.timeDimension(
                {times : times, currentTime: new Date(1)}
            );

            var {{this._control_name}} = new L.Control.TimeDimensionCustom({{this.index}}, {
                autoPlay: {{this.auto_play}},
                backwardButton: {{this.backward_button}},
                displayDate: {{this.display_index}},
                forwardButton: {{this.forward_button}},
                limitMinimumRange: {{this.limit_minimum_range}},
                limitSliders: {{this.limit_sliders}},
                loopButton: {{this.loop_button}},
                maxSpeed: {{this.max_speed}},
                minSpeed: {{this.min_speed}},
                playButton: {{this.play_button}},
                playReverseButton: {{this.play_reverse_button}},
                position: "{{this.position}}",
                speedSlider: {{this.speed_slider}},
                speedStep: {{this.speed_step}},
                styleNS: "{{this.style_NS}}",
                timeSlider: {{this.time_slider}},
                timeSliderDrapUpdate: {{this.time_slider_drap_update}},
                timeSteps: {{this.index_steps}}
                })
                .addTo({{this._parent.get_name()}});

                var {{this.get_name()}} = new TDHeatmap({{this.data}},
                {heatmapOptions: {
                        radius: {{this.radius}},
                        blur: {{this.blur}},
                        minOpacity: {{this.min_opacity}},
                        maxOpacity: {{this.max_opacity}},
                        scaleRadius: {{this.scale_radius}},
                        useLocalExtrema: {{this.use_local_extrema}},
                        defaultWeight: 1,
                        {% if this.gradient %}gradient: {{ this.gradient }}{% endif %}
                    }
                });

        {% endmacro %}
        ))iso8601zChttps://cdn.jsdelivr.net/npm/iso8601-js-period@0.2.1/iso8601.min.js)zleaflet.timedimension.min.jszZhttps://cdn.jsdelivr.net/npm/leaflet-timedimension@1.1.1/dist/leaflet.timedimension.min.js)zheatmap.min.jszVhttps://cdn.jsdelivr.net/gh/python-visualization/folium/folium/templates/pa7_hm.min.js)zleaflet-heatmap.jsz^https://cdn.jsdelivr.net/gh/python-visualization/folium/folium/templates/pa7_leaflet_hm.min.js)z%leaflet.timedimension.control.min.cssz_https://cdn.jsdelivr.net/npm/leaflet-timedimension@1.1.1/dist/leaflet.timedimension.control.cssN   皙?r   333333?FT   皙?
   
bottomleftc                    sF  t  j||||d d| _|  d | _|| _|d ur|ndd tdt|d D | _t| jt| jkr:t	dt
tdt|d | _|| _|| _|| _|| _|rVdnd	| _|
r]dnd	| _|	| _|rgdnd	| _|rndnd	| _|| _|| _|| _|| _|| _d| _d| _d| _d
| _d| _d| _d| _ d| _!d| _"d	| _#d| _$d S )N)nameoverlaycontrolshowHeatMapControlc                 S   s   g | ]}t |qS  )str).0ir   r   l/home/deployuser/azure_apps/autowriter/venv/lib/python3.10/site-packages/folium/plugins/heat_map_withtime.py
<listcomp>   s    z,HeatMapWithTime.__init__.<locals>.<listcomp>r   z3Input data and index are not of compatible lengths.truefalse   zleaflet-control-timecontrol)%super__init___nameget_name_control_namedatarangelenindex
ValueErrorlisttimesradiusblurmin_opacitymax_opacityscale_radiususe_local_extremagradient	auto_playdisplay_index	min_speed	max_speedposition
speed_stepindex_stepsbackward_buttonforward_buttonlimit_sliderslimit_minimum_rangeloop_buttonspeed_slidertime_sliderplay_buttonplay_reverse_buttontime_slider_drap_updatestyle_NS)selfr&   r)   r   r-   r.   r/   r0   r1   r3   r2   r4   r5   r:   r6   r7   r9   r8   r   r   r   	__class__r   r   r"      sH   &
zHeatMapWithTime.__init__c                    sD   t  jdi | |  }t|tsJ d|jtddd d S )Nz8You cannot render this Element if it is not in a Figure.a  
            <script>
                var TDHeatmap = L.TimeDimension.Layer.extend({

            initialize: function(data, options) {
                var heatmapCfg = {
                    radius: 15,
                    blur: 0.8,
                    maxOpacity: 1.,
                    scaleRadius: false,
                    useLocalExtrema: false,
                    latField: 'lat',
                    lngField: 'lng',
                    valueField: 'count',
                    defaultWeight : 1,
                };
                heatmapCfg = $.extend({}, heatmapCfg, options.heatmapOptions || {});
                var layer = new HeatmapOverlay(heatmapCfg);
                L.TimeDimension.Layer.prototype.initialize.call(this, layer, options);
                this._currentLoadedTime = 0;
                this._currentTimeData = {
                    data: []
                    };
                this.data= data;
                this.defaultWeight = heatmapCfg.defaultWeight || 1;
            },
            onAdd: function(map) {
                L.TimeDimension.Layer.prototype.onAdd.call(this, map);
                map.addLayer(this._baseLayer);
                if (this._timeDimension) {
                    this._getDataForTime(this._timeDimension.getCurrentTime());
                }
            },
            _onNewTimeLoading: function(ev) {
                this._getDataForTime(ev.time);
                return;
            },
            isReady: function(time) {
                return (this._currentLoadedTime == time);
            },
            _update: function() {
                this._baseLayer.setData(this._currentTimeData);
                return true;
            },
            _getDataForTime: function(time) {
                    delete this._currentTimeData.data;
                    this._currentTimeData.data = [];
                    var data = this.data[time-1];
                    for (var i = 0; i < data.length; i++) {
                        this._currentTimeData.data.push({
                                lat: data[i][0],
                                lng: data[i][1],
                                count: data[i].length>2 ? data[i][2] : this.defaultWeight
                            });
                        }
                    this._currentLoadedTime = time;
                    if (this._timeDimension && time == this._timeDimension.getCurrentTime() && !this._timeDimension.isLoading()) {
                        this._update();
                    }
                    this.fire('timeload', {
                        time: time
                    });
                }
        });

        L.Control.TimeDimensionCustom = L.Control.TimeDimension.extend({
            initialize: function(index, options) {
                var playerOptions = {
                    buffer: 1,
                    minBufferReady: -1
                    };
                options.playerOptions = $.extend({}, playerOptions, options.playerOptions || {});
                L.Control.TimeDimension.prototype.initialize.call(this, options);
                this.index = index;
                },
            _getDisplayDateFormat: function(date){
                return this.index[date.getTime()-1];
                }
            });
            </script>
                timeControlScript)template_namer   )r!   renderget_root
isinstancer   header	add_childr   )rF   kwargsfigurerG   r   r   rK      s   QzHeatMapWithTime.renderc                 C   sx   ddgddgg}| j D ].}t|d d |d t|d d |d gt|d d |d t|d d |d gg}q|S )z
        Computes the bounds of the object itself (not including it's children)
        in the form [[lat_min, lon_min], [lat_max, lon_max]].

        Nr   r   )r&   r   r   )rF   boundspointr   r   r   _get_self_bounds,  s   

z HeatMapWithTime._get_self_bounds)NNr   r   r   r   FNFFTr   r   r   r   r   TTT)__name__
__module____qualname____doc__r   	_template
default_jsdefault_cssr"   rK   rT   __classcell__r   r   rG   r   r	   	   s<    41
E_r	   N)branca.elementr   r   jinja2r   folium.elementsr   
folium.mapr   folium.utilitiesr   r   r	   r   r   r   r   <module>   s    