Example #1
0
def plotHeatmap(locations: [tuple],
                heatmapName: str,
                worldMap: lf.Map = None,
                center: tuple = (0, 0),
                **kwargs) -> lf.Map:
    ''' Plot the given lat lon locations as a heatmap layer on a world map object
      @center: the center coordinate when creating the world map object
      @locations: list of latitude & longitude pair
      @worldMap: ipyleaflet Map object. If this is specified, the new heatmap will be addded
                 to this object. Else a new Map object will be created
      @heatmapName: name of the heatmap layer
      Returns: a newly created Map object or the passed in worldMap object.
  '''
    # Create map if it's not passed in to the function
    if (worldMap is None):
        baseMap = lf.basemaps.CartoDB.DarkMatter  # lf.basemaps.Esri.WorldTopoMap
        worldMap = lf.Map(basemap=baseMap, center=center, zoom=10)
        worldMap.add_control(lf.FullScreenControl())
        worldMap.add_control(lf.LayersControl(position='topright'))

    # Remove existing heatmap layer that has the same name
    removeLayerByType(worldMap, heatmapName, lf.Heatmap)

    # Add the heatmap layer to the world map object
    heatmap = lf.Heatmap(locations=locations,
                         radius=20,
                         name=heatmapName,
                         **kwargs)
    worldMap.add_layer(heatmap)

    return worldMap
Example #2
0
    def add_base_controls(self):
        '''
        add some basic interactive map controls
        '''
        zc = ipyl.ZoomControl(position='topright')
        self.map.add_control(zc)

        sc = ipyl.ScaleControl(position='bottomleft')
        self.map.add_control(sc)

        fsc = ipyl.FullScreenControl(position='topright')
        self.map.add_control(fsc)

        dc = ipyl.DrawControl(position='topright')
        dc.marker = {}
        dc.rectangle = {}
        dc.circle = {}
        dc.polyline = {}
        dc.circlemarker = {}
        dc.polygon = {
            'shapeOptions': {
                'color': '#81d8d0',
                'fill_color': '#81d8d0',
                'weight': 4,
                'opacity': 1.0,
                'fill_opacity': 0.7
            }
        }
        self.map.add_control(dc)
    def display_composite_ipyleaflet(self, zoom=10):
        image = self.image.clip(ee.Geometry(self.polygon))
        mapid = image.getMapId()
        tiles_url = self.ee_tiles.format(**mapid)

        tile_layer = ipyl.TileLayer(url=tiles_url,
                                    layers='collection',
                                    format='image/png',
                                    name=self.collection,
                                    opacity=1)

        polygon = ipyl.Polygon(locations=self.locations,
                               color=self.color,
                               fill_opacity=0.,
                               name='AoI')

        m = ipyl.Map(center=tuple(self.centroid), zoom=zoom)

        m.add_layer(tile_layer)
        m.add_layer(polygon)

        control = ipyl.LayersControl(position='topright')
        m.add_control(control)
        m.add_control(ipyl.FullScreenControl())
        return m
    def create_map_widgets(self, title_list, map, inventory_df):
        """Create and add map widgets into map.

        Args:
            title_list (list): A list of the file names in the folder.

        """
        map_dropdown = ipywgt.Dropdown(description='Outputfile - 1',
                                       options=title_list,
                                       width=500)
        file_control1 = ipylft.WidgetControl(widget=map_dropdown,
                                             position='bottomleft')

        # use the following line when it needs to have another dropdown
        # dropdown2 = ipywgt.Dropdown(description = 'Outputfile - 2', options = title_list2, width=500)
        # file_control2 = ipylft.WidgetControl(widget=dropdown2, position='bottomleft')

        button = ipywgt.Button(description='Generate Map', button_style='info')
        button.on_click(self.on_button_clicked)
        map_control = ipylft.WidgetControl(widget=button,
                                           position='bottomleft')

        map.add_control(ipylft.LayersControl(position='topright',
                                             style='info'))
        map.add_control(ipylft.FullScreenControl(position='topright'))
        map.add_control(map_control)
        # map.add_control(file_control2)      # use the line when it needs to have extra dropdown
        map.add_control(file_control1)

        # set global for button click
        self.map_dropdown = map_dropdown
        self.inventory_df = inventory_df
        self.inventory_json = json.loads(inventory_df.to_json())

        return map
Example #5
0
    def show(self, tabs=True, layer_control=True, draw_control=False,
             fullscreen=True):
        """ Show the Map on the Notebook """
        if not self.is_shown:
            if layer_control:
                # Layers Control
                lc = ipyleaflet.LayersControl()
                self.add_control(lc)
            if draw_control:
                # Draw Control
                dc = ipyleaflet.DrawControl(edit=False)
                dc.on_draw(self.handle_draw)
                self.add_control(dc)
            if fullscreen:
                # Control
                full_control = ipyleaflet.FullScreenControl()
                self.add_control(full_control)

            if tabs:
                display(self, self.tab_widget)
            else:
                display(self)
        else:
            if tabs:
                display(self, self.tab_widget)
            else:
                display(self)

        self.is_shown = True
        # Start with crosshair cursor
        self.default_style = {'cursor': 'crosshair'}
    def display_animation(self, url):
        m = ipyl.Map(center=tuple(self.centroid), zoom=12)

        video = ipyl.VideoOverlay(url=url,
                                  bounds=tuple(list(map(tuple, self.bounds))))

        m.add_layer(video)
        m.add_control(ipyl.FullScreenControl())

        return m
Example #7
0
    def __init__(self,
                 map=None,
                 layer_controller_list=None,
                 position_controller=None):
        if map is None:
            map = Map()
            map.add_control(ipyleaflet.FullScreenControl())

        if layer_controller_list is None:
            from .layer_controller import LayerControllerList

            layer_controller_list = LayerControllerList(map)
        if position_controller is None:
            position_controller = PositionController(map)

        self.map = map
        self.controller_list = layer_controller_list
        self.position_controller = position_controller

        def on_clear():
            for layer in self.map.layers:
                try:
                    layer.forget_errors()
                except AttributeError:
                    pass

        self.errors = ClearableOutput(
            map.error_log,
            on_clear=on_clear,
            layout=widgets.Layout(max_height="20rem", flex="0 0 auto"),
        )

        self.autoscale_outputs = widgets.VBox(
            [
                x.autoscale_progress for x in reversed(self.map.layers)
                if isinstance(x, WorkflowsLayer)
            ],
            layout=widgets.Layout(flex="0 0 auto", max_height="16rem"),
        )

        super(MapApp, self).__init__(
            [
                map,
                self.errors,
                map.output_log,
                self.autoscale_outputs,
                position_controller,
                layer_controller_list,
            ],
            layout=app_layout,
        )

        map.observe(self._update_autoscale_progress, names=["layers"])
Example #8
0
    def __init__(self, distance_choice="agat"):
        self.m = ipyl.Map(center=(45, 0), zoom=7, layout={"height": "500px"})
        # Date
        date_picker = widg.DatePicker(value=dt.datetime(2020, 1, 26))
        self._date = date_picker.value
        date_picker.observe(self.change_date, "value")
        self.step = 0
        self.distance_choice = distance_choice
        variable_picker = widg.Dropdown(
            value="WWMF", options=["WWMF", "WME", "W1", "PRECIP", "T"])
        variable_picker.observe(self.variable_change, "value")
        dept_picker = widg.Dropdown(value="41",
                                    options={
                                        "Finistère": "29",
                                        "Isère": "38",
                                        "Hérault": "34",
                                        "Loire-et-cher": "41"
                                    })
        dept_picker.observe(self.change_dept, "value")
        self.dept = dept_picker.value
        self._variable = variable_picker.value
        # Open dataset and mask
        self.open_file()

        # Add other widgets
        self.legend = widg.Image(layout=widg.Layout(height="430px"))
        self.html1 = HTML('''
                    <h4>Type de temps</h4>
                        Hover over a pixel
                        ''')
        self.html1.layout.margin = '0px 20px 20px 20px'
        # Add controls
        control1 = WidgetControl(widget=self.html1, position='bottomright')
        self.m.add_control(control1)
        self.m.add_control(ipyl.LayersControl())

        slider = widg.IntSlider(min=0,
                                max=len(self.da.step) - 1,
                                step=1,
                                value=0,
                                description="step")
        slider.observe(self.change_step, 'value')
        self.m.add_control(
            ipyl.WidgetControl(widget=widg.VBox(
                [date_picker, slider, variable_picker, dept_picker]),
                               position="topright"))
        self.m.add_control(ipyl.FullScreenControl())
        self.render()
        super().__init__([self.m, self.legend])
Example #9
0
 def __init__(self,
              center,
              width=None,
              height=None,
              zoom=None,
              fullscreen_widget=False):
     """Return a instance of a Map."""
     if width is None:
         width = ConfigManager.get_maps('width')
     if height is None:
         height = ConfigManager.get_maps('height')
     if zoom is None:
         zoom = 15
     layout = ipywidgets.Layout(width=f'{width}px', height=f'{height}px')
     self.map = ipyleaflet.Map(center=center, zoom=zoom, layout=layout)
     self.map.add_control(ipyleaflet.ScaleControl(position='bottomleft'))
     if fullscreen_widget:
         self.map.add_control(ipyleaflet.FullScreenControl())
Example #10
0
    def create_map_widgets(self, m, outfiles):
        self.dropdown1 = ipywgt.Dropdown(description='Outputfile - 1',
                                         options=outfiles,
                                         width=500)
        file_control1 = ipylft.WidgetControl(widget=self.dropdown1,
                                             position='bottomleft')

        # self.dropdown2 = ipywgt.Dropdown(description = 'Outputfile - 2', options = outfiles, width=500)
        # file_control2 = ipylft.WidgetControl(widget=self.dropdown2, position='bottomleft')

        button = ipywgt.Button(description='Generate Map', button_style='info')
        button.on_click(self.on_button_clicked)
        generatemap_control = ipylft.WidgetControl(widget=button,
                                                   position='bottomleft')

        m.add_control(ipylft.LayersControl(position='topright', style='info'))
        m.add_control(ipylft.FullScreenControl(position='topright'))
        m.add_control(generatemap_control)
        # m.add_control(file_control2)
        m.add_control(file_control1)
Example #11
0
def plotLeaflet(geoJson: dict,
                idToValue: dict,
                worldMap: lf.Map = None,
                includeEmpty: bool = True,
                labelFormat: str = "Id={0} - Value={1}",
                mapArgs: dict = {},
                heatmapArgs: dict = {}) -> lf.Map:
    ''' Plot the choropleth on the map using the ipyleaflet library
      @idToValue: a dictionary containing mappings of ids to their associated values
      @worldMap: ipyleaflet Map object. If this is specified, the new heatmap will be addded
                 to this object. Else a new Map object will be created
      @includeEmpty: true if we want to display the regions that have value 0. False otherwise
      @labelFormat: the string format of the text that is displayed when the mouse hovers over a polygon.
                    The format must contain exactly 2 placeholders.
      Returns: map object
  '''
    updatedIdToValue = __syncIdToValueDict(geoJson, idToValue)

    # If we don't display empty regions, we need to
    # create a new geo JSON that does NOT contain the
    # ids that have 0 value
    if (not includeEmpty):
        origGeoJson = geoJson
        geoJson = {"type": "FeatureCollection", "features": []}

        for idValue, value in updatedIdToValue.items():
            if (value > 0):
                feature = getFeatureById(origGeoJson, idValue)
                geoJson["features"].append(feature)

    # Create the world map object if not specified
    if (worldMap is None):
        #basemap=lf.basemaps.CartoDB.DarkMatter, center=center, zoom=10
        worldMap = lf.Map(**mapArgs)
        worldMap.add_control(lf.FullScreenControl())
        worldMap.add_control(lf.LayersControl(position="topright"))

    # Default heatmap arguments
    minVal, maxVal = min(updatedIdToValue.values()), max(
        updatedIdToValue.values())
    defaultHeatmapArgs = {
        "key_on": "id",
        "border_color": "black",
        "value_min": minVal,
        "value_max": maxVal,
        "style": {
            'fillOpacity': 0.8,
            'dashArray': '5, 5'
        },
        "hover_style": {
            'fillColor': 'purple',
            'dashArray': '0',
            'fillOpacity': 0.5
        },
        "name": "Choropleth",
        "colormap": linear.OrRd_06
    }

    # Make a copy of the heatmapArgs, because we would add the default arguments
    # to this dict if the default arguments are not specified by the caller. Making
    # a copy prevents modifying the passed in dict object
    heatmapArgs = dict(heatmapArgs)
    for k, v in defaultHeatmapArgs.items():
        if (k not in heatmapArgs):
            heatmapArgs[k] = v

    # Create the choropleth layer
    choroplethLayer = lf.Choropleth(geo_data=geoJson,
                                    choro_data=updatedIdToValue,
                                    **heatmapArgs)

    # Create a label widget to display the currently hovered polygon id &
    # the value associated with that id
    labelWidget = widgets.Label(value="")
    widgetControl = lf.WidgetControl(widget=labelWidget,
                                     position="bottomright")
    worldMap.add_control(widgetControl)

    def mouseout(*args, **kwargs):
        ''' Set the label value to empty string when the mouse exits a region '''
        labelWidget.value = ""

    def hover(*args, **kwargs):
        ''' Set the label to the id & its associated value '''
        idValue = kwargs["id"]
        labelWidget.value = labelFormat.format(idValue,
                                               updatedIdToValue[idValue])

    # Register callbacks
    choroplethLayer.on_mouseout(mouseout)
    choroplethLayer.on_hover(hover)

    # Remove existing choropleth layer that has the same name
    choroplethName = heatmapArgs["name"] if ("name" in heatmapArgs) else ""
    removeLayerByType(worldMap, choroplethName, lf.Choropleth)

    worldMap.add_layer(choroplethLayer)
    return worldMap
Example #12
0
    def show(self, **kwargs):
        """
        Generate and return the map object for displaying the map
        Parameters
        -----------
        None

        Returns
        ----------
            map:ipyleaflet.Map
        """
        self.map = ipyleaflet.Map(
            layers=(ipyleaflet.basemap_to_tiles(
                ipyleaflet.basemaps.CartoDB.Positron),),
            **kwargs
        )
        choro_layer = ipyleaflet.Choropleth(
            name=self.dataset,
            geo_data=self.geo_data,
            choro_data=self.choro_data[self.selectedAttr][self.selectedYear],
            colormap=linear.YlOrRd_04,
            style={
                'opacity': 1,
                'weight': 1.9,
                'dashArray': '9',
                'fillOpacity': 0.5}
        )

        def handle_click(**kwargs):
            if kwargs['event'] == 'click':
                clickedFips = kwargs['properties']['GEOID']
                clickedName = self.fipsLookUp[clickedFips]
                dataBox.value = f"{clickedName} : {self.choro_data[self.selectedAttr][self.selectedYear][clickedFips]:,}"
                self.clickedID = clickedFips
        choro_layer.on_click(handle_click)
        # Year select

        def handle_year_change(change):
            new_year = str(change.new)
            choro_layer.choro_data = self.choro_data[self.selectedAttr][new_year]
            if self.clickedID:
                clickedName = self.fipsLookUp[self.clickedID]
                dataBox.value = f"{clickedName} : {self.choro_data[self.selectedAttr][new_year][self.clickedID]:,}"
            self.selectedYear = new_year
        yearList = self.availableYearDict[self.selectedAttr]
        yearListNum = list(map(int, yearList))
        minYear = min(yearListNum)
        maxYear = max(yearListNum)
        yearSlider, yearWidget = self.yearSlider(minYear, maxYear, maxYear)
        yearSlider.observe(handle_year_change, 'value')
        dataBox, dataWidget = self.dataBox()

        def handle_attr_change(change):
            new_attr = change.new
            choro_layer.choro_data = self.choro_data[new_attr][self.selectedYear]
            if self.clickedID:
                clickedName = self.fipsLookUp[self.clickedID]
                dataBox.value = f"{clickedName} : {self.choro_data[new_attr][self.selectedYear][self.clickedID]:,}"
            self.selectedAttr = new_attr
        attrDropdown, attrDropdownWidget = self.attrDropdown()
        attrDropdown.observe(handle_attr_change, "value")
        # Add to map
        self.map.add_layer(choro_layer)
        self.map.add_control(ipyleaflet.LayersControl())
        self.map.add_control(ipyleaflet.FullScreenControl())
        self.map.add_control(attrDropdownWidget)
        self.map.add_control(yearWidget)
        self.map.add_control(dataWidget)
        return self.map
def plot_geo_data_cluster(data, geom_column, title_columns):
    def date_filter(df, date_range, timestamp_column: str):
        dates = pd.to_datetime(df[timestamp_column]).apply(pd.Timestamp.date)
        return df[(date_range[0] <= dates) & (dates <= date_range[1])]

    def toggle_tweets_table_visibility(change):
        app_state['is_in_bounds'] = None
        if change['old'] and not change['new']:
            tweets_table.value, app_state['is_in_bounds'] = '', None
        else:
            update_range()

    def update_range(*_):
        def in_bounds(loc):
            return all(bounds[0] < loc) and all(loc < bounds[1])

        if len(m.bounds) == 0:
            return

        bounds = np.array(m.bounds)
        locs = app_state['filtered_data'][geom_column].apply(_wkb_hex_to_point)
        is_in_bounds = locs.apply(in_bounds)
        if app_state['is_in_bounds'] is None or not np.array_equal(
                is_in_bounds, app_state['is_in_bounds']):
            if is_in_bounds.sum() > 0:
                ts_plot = _get_ts_count_plot(
                    app_state['full_data'],
                    app_state['filtered_data'][is_in_bounds],
                    app_state['timestamp_column'])
                time_slider_box.children = [
                    ts_plot, *time_slider_box.children[1:]
                ]

                if tweets_table_cb.value:
                    tweets_table.value = app_state['filtered_data'].loc[
                        is_in_bounds,
                        title_columns].reset_index(drop=True).to_html(
                            formatters={'media': _to_html},
                            escape=False,
                            na_rep='',
                            index=False)
            else:
                tweets_table.value = ''

        tweets_table_cb.description = 'Show {} Tweets'.format(
            is_in_bounds.sum())
        app_state['is_in_bounds'] = is_in_bounds

    def change_date_range(change):
        def filter_markers(marker_cluster: ipyleaflet.MarkerCluster, min_date,
                           max_date):
            marker_cluster.markers = [
                m for m in app_state['markers']
                if min_date <= m.timestamp.date() <= max_date
            ]

        filtered_data = date_filter(
            app_state['full_data'],
            change['new'],
            timestamp_column=app_state['timestamp_column'])
        app_state['filtered_data'] = filtered_data
        heatmap.locations = list(
            filtered_data[geom_column].apply(_wkb_hex_to_point).values)
        filter_markers(marker_clusters, *change['new'])
        update_range()

    m = ipyleaflet.Map(center=(51, 10),
                       zoom=4,
                       scroll_wheel_zoom=True,
                       zoom_control=False)
    m.layout.height = '900px'

    app_state = dict(is_in_bounds=None,
                     full_data=data.dropna(subset=[geom_column]),
                     filtered_data=data.dropna(subset=[geom_column]),
                     timestamp_column=_get_timestap_column(data))

    info_box_default_text = 'Hover over a marker'
    info_box = widgets.HTML(info_box_default_text,
                            layout=Layout(margin='10px',
                                          overflow='scroll_hidden'))
    m.add_control(
        ipyleaflet.WidgetControl(widget=widgets.HBox(
            [info_box], layout=Layout(max_height='300px')),
                                 position='topright'))

    loading_wrapper = _loading_wrapper_factory(info_box, info_box_default_text)

    tweets_table = widgets.HTML(layout=widgets.Layout(
        overflow='scroll_hidden'))
    tweets_table_box = widgets.HBox([tweets_table],
                                    layout=Layout(max_height='500px',
                                                  overflow_y='auto',
                                                  max_width='900px'))
    tweets_table_cb = widgets.Checkbox(value=False)
    tweets_table_cb.observe(toggle_tweets_table_visibility,
                            type='change',
                            names=('value', ))
    tweets_box = widgets.VBox([tweets_table_cb, tweets_table_box])
    m.add_control(
        ipyleaflet.WidgetControl(widget=tweets_box, position='bottomleft'))

    time_slider = get_time_slider(app_state['full_data'])
    time_slider.observe(loading_wrapper(change_date_range),
                        type='change',
                        names=('value', ))
    time_slider.layout.margin, time_slider.description = '0px 5px 0px 5px', ''
    ts_plot = _get_ts_count_plot(data, app_state['filtered_data'],
                                 app_state['timestamp_column'])
    time_slider_box = widgets.VBox([ts_plot, time_slider])
    m.add_control(
        ipyleaflet.WidgetControl(widget=time_slider_box, position='topleft'))

    marker_clusters = get_marker_cluster(
        app_state['filtered_data'],
        geom_column,
        title_columns=title_columns,
        info_box=info_box,
        timestamp_column=app_state['timestamp_column'])
    app_state['markers'] = marker_clusters.markers

    heatmap_locations = list(app_state['filtered_data'][geom_column].apply(
        _wkb_hex_to_point).values)
    heatmap = ipyleaflet.Heatmap(name='Heatmap',
                                 min_opacity=.1,
                                 blur=20,
                                 radius=20,
                                 max_zoom=12,
                                 locations=heatmap_locations)
    m.add_layer(heatmap)
    m.add_layer(marker_clusters)

    change_date_range(dict(new=time_slider.value))
    m.add_control(ipyleaflet.LayersControl())
    m.add_control(ipyleaflet.FullScreenControl())
    m.observe(update_range)

    display(m)
Example #14
0
    def __init__(self,
                 map=None,
                 layer_controller_list=None,
                 map_controller=None):
        if map is None:
            map = Map()
            map.add_control(ipyleaflet.FullScreenControl())
            map.add_control(ipyleaflet.ScaleControl(position="bottomleft"))
            map.add_control(
                ipyleaflet.SearchControl(
                    position="topleft",
                    url=
                    "https://nominatim.openstreetmap.org/search?format=json&q={s}",
                ))

        if layer_controller_list is None:
            from .layer_controller import LayerControllerList

            layer_controller_list = LayerControllerList(map)
        if map_controller is None:
            map_controller = MapController(map)

        self.map = map
        self.controller_list = layer_controller_list
        widgets.link(
            (self, "control_tile_layers"),
            (layer_controller_list, "control_tile_layers"),
        )
        widgets.link(
            (self, "control_other_layers"),
            (layer_controller_list, "control_other_layers"),
        )
        self.map_controller = map_controller

        def on_clear():
            for layer in self.map.layers:
                try:
                    layer.forget_logs()
                except AttributeError:
                    pass

        self.clearable_logs = ClearableOutput(
            map.logs,
            on_clear=on_clear,
            layout=widgets.Layout(max_height="20rem", flex="0 0 auto"),
        )

        self.autoscale_outputs = widgets.VBox(
            [
                x.autoscale_progress for x in reversed(self.map.layers)
                if isinstance(x, WorkflowsLayer)
            ],
            layout=widgets.Layout(flex="0 0 auto", max_height="16rem"),
        )

        super(MapApp, self).__init__(
            [
                map,
                self.clearable_logs,
                map.output_log,
                self.autoscale_outputs,
                map_controller,
                layer_controller_list,
            ],
            layout=app_layout,
        )

        map.observe(self._update_autoscale_progress, names=["layers"])
Example #15
0
def add_fullscreen_control(map):
    "use map (ipyleaflet.Map object), add fullscreen control and return object"
    map.add_control(ipyleaflet.FullScreenControl())
    return map
Example #16
0
    def _build_ui(self,
                  product_names,
                  time,
                  zoom=None,
                  center=None,
                  height=None,
                  width=None):
        import ipyleaflet as L
        from ipywidgets import widgets as w

        pp = {"zoom": zoom or 1}

        if center is not None:
            pp["center"] = center

        m = L.Map(**pp, scroll_wheel_zoom=True)
        m.add_control(L.FullScreenControl())

        prod_select = w.Dropdown(
            options=product_names,
            layout=w.Layout(
                flex="0 1 auto",
                width="10em",
            ),
        )

        date_txt = w.Text(
            value=time,
            layout=w.Layout(
                flex="0 1 auto",
                width="6em",
            ),
        )

        info_lbl = w.Label(
            value="",
            layout=w.Layout(flex="1 0 auto",
                            # border='1px solid white',
                            ),
        )
        btn_bwd = w.Button(
            icon="step-backward",
            layout=w.Layout(
                flex="0 1 auto",
                width="3em",
            ),
        )
        btn_fwd = w.Button(
            icon="step-forward",
            layout=w.Layout(
                flex="0 1 auto",
                width="3em",
            ),
        )
        btn_show = w.Button(
            description="show",
            layout=w.Layout(
                flex="0 1 auto",
                width="6em",
            ),
            style=dict(
                # button_color='green'
            ),
        )

        ctrls = w.HBox(
            [
                prod_select,
                w.Label("Time Period"),
                date_txt,
                btn_bwd,
                btn_fwd,
                info_lbl,
                btn_show,
            ],
            layout=w.Layout(
                # border='1px solid tomato',
            ),
        )
        # m.add_control(L.WidgetControl(widget=ctrls, position='topright'))

        ui = w.VBox(
            [ctrls, m],
            layout=w.Layout(
                width=width,
                height=height,
                # border='2px solid plum',
            ),
        )

        state = SimpleNamespace(time=time,
                                product=product_names[0],
                                count=0,
                                bounds=None)
        ui_state = SimpleNamespace(ui=ui, info=info_lbl, map=m)

        def bounds_handler(event):
            (lat1, lon1), (lat2, lon2) = event["new"]
            lon1 = max(lon1, -180)
            lon2 = min(lon2, +180)
            lat1 = max(lat1, -90)
            lat2 = min(lat2, +90)

            state.bounds = dict(lat=(lat1, lat2), lon=(lon1, lon2))

            self.on_bounds(state.bounds)

        def on_date_change(txt):
            state.time = txt.value
            self.on_date(state.time)

        def on_product_change(e):
            state.product = e["new"]
            self.on_product(state.product)

        def on_show(b):
            state.time = date_txt.value
            self.on_show()

        def time_advance(step):
            date_txt.value = _dt_step(date_txt.value, step)
            on_date_change(date_txt)

        date_txt.on_submit(on_date_change)
        prod_select.observe(on_product_change, ["value"])
        m.observe(bounds_handler, ("bounds", ))
        btn_show.on_click(on_show)
        btn_fwd.on_click(lambda b: time_advance(1))
        btn_bwd.on_click(lambda b: time_advance(-1))

        return state, ui_state
def plot_geo_shapes_vis(data, nuts_shapes, nuts_ids_columns, color_column,
                        timestamp_column):
    def plot_cbar(name, logarithmic=False):
        vmin, vmax = app_state['vmin'], app_state['vmax']
        if vmin == vmax or any(pd.isna([vmin, vmax])):
            return
        fig, ax = plt.subplots(figsize=(.3, 10))
        norm = matplotlib.colors.LogNorm(
            vmin, vmax) if logarithmic else matplotlib.colors.Normalize(
                vmin, vmax)
        cbar = matplotlib.colorbar.ColorbarBase(ax,
                                                cmap=plt.get_cmap(name),
                                                norm=norm,
                                                orientation='vertical')
        return cbar

    def change_date_range(change):
        data = _date_filter(app_state['data'],
                            change['new'],
                            timestamp_column=timestamp_column).dropna(
                                subset=nuts_ids_columns, how='all')
        merged_dfs = [
            merge_df(data=data,
                     nuts_shapes=nuts_shapes,
                     nuts_ids_column=nuts_ids_column,
                     color_column=color_column,
                     level=level_selector.value,
                     levels=app_state['nuts_levels'])
            for nuts_ids_column in nuts_ids_columns
        ]
        app_state['vmax'] = np.max(
            [df[color_column].max() for df in merged_dfs])
        interactive_output(
            plot_cbar, dict(name=cmap_selector, logarithmic=logarithmic_cbox))

        m.layers = [l for l in m.layers if type(l) != ipyleaflet.LayerGroup]
        for merged_df, nuts_ids_column in zip(merged_dfs, nuts_ids_columns):
            table_columns = [
                '_timestamp', 'text_translated', 'num_persons', 'mode',
                *[col for col in nuts_ids_columns if col != nuts_ids_column]
            ]
            layer = get_shapes_heatmap(data=merged_df,
                                       nuts_ids_column=nuts_ids_column,
                                       color_column=color_column,
                                       info_widget_html=info_widget,
                                       vmin=app_state['vmin'],
                                       vmax=app_state['vmax'],
                                       full_data=app_state['full_data'],
                                       time_hist=time_hist,
                                       date_limits=change['new'],
                                       tweets_table=tweets_table,
                                       cmap=app_state['cmap'],
                                       table_columns=table_columns,
                                       logarithmic=app_state['logarithmic'])
            m.add_layer(layer)

        if 'full_groups' not in app_state:
            app_state['full_groups'] = [
                l.layers for l in m.layers if type(l) is ipyleaflet.LayerGroup
            ]

        cbar_widget.children = [
            interactive_output(
                plot_cbar,
                dict(name=cmap_selector, logarithmic=logarithmic_cbox))
        ]

    def change_level_layers(change={}):
        def change_layers(layer_group: ipyleaflet.LayerGroup,
                          all_layers: list):
            new_layers = [
                l for l in all_layers if l.data['features'][0]['properties']
                ['LEVL_CODE'] == app_state['level']
            ]
            layer_group.layers = new_layers if app_state[
                'level'] != 'all' else all_layers

        layer_groups = [
            l for l in m.layers if type(l) is ipyleaflet.LayerGroup
        ]
        if 'new' in change:
            app_state['level'] = change['new']
        for layer_group, full_group in zip(layer_groups,
                                           app_state['full_groups']):
            change_layers(layer_group, full_group)

    def change_colormap():
        cmap, logarithmic = app_state['cmap'], app_state['logarithmic']

        def update_layer(l):
            val = l.data['features'][0]['properties'][color_column]
            color = get_color(val,
                              cmap=cmap,
                              vmin=app_state['vmin'],
                              vmax=app_state['vmax'],
                              logarithmic=logarithmic)
            l.style.update({'fillColor': color, 'color': color})
            l.hover_style.update({'fillColor': color, 'color': color})
            new_layer = ipyleaflet.GeoJSON(data=l.data,
                                           style=l.style,
                                           hover_style=l.hover_style)
            new_layer._hover_callbacks = l._hover_callbacks
            new_layer._click_callbacks = l._click_callbacks
            return new_layer

        app_state['full_groups'] = [[update_layer(l) for l in layers]
                                    for layers in app_state['full_groups']]

        change_level_layers()

    def change_colormap_name(change):
        app_state['cmap'] = change['new']
        change_colormap()

    def change_colormap_log(change):
        app_state['logarithmic'] = change['new']
        change_colormap()

    def add_widget(widget, pos, margin='0px 0px 0px 0px'):
        widget.layout.margin = margin
        widget_control = ipyleaflet.WidgetControl(widget=widget, position=pos)
        m.add_control(widget_control)

    def on_zoom(change, offset=-5):
        if m.zoom != app_state['zoom']:
            app_state['zoom'] = m.zoom
            if level_on_zoom.value:
                min_level, max_level = np.min(
                    app_state['nuts_levels']), np.max(app_state['nuts_levels'])
                level = min(max_level, max(min_level, m.zoom + offset))
                app_state['level'] = level
                level_selector.value = level

    app_state = dict(zoom=4,
                     data=data.dropna(subset=nuts_ids_columns, how='all'),
                     cmap='viridis',
                     logarithmic=False,
                     vmin=1,
                     vmax=1,
                     full_data=data.copy(),
                     level='all',
                     nuts_levels=sorted(nuts_shapes['LEVL_CODE'].unique()))
    m = ipyleaflet.Map(center=(51, 10),
                       zoom=app_state['zoom'],
                       scroll_wheel_zoom=True,
                       zoom_control=False)
    m.layout.height = '900px'

    info_widget_default_text = 'Hover over a Region<br>Click it to see tweets'
    info_widget = widgets.HTML(info_widget_default_text)
    add_widget(info_widget, pos='topright', margin='0px 5px 0px 5px')

    loading_wrapper = _loading_wrapper_factory(info_widget,
                                               info_widget_default_text)

    time_hist = widgets.HBox([])
    add_widget(time_hist, pos='bottomleft')

    tweets_table = widgets.HTML(layout=widgets.Layout(
        overflow='scroll_hidden'))
    tweets_box = widgets.HBox([tweets_table],
                              layout=Layout(max_height='400px',
                                            overflow_y='auto',
                                            max_width='900px'))
    add_widget(tweets_box, pos='bottomleft')

    time_slider = get_time_slider(app_state['data'])
    time_slider.observe(loading_wrapper(change_date_range),
                        type='change',
                        names=('value', ))
    add_widget(time_slider, 'topleft', margin='0px 5px 0px 5px')

    level_selector = widgets.Dropdown(
        options=['all', *app_state['nuts_levels']],
        description='NUTS levels',
        layout=Layout(max_width='180px'))
    level_selector.observe(handler=loading_wrapper(change_level_layers),
                           type='change',
                           names=('value', ))
    level_on_zoom = widgets.Checkbox(value=True,
                                     description='with zoom',
                                     layout=Layout(max_width='180px'))
    level_control = widgets.VBox([level_selector, level_on_zoom])

    cmap_selector = widgets.Dropdown(
        options=['viridis', 'inferno', 'magma', 'winter', 'cool'],
        description='colormap',
        layout=Layout(max_width='180px'))
    logarithmic_cbox = widgets.Checkbox(description='logarithmic',
                                        layout=Layout(max_width='180px'))
    cmap_control = widgets.VBox([cmap_selector, logarithmic_cbox])
    cmap_selector.observe(handler=loading_wrapper(change_colormap_name),
                          type='change',
                          names=('value', ))
    logarithmic_cbox.observe(handler=loading_wrapper(change_colormap_log),
                             type='change',
                             names=('value', ))
    add_widget(widgets.HBox([level_control, cmap_control]),
               pos='topleft',
               margin='5px 5px 0px 5px')

    cbar_widget = widgets.HBox([
        interactive_output(
            plot_cbar, dict(name=cmap_selector, logarithmic=logarithmic_cbox))
    ])
    add_widget(cbar_widget, pos='bottomright')

    m.add_control(ipyleaflet.LayersControl())
    m.add_control(ipyleaflet.FullScreenControl())
    m.observe(handler=on_zoom)

    change_date_range(dict(new=time_slider.value))
    display(m)
Example #18
0
    def controls_on_Map(self):
        control_layer = ipyleaflet.LayersControl(position='topright')
        self.m01.add_control(control_layer)

        control_fullscreen = ipyleaflet.FullScreenControl()
        self.m01.add_control(control_fullscreen)

        self.control_draw = ipyleaflet.DrawControl()
        self.m01.add_control(self.control_draw)

        control_scale = ipyleaflet.ScaleControl(position='bottomleft')
        self.m01.add_control(control_scale)

        slider_heatmap_radius = ipywidgets.IntSlider(description='Radius',
                                                     min=1,
                                                     max=50,
                                                     value=15)
        ipywidgets.jslink((slider_heatmap_radius, 'value'),
                          (self.heatmap_all, 'radius'))
        widget_control01 = ipyleaflet.WidgetControl(
            widget=slider_heatmap_radius, position='bottomright')
        self.m01.add_control(widget_control01)

        self.date_slider = ipywidgets.SelectionSlider(options=pd.date_range(
            start='2000-01-01', end='2020-01-01', freq='M').to_numpy())
        self.date_slider.observe(self.date_location, names='value')
        ipywidgets.jslink((slider_heatmap_radius, 'value'),
                          (self.heatmap_byLast, 'radius'))
        widget_control02 = ipyleaflet.WidgetControl(widget=self.date_slider,
                                                    position='topright')
        self.m01.add_control(widget_control02)

        self.control_selectDownload = ipywidgets.Dropdown(
            options=['Watershed', 'All', 'byDate'],
            value=None,
            description='Select type:')
        self.control_selectDownload.observe(self.dropdown_shapefile,
                                            names='value')
        self.control_selectDownload.observe(self.shapefile_buttom,
                                            names='value')

        box_layout = ipywidgets.Layout(display='flex',
                                       flex_flow='column',
                                       align_items='stretch',
                                       width='100%')

        self.control_pathDownload = ipywidgets.Text(
            placeholder='Write your PATH to Download HERE.')
        vbox01 = ipywidgets.VBox(
            [self.control_selectDownload, self.control_pathDownload])
        self.control_buttonDownload = ipywidgets.Button(description='Download')
        self.control_loadingDownload = ipywidgets.FloatProgress(min=0,
                                                                max=1,
                                                                value=0)

        self.control_choiceDownload = ipywidgets.RadioButtons(
            options=['Rain', 'Flow'])
        hbox01 = ipywidgets.HBox(
            [self.control_choiceDownload, self.control_buttonDownload],
            layout=box_layout)

        vbox02 = ipywidgets.VBox(
            [vbox01, hbox01, self.control_loadingDownload], layout=box_layout)

        widget_control03 = ipyleaflet.WidgetControl(widget=vbox02,
                                                    position='bottomright')
        self.m01.add_control(widget_control03)
        # control_progressDownload = ipywidgets.FloatProgress()
        self.control_shapefileButtom = ipywidgets.Button(
            description='Visualizar')