Пример #1
0
    def __init__(self, n_days_old_satimg=1):
        t = datetime.datetime.now() - datetime.timedelta(days=n_days_old_satimg)
        t_str = t.strftime("%Y-%m-%d")

        self.m = Map(
            layers=[
                basemap_to_tiles(basemaps.NASAGIBS.ModisTerraTrueColorCR, t_str),
            ],
            center=(52.204793, 360.121558),
            zoom=2,
        )

        self.domain_coords = []
        self.polygon = None
        self.marker_locs = {}

        self.m.on_interaction(self._handle_map_click)

        button_reset = Button(description="reset")
        button_reset.on_click(self._clear_domain)
        button_save = Button(description="save domain")
        button_save.on_click(self._save_domain)
        self.name_textfield = Text(value="domain_name", width=10)

        self.m.add_control(WidgetControl(widget=button_save, position="bottomright"))
        self.m.add_control(WidgetControl(widget=button_reset, position="bottomright"))
        self.m.add_control(
            WidgetControl(widget=self.name_textfield, position="bottomright")
        )
Пример #2
0
    def __init__(self,
                 position: str = "bottomleft",
                 attr_name: str = "style",
                 kind: str = "stroke",
                 orientation: str = "horizontal",
                 transparent: bool = False,
                 a_map: Map = None,
                 layer: Layer = None,
                 place_control: bool = True):
        def updated(change):
            """Called after each single-letter edit of the JSON in the textarea.
            """
            if change["type"] != "change":
                return
            value = change["owner"].value
            if not is_valid_json(value):
                return
            else:
                layer.style = json.loads(value)

        def close(button):
            a_map.remove_control(wc)

        layout = Layout(width="28px", height="28px", padding="0px 0px 0px 4px")
        btn = Button(tooltip="Close", icon="close", layout=layout)
        btn.on_click(close)
        ta = Textarea(value=json.dumps(getattr(layer, attr_name), indent=2))
        ta.layout.width = "200px"
        ta.observe(updated)
        header = HBox([HTML(f"<i>{attr_name} (JSON)</i>"), btn])
        ui = VBox([header, ta])
        wc = WidgetControl(widget=ui, position=position, transparent_bg=True)
        a_map.add_control(wc)
Пример #3
0
 def _show_colorbar(self, da):
     if self.colorbar_position and self.colormap is not None:
         vmin = da.min().values
         vmax = da.max().values
         fig = plt.figure(figsize=(8, 3))
         ax = fig.add_axes([0.05, 0.8, 0.5, 0.07])
         norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
         cbar = mpl.colorbar.ColorbarBase(ax,
                                          cmap=self.colormap,
                                          norm=norm,
                                          orientation='horizontal')
         f = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
         output = Output()
         try:
             plt.savefig(f.name, bbox_inches='tight')
             with output:
                 display(Image(filename=f.name))
         finally:
             os.unlink(f.name)
             f.close()
         self.colorbar = WidgetControl(widget=output,
                                       position=self.colorbar_position,
                                       transparent_bg=True)
         self.m.add_control(self.colorbar)
         plt.close()
def show_map(selected_stats, year): 
    control = WidgetControl(widget=districtbox, position='topright', min_width = 250, max_width=500)

    # load selected stats into choro_data_all
    choro_data_all, unit = choro_data_complete[selected_stats], units[selected_stats]
    # for geo plot extract chosen year and assign to choro_data
    choro_data = choro_data_all[choro_data_all['year']==year]
    choro_data = dict(choro_data.drop(columns=['year', 'name']).to_dict('split')['data'])
    
    # initialize bar chart with Frankfurt vs Offenbach
    update_figure('06412', selected_stats, choro_data_all, year)
    update_figure('06413', selected_stats, choro_data_all, year)

    # initialize districtbox
    loading_name, loading_values = id_to_name['06413'], choro_data['06413']
    districtbox.value = f'<center><p><b>{loading_name}</b>:</p> {loading_values:g} {unit} {norm_unit}</center>'
    
    # set y-axis label
    fig.update_layout(yaxis_title=f'{stat_dict[selected_stats]} [{unit} {norm_unit}]', yaxis={'range':[0,max(choro_data_all[selected_stats])]})
    

    # define chropleth layer for basic geo plotting
    layer = Choropleth(geo_data=geo_data,choro_data=choro_data,colormap=cm,
                       style={'fillOpacity': 0.65, 'dashArray': '0, 0', 'weight':1})
    
    # define GeoJSON layer for click and hover event interactions
    geo_json = GeoJSON(data=geo_data,
                       style={'opacity': 0, 'dashArray': '9', 'fillOpacity': .0, 'weight': 1},
                       hover_style={'color': 'blue', 'dashArray': '0', 'fillOpacity': 0.7})

    # on hover, the districtbox is updated to show properties of the hovered district
    def update_districtbox(feature,  **kwargs):
        feature['value'] = choro_data[feature['id']]
        districtbox.value = f'<center><p><b>{id_to_name[feature["id"]]}</b>:</p> {feature["value"]:g} {unit} {norm_unit}</center>'

    # this function is called upon a click events and triggers figure update with the arguments passed from the map
    def update_fig_on_click(feature, **kwags):
        update_figure(feature['id'], selected_stats, choro_data_all, year)
    geo_json.on_hover(update_districtbox)
    geo_json.on_click(update_fig_on_click)

    # add layers and controls; set layout parameters
    m = Map(basemap=basemaps.OpenStreetMap.Mapnik, center=(50.5,9), zoom=8)
    m.add_layer(layer)
    m.add_layer(geo_json)
    m.add_control(control)
    m.layout.width = '40%'
    m.layout.height = '700px'

    # custom made legend using min/max normalization
    min_value, max_value = min(choro_data.values()), max(choro_data.values())
    legend = LegendControl(
          {f"{min_value:g} {unit}  {norm_unit}": cm(0), #hier
          f"{min_value+0.5*(max_value-min_value):g} {unit}  {norm_unit}": cm(.5),
          f"{max_value:g} {unit}  {norm_unit}": cm(1)},
          name= f"{stat_dict[selected_stats]} ({year})", position="bottomleft")
    m.add_control(legend)
    return HBox([m, fig], layout=Layout(width='85%'))

    
Пример #5
0
    def tool_click(b):
        with output:
            output.clear_output()
            if b.icon == "folder-open":
                display(filechooser_widget)
                m.add_control(output_ctrl)
            elif b.icon == "gears":
                import whiteboxgui.whiteboxgui as wbt

                if hasattr(m, "whitebox") and m.whitebox is not None:
                    if m.whitebox in m.controls:
                        m.remove_control(m.whitebox)

                tools_dict = wbt.get_wbt_dict()
                wbt_toolbox = wbt.build_toolbox(tools_dict,
                                                max_width="800px",
                                                max_height="500px")

                wbt_control = WidgetControl(widget=wbt_toolbox,
                                            position="bottomright")

                m.whitebox = wbt_control
                m.add_control(wbt_control)
            elif b.icon == "map":
                display(basemap_widget)
                m.add_control(output_ctrl)
Пример #6
0
def convert_js2py(m):
    """A widget for converting Earth Engine JavaScript to Python.

    Args:
        m (object): geemap.Map
    """

    full_widget = widgets.VBox(
        layout=widgets.Layout(width="465px", height="350px"))

    text_widget = widgets.Textarea(
        placeholder=
        "Paste your Earth Engine JavaScript into this textbox and click the Convert button below to convert the Javascript to Python",
        layout=widgets.Layout(width="455px", height="310px"),
    )

    buttons = widgets.ToggleButtons(
        value=None,
        options=["Convert", "Clear", "Close"],
        tooltips=["Convert", "Clear", "Close"],
        button_style="primary",
    )
    buttons.style.button_width = "142px"

    def button_clicked(change):
        if change["new"] == "Convert":
            from .conversion import js_snippet_to_py, create_new_cell

            if len(text_widget.value) > 0:
                out_lines = js_snippet_to_py(
                    text_widget.value,
                    add_new_cell=False,
                    import_ee=False,
                    import_geemap=False,
                    show_map=False,
                )
                if len(out_lines) > 0 and len(out_lines[0].strip()) == 0:
                    out_lines = out_lines[1:]
                text_widget.value = "".join(out_lines)
                create_code_cell(text_widget.value)

        elif change["new"] == "Clear":
            text_widget.value = ""
        elif change["new"] == "Close":
            m.toolbar_reset()
            if m.convert_ctrl is not None and m.convert_ctrl in m.controls:
                m.remove_control(m.convert_ctrl)
            full_widget.close()
        buttons.value = None

    buttons.observe(button_clicked, "value")

    full_widget.children = [text_widget, buttons]
    widget_control = WidgetControl(widget=full_widget, position="topright")
    m.add_control(widget_control)
    m.convert_ctrl = widget_control
Пример #7
0
    def __init__(self,
                 description: str = "Basemap",
                 position: str = "topright",
                 a_map: Map = None):
        options = list(yield_basemap_dicts())
        options = [opt["name"] for opt in options]

        current_basemap_name = [
            l for l in a_map.layers if type(l) == TileLayer
        ][0].name
        start_value = current_basemap_name if current_basemap_name in options else options[
            0]

        dropdown = Dropdown(description=description,
                            options=options,
                            value=start_value,
                            layout=Layout(width="250px"))

        close_btn = Button(
            icon="times",
            button_style="info",
            tooltip="Close the basemap widget",
            layout=Layout(width="32px"),
        )

        self.widget = HBox([dropdown, close_btn])

        def switch(basemap_name):
            if len(a_map.layers) == 1:
                a_map.layers = tuple([TileLayer(**get_basemap(basemap_name))])
            else:
                old_basemap = [
                    l for l in a_map.layers if type(l) == TileLayer
                ][0]
                a_map.substitute_layer(old_basemap,
                                       TileLayer(**get_basemap(basemap_name)))

        def on_click(change):
            basemap_name = change["new"]
            switch(basemap_name)

        dropdown.observe(on_click, "value")

        def close_click(change):
            if a_map.basemap_ctrl is not None and a_map.basemap_ctrl in a_map.controls:
                a_map.remove_control(a_map.basemap_ctrl)
            self.widget.close()

        close_btn.on_click(close_click)

        self.widget_control = WidgetControl(widget=self.widget,
                                            position="topright")
        a_map.add_control(self.widget_control)
        a_map.basemap_ctrl = self.widget_control
        switch(dropdown.value)
Пример #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])
Пример #9
0
 def __init__(self):
     
     # create the extra widget
     self.state = sw.StateBar(done=True)
     self.color = v.ListItemGroup(v_model = None, children=[v.ListItem(children= [c], value=c) for c in cp.planet_colors[:4]])
     self.palette = v.Menu(
         value=False,
         v_slots=[{
             'name': 'activator',
             'variable': 'menu',
             'children': v.Btn(v_model = False, v_on='menu.on', color='primary', icon = True, children=[v.Icon(children=['mdi-palette'])])
         }],
         children = [v.List(dense=True, outlined=True, rounded=True, children=[self.color])]
     )
     
     # create the map 
     super().__init__(gee=False)
     
     # add the widget to the map (as to left and right items)
     self.add_control(WidgetControl(widget=self.state, position='topleft'))
     self.add_control(WidgetControl(widget=self.palette, position='topleft'))
     
     # create jslinks
     jslink((self, 'combo'), (self.color, 'v_model'))
Пример #10
0
    def add_layer(self, l):

        # call the original function
        super().add_layer(l)

        # add a layer state object
        state = StateBar(name=l.name)
        self.layer_state_list += [state]
        self.add_control(WidgetControl(widget=state, position="topleft"))

        # link it to the layer state
        # layer = next(l for l in self.layers if l.name == name)
        l.observe(state.activate, "loading")

        return
Пример #11
0
def change_basemap(m):
    """Widget for change basemaps.

    Args:
        m (object): geemap.Map()
    """
    from .basemaps import _ee_basemaps

    dropdown = widgets.Dropdown(
        options=list(_ee_basemaps.keys()),
        value="ROADMAP",
        layout=widgets.Layout(width="200px")
        # description="Basemaps",
    )

    close_btn = widgets.Button(
        icon="times",
        tooltip="Close the basemap widget",
        button_style="primary",
        layout=widgets.Layout(width="32px"),
    )

    basemap_widget = widgets.HBox([dropdown, close_btn])

    def on_click(change):
        basemap_name = change["new"]

        if len(m.layers) == 1:
            old_basemap = m.layers[0]
        else:
            old_basemap = old_basemap = m.layers[1]
        m.substitute_layer(old_basemap, _ee_basemaps[basemap_name])

    dropdown.observe(on_click, "value")

    def close_click(change):
        m.toolbar_reset()
        if m.basemap_ctrl is not None and m.basemap_ctrl in m.controls:
            m.remove_control(m.basemap_ctrl)
        basemap_widget.close()

    close_btn.on_click(close_click)

    basemap_control = WidgetControl(widget=basemap_widget, position="topright")
    m.add_control(basemap_control)
    m.basemap_ctrl = basemap_control
Пример #12
0
    def tool_click(b):
        with output:
            output.clear_output()
            if b.icon == "folder-open":
                display(filechooser_widget)
                m.add_control(output_ctrl)

            elif b.icon == "filter":
                dropdown_layer.options = [
                    layer.name for layer in m.layers
                    if not isinstance(layer, ipyleaflet.TileLayer)
                ]
                #               display(layers)
                display(filter_widget)
                m.add_control(filter_layer_control)

            elif b.icon == "map":
                display(basemap_widget)
                m.add_control(basemap_control)

            elif b.icon == "gears":
                import whiteboxgui.whiteboxgui as wbt

                if hasattr(m, "whitebox") and m.whitebox is not None:
                    if m.whitebox in m.controls:
                        m.remove_control(m.whitebox)

                tools_dict = wbt.get_wbt_dict()
                wbt_toolbox = wbt.build_toolbox(tools_dict,
                                                max_width="800px",
                                                max_height="500px")

                wbt_control = WidgetControl(widget=wbt_toolbox,
                                            position="bottomright")

                m.whitebox = wbt_control
                m.add_control(wbt_control)

            elif b.icon == "map-marker":
                display(add_csv_widget)
                m.add_control(output_ctrl)
#            elif b.icon == "question":

            print(f"You clicked the {b.icon} button")
Пример #13
0
    def __init__(self):

        # create a save widget
        self.save = cw.ExportMap()

        # create the map
        self.m = cw.CustomMap()
        self.m.max_zoom = (
            14  # after this zoom level GEE crash and refuse to display images
        )

        # add a legend to the map
        self.m.add_legend(legend_title="Legend", legend_dict=cp.legend_dict)

        # add the export control
        self.m.add_control(WidgetControl(widget=self.save, position="topleft"))

        # create the tile
        super().__init__("result_tile", cm.tile.result, inputs=[self.m])
Пример #14
0
def get_image_container_zoom():
    image_container = Map(center = config["center"], min_zoom=config["min_zoom"], zoom=config["min_zoom"], dragging=True,
                          zoom_control=True, box_zoom=True, double_click_zoom=True, bounce_at_zoom_limits=False,
                          layers=[LocalTileLayer(path='../classes/white.png')], layout=dict(width=config["size"], height=config["size"]),
                          crs=projections.Simple)
    
    button = widgets.Button(    
        disabled=False,
        button_style='', 
        icon='arrows-alt', 
        layout= widgets.Layout(width='35px', height='30px')
    )
    def function(b):
        center_image_on_map(image_container)
    
    button.on_click(function)
    recenter_control = WidgetControl(widget = button, position = 'topleft')
    image_container.add_control(recenter_control)
    
    return image_container
Пример #15
0
def addTimeseries(inMap,path,bands,new_plot):
        px_series = xr.open_dataset(path)
        date_start = px_series.t.min().values
        date_end = px_series.t.max().values
        color = ['blue','red','green','yellow']

        for i,b in enumerate(bands):
            x_data = px_series.t.values
            y_data = px_series.to_array().loc[dict(variable=b)][:,0,0].values
            x_data = x_data[~np.isnan(y_data)]
            y_data = y_data[~np.isnan(y_data)]
            x_data = x_data[y_data!=0]
            y_data = y_data[y_data!=0]
            axes_options = {'x': {'label':'Time', 'side':'bottom', 'num_ticks':8, 'tick_format':'%b %y'}, 'y': {'orientation':'vertical', 'side':'left', 'num_ticks':10}}
            if i==0:
                title = ''
                for x in bands:
                    title += (x + ' ')
                title += ' timeseries'
                if new_plot:
                    inMap.figure = bqplt.figure(title=title,layout={'max_height': '250px', 'width': '600px'})
                else:
                    if inMap.figure is not None:
                        pass
                    else:
                        inMap.figure = bqplt.figure(title=title,layout={'max_height': '250px', 'width': '600px'})
                        

            scatt = bqplt.scatter(x_data, y_data, labels=[b], display_legend=True, colors=[color[i]], default_size=30, axes_options=axes_options)
        
        widget_control = WidgetControl(widget=inMap.figure, position='bottomright')
        if inMap.figure_widget is not None:
            inMap.map.remove_control(inMap.figure_widget)
        inMap.figure_widget = widget_control
        inMap.map.add_control(inMap.figure_widget)
        return
Пример #16
0
    def add_widget_as_control(self, widget, position, first=False):
        """
        Add widget as control in the given position

        Args:
            widget (dom.widget): Widget to convert as map control
            position (str): 'topleft', 'topright', 'bottomright', 'bottomlreft'
            first (Bool): Whether set the control as first or last element
        """

        new_control = WidgetControl(
            widget=widget, position=position, transparent_bg=True
        )

        if first == True:

            self.controls = tuple(
                [new_control] + [control for control in self.controls]
            )
        else:

            self.controls = self.controls + tuple([new_control])

        return
Пример #17
0
    def plot(self,
             m,
             x_dim='x',
             y_dim='y',
             fit_bounds=True,
             rgb_dim=None,
             transform0=None,
             transform1=passthrough,
             transform2=coarsen(),
             transform3=passthrough,
             colormap=None,
             persist=True,
             dynamic=False,
             tile_dir=None,
             tile_height=256,
             tile_width=256,
             resampling=Resampling.nearest,
             debug_output=None):
        """Display an array as an interactive map.

        Assumes that the pixels are given on a regular grid
        (fixed spacing in x and y).

        Parameters
        ----------
        m : ipyleaflet.Map
            The map on while to show the layer.
        y_dim : str, optional
            Name of the y dimension/coordinate
            (default: 'y').
        x_dim : str, optional
            Name of the x dimension/coordinate
            (default: 'x').
        rgb_dim : str, optional
            Name of the RGB dimension/coordinate
            (default: None).
        transform0 : function, optional
            Transformation over the whole DataArray.
        transform1 : function, optional
            Transformation over the visible DataArray.
        transform2 : function, optional
            Transformation over a tile before reprojection.
        transform3 : function, optional
            Transformation over a tile before saving to PNG.
        colormap : function, optional
            The colormap function to use for the tile PNG
            (default: matplotlib.pyplot.cm.inferno).
        persist : bool, optional
            Whether to keep the tile files (True) or not (False).
        dynamic : bool, optional
            Whether the map is dynamic (True) or not (False). If True then the
            tiles will refreshed each time the map is dragged or zoomed.
        tile_dir : str, optional
            The path to the tile directory (must be absolute).
        tile_height : int, optional
            The heiht of a tile in pixels (default: 256).
        tile_width : int, optional
            The width of a tile in pixels (default: 256).
        resampling : int, optional
            The resampling method to use, see rasterio.warp.reproject
            (default: Resampling.nearest).

        Returns
        -------
        l : ipyleaflet.LocalTileLayer
            A handler to the layer that is added to the map.
        """

        if debug_output is None:
            self.debug_output = Output()
        else:
            self.debug_output = debug_output

        with self.debug_output:
            if 'proj4def' in m.crs:
                # it's a custom projection
                if dynamic:
                    raise RuntimeError('Dynamic maps are only supported for Web Mercator (EPSG:3857), not {}'.format(m.crs))
                self.dst_crs = m.crs['proj4def']
                self.web_mercator = False
                self.custom_proj = True
            elif m.crs['name'].startswith('EPSG'):
                epsg = m.crs['name'][4:]
                if dynamic and epsg != '3857':
                    raise RuntimeError('Dynamic maps are only supported for Web Mercator (EPSG:3857), not {}'.format(m.crs))
                self.dst_crs = 'EPSG:' + epsg
                self.web_mercator = epsg == '3857'
                self.custom_proj = False
            else:
                raise RuntimeError('Unsupported map projection: {}'.format(m.crs))

            self.nodata = self._da.rio.nodata
            var_dims = self._da.dims
            expected_dims = [y_dim, x_dim]
            if rgb_dim is not None:
                expected_dims.append(rgb_dim)
            if set(var_dims) != set(expected_dims):
                raise ValueError(
                    "Invalid dimensions in DataArray: "
                    "should include only {}, found {}."
                    .format(tuple(expected_dims), var_dims)
                )

            if rgb_dim is not None and colormap is not None:
                raise ValueError(
                    "Cannot have a RGB dimension and a "
                    "colormap at the same time."
                )
            elif rgb_dim is None:
                if colormap is None:
                    colormap = plt.cm.inferno
                if transform0 is None:
                    transform0 = normalize
            else:
                # there is a RGB dimension
                if transform0 is None:
                    transform0 = passthrough

            self.resampling = resampling
            self.tile_dir = tile_dir
            self.persist = persist
            self.attrs = self._da.attrs
            self.m = m
            self.dynamic = dynamic
            self.tile_width = tile_width
            self.tile_height = tile_height
            self.transform0 = transform0
            self.transform1 = transform1
            self.transform2 = transform2
            self.transform3 = transform3
            self.colormap = colormap
            if self.dynamic:
                self.persist = False
                self.tile_dir = None

            self._da = self._da.rename({y_dim: 'y', x_dim: 'x'})
            if rgb_dim is None:
                self.is_rgb = False
            else:
                self.is_rgb = True
                self._da = self._da.rename({rgb_dim: 'rgb'})

            # ensure latitudes are descending
            if np.any(np.diff(self._da.y.values) >= 0):
                self._da = self._da.sel(y=slice(None, None, -1))

            # infer grid specifications (assume a rectangular grid)
            y = self._da.y.values
            x = self._da.x.values

            self.x_left = float(x.min())
            self.x_right = float(x.max())
            self.y_lower = float(y.min())
            self.y_upper = float(y.max())

            self.dx = float((self.x_right - self.x_left) / (x.size - 1))
            self.dy = float((self.y_upper - self.y_lower) / (y.size - 1))

            if fit_bounds:
                asyncio.ensure_future(self.async_fit_bounds())
            else:
                asyncio.ensure_future(self.async_wait_for_bounds())

            self.l = LocalTileLayer()
            if self._da.name is not None:
                self.l.name = self._da.name

            self._da_notransform = self._da

            self.spinner = Spinner()
            self.spinner.radius = 5
            self.spinner.length = 3
            self.spinner.width = 5
            self.spinner.lines = 8
            self.spinner.color = '#000000'
            self.spinner.layout.height = '30px'
            self.spinner.layout.width = '30px'
            self.spinner_control = WidgetControl(widget=self.spinner, position='bottomright')

            return self.l
Пример #18
0
def main_toolbar(m):

    padding = "0px 0px 0px 5px"  # upper, right, bottom, left

    toolbar_button = widgets.ToggleButton(
        value=False,
        tooltip="Toolbar",
        icon="wrench",
        layout=widgets.Layout(width="28px", height="28px", padding=padding),
    )

    close_button = widgets.ToggleButton(
        value=False,
        tooltip="Close the tool",
        icon="times",
        button_style="primary",
        layout=widgets.Layout(height="28px", width="28px", padding=padding),
    )

    toolbar = widgets.HBox([toolbar_button])

    def close_click(change):
        if change["new"]:
            toolbar_button.close()
            close_button.close()
            toolbar.close()

    close_button.observe(close_click, "value")

    rows = 2
    cols = 3
    grid = widgets.GridspecLayout(rows,
                                  cols,
                                  grid_gap="0px",
                                  layout=widgets.Layout(width="96px"))

    icons = ["folder-open", "map", "gears", "filter", "map-marker", "question"]

    for i in range(rows):
        for j in range(cols):
            grid[i, j] = widgets.Button(description="",
                                        button_style="primary",
                                        icon=icons[i * rows + j],
                                        layout=widgets.Layout(width="28px",
                                                              padding="0px"))

    toolbar = widgets.VBox([toolbar_button])

    def toolbar_click(change):
        if change["new"]:
            toolbar.children = [
                widgets.HBox([close_button, toolbar_button]), grid
            ]
        else:
            toolbar.children = [toolbar_button]

    toolbar_button.observe(toolbar_click, "value")

    toolbar_ctrl = WidgetControl(widget=toolbar, position="topright")

    m.add_control(toolbar_ctrl)

    output = widgets.Output()
    output_ctrl = WidgetControl(widget=output, position="topright")

    buttons = widgets.ToggleButtons(
        value=None,
        options=["Apply", "Reset", "Close"],
        tooltips=["Apply", "Reset", "Close"],
        button_style="primary",
    )
    buttons.style.button_width = "80px"

    data_dir = os.path.abspath('./data')

    # File Chooser Widget
    fc = FileChooser(data_dir)
    fc.use_dir_icons = True
    fc.filter_pattern = ['*.shp', '*.geojson', '*.json']

    filechooser_widget = widgets.VBox([fc, buttons])

    def button_click(change):
        if change["new"] == "Apply" and fc.selected is not None:
            if fc.selected.endswith(".shp"):
                m.add_shapefile(fc.selected, layer_name="Shapefile")
            elif fc.selected.endswith(".geojson"):
                m.add_geojson(fc.selected, layer_name="GeoJSON")
            elif fc.selected.endswith(".json"):
                m.add_geojson(fc.selected, layer_name="GeoJSON")
        elif change["new"] == "Reset":
            fc.reset()
        elif change["new"] == "Close":
            fc.reset()
            m.remove_control(output_ctrl)

    buttons.observe(button_click, "value")

    # Basemap Widget
    from .basemaps import _ee_basemaps

    dropdown_basemap = widgets.Dropdown(
        options=list(_ee_basemaps.keys()),
        value="ROADMAP",
        layout=widgets.Layout(width="200px"),
        description="Basemaps",
    )

    close_button_basemap = widgets.Button(
        icon="times",
        tooltip="Close the basemap widget",
        button_style="primary",
        layout=widgets.Layout(width="32px"),
    )

    basemap_widget = widgets.HBox([dropdown_basemap, close_button_basemap])

    def on_click(change):
        basemap_name = change["new"]

        if len(m.layers) == 1:
            old_basemap = m.layers[0]
        else:
            old_basemap = m.layers[1]
        m.substitute_layer(old_basemap, _ee_basemaps[basemap_name])

    dropdown_basemap.observe(on_click, "value")

    def close_click(change):
        if m.basemap_ctrl is not None and m.basemap_ctrl in m.controls:
            m.remove_control(m.basemap_ctrl)
        basemap_widget.close()

    close_button_basemap.on_click(close_click)

    basemap_control = WidgetControl(widget=basemap_widget, position="topright")
    m.basemap_ctrl = basemap_control

    # Select Layer for Filtering Widget
    layers = [
        layer.name for layer in m.layers
        if not isinstance(layer, ipyleaflet.TileLayer)
    ]

    dropdown_layer = widgets.Dropdown(options=layers, description='Layer:')

    dropdown_layer_field = widgets.Dropdown(description='Field:')

    dropdown_layer_field_value = widgets.Dropdown(description='Value:')

    out_filter_layer = widgets.Output()

    def on_click_layer(change):
        with out_filter_layer:
            out_filter_layer.clear_output()
            dropdown_layer_field.options = list(
                m.find_layer(
                    change.new).data['features'][0]['properties'].keys())

    dropdown_layer.observe(on_click_layer, names="value")

    out_filter_layer_field = widgets.Output()

    def on_click_layer_field(change):
        with out_filter_layer_field:
            out_filter_layer_field.clear_output()
            field_values = set()
            for record in m.find_layer(dropdown_layer.value).data['features']:
                field_values.add(
                    record['properties'][dropdown_layer_field.value])
            dropdown_layer_field_value.options = sorted(field_values)

    dropdown_layer_field.observe(on_click_layer_field, names="value")

    add_filter_layer = widgets.Button(
        icon="plus",
        tooltip="Add a layer based on the filter options",
        button_color="lightgreen",
        layout=widgets.Layout(width="32px"))

    out_click_add_filter_layer = widgets.Output()

    def click_add_filter_layer(change):

        import itertools
        import copy

        data = copy.deepcopy(m.find_layer(dropdown_layer.value).data)
        filter_data = [
            record for record in data['features'] if record['properties'][
                dropdown_layer_field.value] == dropdown_layer_field_value.value
        ]
        data['features'] = filter_data

        style = {
            "stroke": True,
            "color": "#000000",
            "weight": 2,
            "opacity": 1,
            "fill": True,
            "fillColor": "#0000ff",
            "fillOpacity": 0.4,
        }

        geojson = ipyleaflet.GeoJSON(data=data,
                                     style=style,
                                     name="{} - {} - {} Layer".format(
                                         dropdown_layer.value,
                                         dropdown_layer_field.value,
                                         dropdown_layer_field_value.value))

        m.add_layer(geojson)

    add_filter_layer.on_click(click_add_filter_layer)

    close_dropdown_layer = widgets.Button(icon="times",
                                          tooltip="Close the filter widget",
                                          button_style="primary",
                                          layout=widgets.Layout(width="32px"))

    box_layout = widgets.Layout(display='flex',
                                flex_flow='row',
                                align_items='stretch',
                                width='70%')

    filter_buttons_box = widgets.Box([close_dropdown_layer, add_filter_layer])
    filter_dropdown_box = widgets.Box(
        [dropdown_layer, dropdown_layer_field, dropdown_layer_field_value])
    filter_widget = widgets.HBox([filter_dropdown_box, filter_buttons_box])

    def close_click_dropdown(change):
        filter_widget.close()

    close_dropdown_layer.on_click(close_click_dropdown)

    filter_layer_control = WidgetControl(widget=filter_widget,
                                         position="bottomright")
    m.filter_layer_ctrl = filter_layer_control

    # Add CSV Widget
    buttons_csv = widgets.ToggleButtons(
        value=None,
        options=["Display", "Close"],
        tooltips=["Display", "Close"],
        button_style="primary",
    )
    buttons_csv.style.button_width = "80px"

    layer_name_csv = widgets.Text(value="Untitled" + random_string(),
                                  placeholder="Type the layer name here",
                                  description="Layer name:",
                                  disabled=False)

    #observe(layer_name_csv, "value")

    fc_csv = FileChooser(data_dir)
    fc_csv.use_dir_icons = True
    fc_csv.filter_pattern = ['*.csv']

    add_csv_widget = widgets.VBox([fc_csv, layer_name_csv, buttons_csv])

    def button_click_csv(change):
        if change["new"] == "Display" and fc_csv.selected is not None:
            layer_name = "RandomForNow"
            m.add_points_from_csv(fc_csv.selected, layer_name=layer_name)
        elif change["new"] == "Close":
            fc_csv.reset()
            m.remove_control(output_ctrl)

    buttons_csv.observe(button_click_csv, "value")

    def tool_click(b):
        with output:
            output.clear_output()
            if b.icon == "folder-open":
                display(filechooser_widget)
                m.add_control(output_ctrl)

            elif b.icon == "filter":
                dropdown_layer.options = [
                    layer.name for layer in m.layers
                    if not isinstance(layer, ipyleaflet.TileLayer)
                ]
                #               display(layers)
                display(filter_widget)
                m.add_control(filter_layer_control)

            elif b.icon == "map":
                display(basemap_widget)
                m.add_control(basemap_control)

            elif b.icon == "gears":
                import whiteboxgui.whiteboxgui as wbt

                if hasattr(m, "whitebox") and m.whitebox is not None:
                    if m.whitebox in m.controls:
                        m.remove_control(m.whitebox)

                tools_dict = wbt.get_wbt_dict()
                wbt_toolbox = wbt.build_toolbox(tools_dict,
                                                max_width="800px",
                                                max_height="500px")

                wbt_control = WidgetControl(widget=wbt_toolbox,
                                            position="bottomright")

                m.whitebox = wbt_control
                m.add_control(wbt_control)

            elif b.icon == "map-marker":
                display(add_csv_widget)
                m.add_control(output_ctrl)
#            elif b.icon == "question":

            print(f"You clicked the {b.icon} button")

    for i in range(rows):
        for j in range(cols):
            tool = grid[i, j]
            tool.on_click(tool_click)
Пример #19
0
def mk_map_region_selector(height='600px', **kwargs):
    from ipyleaflet import Map, WidgetControl, FullScreenControl, DrawControl
    from ipywidgets.widgets import Layout, Button, HTML
    from types import SimpleNamespace

    state = SimpleNamespace(selection=None, bounds=None, done=False)

    btn_done = Button(description='done', layout=Layout(width='5em'))
    btn_done.style.button_color = 'green'
    btn_done.disabled = True

    html_info = HTML(
        layout=Layout(flex='1 0 20em', width='20em', height='3em'))

    def update_info(txt):
        html_info.value = '<pre style="color:grey">' + txt + '</pre>'

    m = Map(**kwargs) if len(kwargs) else Map(zoom=2)
    m.scroll_wheel_zoom = True
    m.layout.height = height

    widgets = [
        WidgetControl(widget=btn_done, position='topright'),
        WidgetControl(widget=html_info, position='bottomleft'),
    ]
    for w in widgets:
        m.add_control(w)

    draw = DrawControl()

    draw.circle = {}
    draw.polyline = {}
    draw.circlemarker = {}

    shape_opts = {
        "fillColor": "#fca45d",
        "color": "#000000",
        "fillOpacity": 0.1
    }
    draw.rectangle = {"shapeOptions": shape_opts}
    poly_opts = {"shapeOptions": dict(**shape_opts)}
    poly_opts["shapeOptions"]["original"] = dict(**shape_opts)
    poly_opts["shapeOptions"]["editing"] = dict(**shape_opts)

    draw.polygon = poly_opts
    draw.edit = True
    draw.remove = True
    m.add_control(draw)
    m.add_control(FullScreenControl())

    def on_done(btn):
        state.done = True
        btn_done.disabled = True
        m.remove_control(draw)
        for w in widgets:
            m.remove_control(w)

    def bounds_handler(event):
        (lat1, lon1), (lat2, lon2) = event['new']
        txt = 'lat: [{:.{n}f}, {:.{n}f}]\nlon: [{:.{n}f}, {:.{n}f}]'.format(
            lat1, lat2, lon1, lon2, n=4)
        update_info(txt)
        state.bounds = dict(lat=(lat1, lat2), lon=(lon1, lon2))

    def on_draw(event):
        v = event['new']
        action = event['name']
        if action == 'last_draw':
            state.selection = v['geometry']
        elif action == 'last_action' and v == 'deleted':
            state.selection = None

        btn_done.disabled = state.selection is None

    draw.observe(on_draw)
    m.observe(bounds_handler, ('bounds', ))
    btn_done.on_click(on_done)

    return m, state
Пример #20
0
    def __init__(
        self,
        a_map: Map,
        description: str = "H3",
        position: str = "topright",
    ):
        """Instantiate a tile grid tool and place it on a map.
        """
        self._max_zoom_delta = -1

        self.tile_id = ""
        self.level = int(a_map.zoom)
        style = {"color": "#888888", "weight": 1, "fillOpacity": 0}
        hover_style = {"weight": 3, "fillOpacity": 0.1}
        self.gj = GeoJSON(data=geojson.Feature(),
                          name=description,
                          style=style,
                          hover_style=hover_style)

        min_, max_ = 0, int(a_map.zoom) + self._max_zoom_delta
        self.slider = IntSlider(description=description,
                                min=min_,
                                max=max_,
                                value=self.level)
        self.ht = HTML(f"ID: {self.tile_id} Map zoom: {int(a_map.zoom)}")
        self.close_btn = Button(
            icon="times",
            button_style="info",
            tooltip="Close the widget",
            layout=Layout(width="32px"),
        )
        self.widget = HBox([self.slider, self.ht, self.close_btn])

        def hover(event, feature, **kwargs):
            if event == "mouseover":
                self.tile_id = feature["id"]
                self.ht.value = f"{self.tile_id} Map zoom: {int(a_map.zoom)}"

        def slider_moved(event):
            if event["type"] == "change" and event["name"] == "value":
                self.level = event["new"]

                # Ipyleaflet buglet(?): This name is updated in the GeoJSON layer,
                # but not in the LayersControl!
                self.gj.name = f"H3"  # level {self.level}"

                self.tile_id = ""
                map_interacted({
                    "type": "change",
                    "name": "bounds",
                    "owner": a_map
                })

        self.slider.observe(slider_moved)

        def map_interacted(event):
            if event["type"] == "change" and event["name"] == "bounds":
                self.ht.value = f"{self.tile_id}, Map zoom: {int(a_map.zoom)}"
                self.slider.max = int(a_map.zoom) + self._max_zoom_delta
                m = event["owner"]

                b_poly = list(m.bounds_polygon)
                b_poly += [tuple(b_poly[0])]
                # m += Polyline(locations=b_poly)
                poly = geojson.Polygon(coordinates=[[(p[0], p[1])
                                                     for p in b_poly]])
                hexagons = list(h3.polyfill(dict(poly), self.slider.value))
                fc = geojson.FeatureCollection(features=[
                    geojson.Polygon(coordinates=h3.h3_set_to_multi_polygon(
                        [h], geo_json=True)[0],
                                    id=h) for h in hexagons
                ])
                self.gj.data = fc

                # Ipyleaflet buglet(?): This name is updated in the GeoJSON layer,
                # but not in the LayersControl!
                self.gj.name = f"H3"  # level {self.level}"

                self.gj.on_hover(hover)

        def close_click(change):
            self.widget.children = []
            self.widget.close()

        self.close_btn.on_click(close_click)

        a_map += self.gj
        a_map.observe(map_interacted)
        map_interacted({"type": "change", "name": "bounds", "owner": a_map})

        self.widget_control = WidgetControl(widget=self.widget,
                                            position=position)
        a_map.add_control(self.widget_control)
Пример #21
0
def open_data_widget(m):
    """A widget for opening local vector/raster data.

    Args:
        m (object): geemap.Map
    """
    tool_output = widgets.Output()
    tool_output_ctrl = WidgetControl(widget=tool_output, position="topright")

    if m.tool_output_ctrl is not None and m.tool_output_ctrl in m.controls:
        m.remove_control(m.tool_output_ctrl)

    file_type = widgets.ToggleButtons(
        options=["Shapefile", "GeoJSON", "GeoTIFF"],
        tooltips=[
            "Open a shapefile",
            "Open a GeoJSON file",
            "Open a GeoTIFF",
        ],
    )

    file_chooser = FileChooser(os.getcwd())
    file_chooser.filter_pattern = "*.shp"
    file_chooser.use_dir_icons = True

    style = {"description_width": "initial"}
    layer_name = widgets.Text(
        value="Shapefile",
        description="Enter a layer name:",
        tooltip="Enter a layer name for the selected file",
        style=style,
        layout=widgets.Layout(width="454px"),
    )

    ok_cancel = widgets.ToggleButtons(
        value=None,
        options=["Apply", "Reset", "Close"],
        tooltips=["Apply", "Reset", "Close"],
        button_style="primary",
    )

    bands = widgets.Text(
        value="1",
        description="Bands:",
        tooltip="Enter a list of band indices",
        style=style,
        layout=widgets.Layout(width="110px"),
    )

    colormap = widgets.Dropdown(
        options=[],
        value=None,
        description="colormap:",
        layout=widgets.Layout(width="172px"),
        style=style,
    )

    x_dim = widgets.Text(
        value="x",
        description="x_dim:",
        tooltip="The x dimension",
        style=style,
        layout=widgets.Layout(width="80px"),
    )

    y_dim = widgets.Text(
        value="y",
        description="y_dim:",
        tooltip="The xydimension",
        style=style,
        layout=widgets.Layout(width="80px"),
    )

    raster_options = widgets.HBox()

    main_widget = widgets.VBox(
        [file_type, file_chooser, layer_name, raster_options, ok_cancel]
    )

    tool_output.clear_output()
    with tool_output:
        display(main_widget)

    # def chooser_callback(chooser):
    #     if len(layer_name.value) == 0 and file_chooser.selected is not None:
    #         layer_name.value = os.path.splitext(file_chooser.selected_filename)[0]

    def bands_changed(change):
        if change["new"] and "," in change["owner"].value:
            colormap.value = None
            colormap.disabled = True
        else:
            colormap.disabled = False

    bands.observe(bands_changed, "value")

    def file_type_changed(change):
        ok_cancel.value = None
        file_chooser.default_path = os.getcwd()
        file_chooser.reset()
        layer_name.value = file_type.value
        if change["new"] == "Shapefile":
            file_chooser.filter_pattern = "*.shp"
            raster_options.children = []
        elif change["new"] == "GeoJSON":
            file_chooser.filter_pattern = "*.geojson"
            raster_options.children = []
        elif change["new"] == "GeoTIFF":
            import matplotlib.pyplot as plt

            file_chooser.filter_pattern = "*.tif"
            colormap.options = plt.colormaps()
            colormap.value = "terrain"
            raster_options.children = [bands, colormap, x_dim, y_dim]

    def ok_cancel_clicked(change):
        if change["new"] == "Apply":
            m.default_style = {"cursor": "wait"}
            file_path = file_chooser.selected

            if file_path is not None:
                ext = os.path.splitext(file_path)[1]
                with tool_output:
                    if ext.lower() == ".shp":
                        ee_object = shp_to_ee(file_path)
                        m.addLayer(ee_object, {}, layer_name.value)
                        m.centerObject(ee_object)
                    elif ext.lower() == ".geojson":
                        ee_object = geojson_to_ee(file_path)
                        m.addLayer(ee_object, {}, layer_name.value)
                        m.centerObject(ee_object)
                    elif ext.lower() == ".tif":
                        sel_bands = [int(b.strip()) for b in bands.value.split(",")]
                        m.add_raster(
                            image=file_path,
                            bands=sel_bands,
                            layer_name=layer_name.value,
                            colormap=colormap.value,
                            x_dim=x_dim.value,
                            y_dim=y_dim.value,
                        )
            else:
                print("Please select a file to open.")

            m.toolbar_reset()
            m.default_style = {"cursor": "default"}

        elif change["new"] == "Reset":
            file_chooser.reset()
            tool_output.clear_output()
            with tool_output:
                display(main_widget)
            m.toolbar_reset()
        elif change["new"] == "Close":
            if m.tool_output_ctrl is not None and m.tool_output_ctrl in m.controls:
                m.remove_control(m.tool_output_ctrl)
                m.tool_output_ctrl = None
                m.toolbar_reset()

        ok_cancel.value = None

    file_type.observe(file_type_changed, names="value")
    ok_cancel.observe(ok_cancel_clicked, names="value")
    # file_chooser.register_callback(chooser_callback)

    m.add_control(tool_output_ctrl)
    m.tool_output_ctrl = tool_output_ctrl
    def __init__(self, questionnaire_tile, aoi_model, area_tile, theme_tile):

        # add the explanation
        mkd = sw.Markdown("  \n".join(cm.map.txt))

        # create a save widget
        self.save = cw.ExportMap()

        # create the map
        self.m = sm.SepalMap(dc=True).hide_dc()
        self.m.add_control(WidgetControl(widget=self.save, position="topleft"))
        self.m.add_colorbar(colors=cp.red_to_green, vmin=1, vmax=5)

        # create a window to display AOI information
        self.html = HTML()
        self.html.layout.margin = "0em 2em 0em 20em"
        control = WidgetControl(widget=self.html, position="bottomright")
        self.m.add_control(control)

        # drawing managment
        self.draw_features = deepcopy(self.EMPTY_FEATURES)
        self.colors = []
        self.name_dialog = cw.CustomAoiDialog()

        # create a layout with 2 btn
        self.map_btn = sw.Btn(cm.compute.btn, class_="ma-2")
        self.compute_dashboard = sw.Btn(cm.map.compute_dashboard,
                                        class_="ma-2",
                                        disabled=True)

        # models
        self.layer_model = questionnaire_tile.layer_model
        self.question_model = questionnaire_tile.question_model
        self.aoi_model = aoi_model

        # create the shape loader
        self.load_shape = cw.LoadShapes()

        # get the dashboard tile
        self.area_tile = area_tile
        self.theme_tile = theme_tile

        # init the final layers
        self.wlc_outputs = None
        self.area_dashboard = None
        self.theme_dashboard = None

        # create the tile
        super().__init__(
            id_="map_widget",
            title=cm.map.title,
            inputs=[mkd, self.load_shape, self.m, self.name_dialog],
            alert=sw.Alert(),
            btn=v.Layout(children=[self.map_btn, self.compute_dashboard]),
        )

        # decorate the function
        self._compute = su.loading_button(self.alert, self.map_btn,
                                          debug=True)(self._compute)
        self._dashboard = su.loading_button(self.alert,
                                            self.compute_dashboard,
                                            debug=True)(self._dashboard)

        # add js behaviour
        self.compute_dashboard.on_event("click", self._dashboard)
        self.m.dc.on_draw(self._handle_draw)
        self.map_btn.on_event("click", self._compute)
        self.load_shape.btn.on_event("click", self._load_shapes)
        self.name_dialog.observe(self.save_draw, "value")
Пример #23
0
    def __init__(
        self,
        a_map: Map,
        description: str = "Mercator",
        position: str = "topright",
    ):
        """Instantiate a tile grid tool and place it on a map.
        """
        self._max_zoom_delta = 4

        self.tile_id = ""
        self.level = int(a_map.zoom)
        style = {"color": "#888888", "weight": 1, "fillOpacity": 0}
        hover_style = {"weight": 3, "fillOpacity": 0.1}
        self.gj = GeoJSON(data=geojson.Feature(),
                          name=description,
                          style=style,
                          hover_style=hover_style)

        min, max = 0, int(a_map.zoom) + self._max_zoom_delta
        self.slider = IntSlider(description=description,
                                min=min,
                                max=max,
                                value=self.level)
        self.ht = HTML(f"ID: {self.tile_id} Map zoom: {int(a_map.zoom)}")
        self.close_btn = Button(
            icon="times",
            button_style="info",
            tooltip="Close the widget",
            layout=Layout(width="32px"),
        )
        self.widget = HBox([self.slider, self.ht, self.close_btn])

        def hover(event, feature, **kwargs):
            if event == "mouseover":
                self.tile_id = feature["id"]
                self.ht.value = f"{self.tile_id} Map zoom: {int(a_map.zoom)}"

        def slider_moved(event):
            if event["type"] == "change" and event["name"] == "value":
                self.level = event["new"]

                # Ipyleaflet buglet(?): This name is updated in the GeoJSON layer,
                # but not in the LayersControl!
                self.gj.name = f"Mercator"  # level {self.level}"

                self.tile_id = ""
                map_interacted({
                    "type": "change",
                    "name": "bounds",
                    "owner": a_map
                })

        self.slider.observe(slider_moved)

        def map_interacted(event):
            if event["type"] == "change" and event["name"] == "bounds":
                self.ht.value = f"{self.tile_id}, Map zoom: {int(a_map.zoom)}"
                self.slider.max = int(a_map.zoom) + self._max_zoom_delta

                m = event["owner"]
                ((south, west), (north, east)) = m.bounds

                b_poly = list(m.bounds_polygon)
                b_poly += [tuple(b_poly[0])]
                # m += Polyline(locations=b_poly)

                # Attention in the order of west, south, east, north!
                tiles = mercantile.tiles(west,
                                         south,
                                         east,
                                         north,
                                         zooms=self.level)

                features = [mercantile.feature(t) for t in tiles]
                self.gj.data = geojson.FeatureCollection(features=features)

                # Ipyleaflet buglet(?): This name is updated in the GeoJSON layer,
                # but not in the LayersControl!
                self.gj.name = f"Mercator"  # level {self.level}"

                self.gj.on_hover(hover)

        def close_click(change):
            self.widget.children = []
            self.widget.close()

        self.close_btn.on_click(close_click)

        a_map += self.gj
        a_map.observe(map_interacted)
        map_interacted({"type": "change", "name": "bounds", "owner": a_map})

        self.widget_control = WidgetControl(widget=self.widget,
                                            position=position)
        a_map.add_control(self.widget_control)
Пример #24
0
    def show_m():

        multipoly = []
        multycent = []
        geom = spatial_utils.transform_geometry(info_data)
        poly = geom['geom'][0]['coordinates'][0]
        #     poly = spatial_utils.swap_xy(geom['coordinates'][0])[0]
        multipoly.append(poly)
        centroid = spatial_utils.centroid(poly)
        multycent.append(centroid)

        centroid = spatial_utils.centroid(multycent)
        m = Map(center=centroid,
                zoom=16,
                basemap=basemaps.OpenStreetMap.Mapnik)

        polygon = Polygon(locations=multipoly,
                          name='Parcel polygon',
                          color="yellow",
                          fill_color=None)

        m.add_layer(polygon)
        basemap2 = basemap_to_tiles(basemaps.Esri.WorldImagery)

        poly_text = HTML()
        poly_text.value = f"""Parcel ID: {pid}<br>
                                    Crop name: {crop_name}<br>
                                    Area: {area:.2f} sqm<br>
                                    Coordinates: {centroid}
                                    """
        poly_text.placeholder = "HTML"
        poly_text.description = ""

        # Popup with a given location on the map:
        poly_popup = Popup(child=poly_text,
                           close_button=False,
                           auto_close=False,
                           close_on_escape_key=False)
        m.add_layer(poly_popup)

        polygon.popup = poly_popup  # Popup associated to a layer

        # Layers control
        show_poly = Checkbox(value=True,
                             description='Polygon',
                             indent=False,
                             layout=Layout(width='140px'))
        show_sat = Checkbox(value=False,
                            description='High res basemap',
                            indent=False,
                            layout=Layout(width='140px'))

        def polygon_changed(b):
            try:
                if show_poly.value is True:
                    m.add_layer(polygon)
                else:
                    m.remove_layer(polygon)
            except Exception:
                pass

        show_poly.observe(polygon_changed)

        def show_sat_changed(b):
            try:
                if show_sat.value is True:
                    m.add_layer(basemap2)
                else:
                    m.remove_layer(basemap2)
            except Exception:
                pass

        show_sat.observe(show_sat_changed)

        try:
            df = raster_utils.create_df(ci_path, pid, ci_band.value)

            geotiff = normpath(
                join(ci_path, f"{df['imgs'][0]}.{ci_band.value[0]}.tif"))
            bounds = raster_utils.bounds(geotiff)

            images = {}
            for i, row in df.iterrows():
                str_date = str(row['date'].date()).replace('-', '')
                img_tc = normpath(
                    join(ci_path,
                         f"{('').join(ci_band.value)}_{str_date}.png"))

                # Create false color image if it does not exist
                # Merge bands (images path, export image path, bands list)
                if not isfile(img_tc):
                    imgs_path = normpath(join(ci_path, row['imgs']))
                    raster_utils.merge_bands(imgs_path, img_tc, ci_band.value)

                if bool(config.get_value(['set', 'jupyterlab'])) is True:
                    jlab_path = os.getcwd().replace(os.path.expanduser("~"),
                                                    '')
                    image_path = normpath(join(f'files{jlab_path}', img_tc))
                else:
                    image_path = img_tc

                # print('image_path: ', image_path)
                images[i] = ImageOverlay(url=image_path,
                                         name=str_date,
                                         bounds=(bounds))

            # Time slider
            slider = IntSlider(value=1,
                               min=1,
                               max=len(images),
                               step=1,
                               description=str(df['date'][0].date()),
                               continuous_update=False,
                               orientation='horizontal',
                               readout=True,
                               readout_format='d')
            show_chip = Checkbox(value=True,
                                 description='Chip image',
                                 indent=False,
                                 layout=Layout(width='140px'))

            def on_ci_band_change(change):
                pass

            ci_band.observe(on_ci_band_change, 'value')

            def show_chip_changed(b):
                try:
                    if show_chip.value is True:
                        m.add_layer(images[slider.value - 1])
                    else:
                        m.remove_layer(images[slider.value - 1])
                except Exception:
                    pass

            show_chip.observe(show_chip_changed)

            # Slider control
            play = Play(
                value=1,
                min=1,
                max=len(images),
                step=1,
                interval=1000,
                description="Press play",
            )

            def slider_changed(b):
                if show_chip.value is True:
                    try:
                        m.substitute_layer(images[b['old'] - 1],
                                           images[b['new'] - 1])
                    except Exception:
                        pass
                    slider.description = str(df['date'][slider.value -
                                                        1].date())

            slider.observe(slider_changed)
            jslink((play, 'value'), (slider, 'value'))
            time_box = HBox([slider, play])
            time_control = WidgetControl(widget=time_box,
                                         position='bottomleft')
            m.add_control(time_control)
            m.add_layer(images[0])

            map_options = VBox([show_poly, show_chip, show_sat])
        except Exception as err:
            map_options = VBox([show_poly, show_sat])
            print(err)

        layers_control = WidgetControl(widget=map_options,
                                       position='topright',
                                       max_width=150)
        m.add_control(layers_control)
        return m
Пример #25
0
    def __init__(self,
                 basemaps=[],
                 dc=False,
                 vinspector=False,
                 gee=True,
                 **kwargs):

        self.world_copy_jump = True

        # Init the map
        super().__init__(
            ee_initialize=
            False,  # we take care of the initialization on our side
            add_google_map=False,
            center=[0, 0],
            zoom=2,
            **kwargs)

        # init ee
        self.ee = gee
        if gee: su.init_ee()

        # init the rasters
        self.loaded_rasters = {}

        # add the basemaps
        self.clear_layers()
        if len(basemaps):
            [self.add_basemap(basemap) for basemap in set(basemaps)]
        else:
            self.add_basemap('CartoDB.DarkMatter')

        # add the base controls
        self.clear_controls()
        self.add_control(ZoomControl(position='topright'))
        self.add_control(LayersControl(position='topright'))
        self.add_control(AttributionControl(position='bottomleft'))
        self.add_control(ScaleControl(position='bottomleft', imperial=False))

        # change the prefix
        for control in self.controls:
            if type(control) == AttributionControl:
                control.prefix = "SEPAL"

        # specific drawing control
        self.set_drawing_controls(dc)

        # Add value inspector
        self.w_vinspector = widgets.Checkbox(
            value=False,
            description='Inspect values',
            indent=False,
            layout=widgets.Layout(width='18ex'))

        if vinspector:
            self.add_control(
                WidgetControl(widget=self.w_vinspector, position='topright'))

            link((self.w_vinspector, 'value'), (self, 'vinspector'))

        # Create output space for raster interaction
        self.output_r = widgets.Output(layout={'border': '1px solid black'})
        self.output_control_r = WidgetControl(widget=self.output_r,
                                              position='bottomright')
        self.add_control(self.output_control_r)

        # define interaction with rasters
        self.on_interaction(self._raster_interaction)
Пример #26
0
def tool_template(m):

    widget_width = "250px"
    padding = "0px 0px 0px 5px"  # upper, right, bottom, left

    toolbar_button = widgets.ToggleButton(
        value=False,
        tooltip="Toolbar",
        icon="gear",
        layout=widgets.Layout(width="28px",
                              height="28px",
                              padding="0px 0px 0px 4px"),
    )

    close_button = widgets.ToggleButton(
        value=False,
        tooltip="Close the tool",
        icon="times",
        button_style="primary",
        layout=widgets.Layout(height="28px",
                              width="28px",
                              padding="0px 0px 0px 4px"),
    )

    checkbox = widgets.Checkbox(
        description="Checkbox",
        indent=False,
        layout=widgets.Layout(padding=padding, width=widget_width),
    )

    dropdown = widgets.Dropdown(
        options=["Option 1", "Option 2", "Option 3"],
        value=None,
        description="Dropdown:",
        layout=widgets.Layout(width=widget_width, padding=padding),
        style={"description_width": "initial"},
    )

    int_slider = widgets.IntSlider(
        min=1,
        max=100,
        description="Int Slider: ",
        readout=False,
        continuous_update=True,
        layout=widgets.Layout(width="220px", padding=padding),
        style={"description_width": "initial"},
    )

    int_slider_label = widgets.Label()
    widgets.jslink((int_slider, "value"), (int_slider_label, "value"))

    float_slider = widgets.FloatSlider(
        min=1,
        max=100,
        description="Float Slider: ",
        readout=False,
        continuous_update=True,
        layout=widgets.Layout(width="220px", padding=padding),
        style={"description_width": "initial"},
    )

    float_slider_label = widgets.Label()
    widgets.jslink((float_slider, "value"), (float_slider_label, "value"))

    color = widgets.ColorPicker(
        concise=False,
        description="Color:",
        value="white",
        style={"description_width": "initial"},
        layout=widgets.Layout(width=widget_width, padding=padding),
    )

    text = widgets.Text(
        value="",
        description="Textbox:",
        placeholder="Placeholder",
        style={"description_width": "initial"},
        layout=widgets.Layout(width=widget_width, padding=padding),
    )

    textarea = widgets.Textarea(
        placeholder="Placeholder",
        layout=widgets.Layout(width=widget_width),
    )

    buttons = widgets.ToggleButtons(
        value=None,
        options=["Apply", "Reset", "Close"],
        tooltips=["Apply", "Reset", "Close"],
        button_style="primary",
    )
    buttons.style.button_width = "80px"

    output = widgets.Output(
        layout=widgets.Layout(width=widget_width, padding=padding))

    toolbar_widget = widgets.VBox()
    toolbar_widget.children = [toolbar_button]
    toolbar_header = widgets.HBox()
    toolbar_header.children = [close_button, toolbar_button]
    toolbar_footer = widgets.VBox()
    toolbar_footer.children = [
        checkbox,
        widgets.HBox([int_slider, int_slider_label]),
        widgets.HBox([float_slider, float_slider_label]),
        dropdown,
        text,
        color,
        textarea,
        buttons,
        output,
    ]

    toolbar_event = ipyevents.Event(
        source=toolbar_widget, watched_events=["mouseenter", "mouseleave"])

    def handle_toolbar_event(event):

        if event["type"] == "mouseenter":
            toolbar_widget.children = [toolbar_header, toolbar_footer]
        elif event["type"] == "mouseleave":
            if not toolbar_button.value:
                toolbar_widget.children = [toolbar_button]
                toolbar_button.value = False
                close_button.value = False

    toolbar_event.on_dom_event(handle_toolbar_event)

    def toolbar_btn_click(change):
        if change["new"]:
            close_button.value = False
            toolbar_widget.children = [toolbar_header, toolbar_footer]
        else:
            if not close_button.value:
                toolbar_widget.children = [toolbar_button]

    toolbar_button.observe(toolbar_btn_click, "value")

    def close_btn_click(change):
        if change["new"]:
            toolbar_button.value = False
            if m.tool_control is not None and m.tool_control in m.controls:
                m.remove_control(m.tool_control)
                m.tool_control = None
                toolbar_widget.close()

    close_button.observe(close_btn_click, "value")

    def button_clicked(change):
        if change["new"] == "Apply":
            with output:
                output.clear_output()
                print("Running ...")
        elif change["new"] == "Reset":
            textarea.value = ""
            output.clear_output()
        elif change["new"] == "Close":
            m.toolbar_reset()
            if m.tool_control is not None and m.tool_control in m.controls:
                m.remove_control(m.tool_control)
                m.tool_control = None
                toolbar_widget.close()
        buttons.value = None

    buttons.observe(button_clicked, "value")

    toolbar_control = WidgetControl(widget=toolbar_widget, position="topright")

    if toolbar_control not in m.controls:
        m.add_control(toolbar_control)
        m.tool_control = toolbar_control

    toolbar_button.value = True
Пример #27
0
    def __init__(self,
                 position: str = "bottomleft",
                 attr_name: str = "style",
                 kind: str = "stroke",
                 orientation: str = "horizontal",
                 transparent: bool = False,
                 a_map: Map = None,
                 layer: Layer = None,
                 place_control: bool = True):
        """Add a widget to the map that allows styling some given layer.

        At the moment only the stroke color, opacity and weight can be changed
        using a color picker and sliders. Dash array might follow later.

        :param m: The map object to which to add a styling widget.
        :param layer: The layer object which is to be styled.
        :param attr_name: The layer's attribute name storing the style object.
            This is usually one of: "style", "hover_style", and "point_style"
        :param kind: The kind of style, either "stroke" or "fill".
        :param orientation: The orientation of the UI elements, either "horizontal"
            (default) or "vertical".
        :param transparent: A flag to indicate if the widget background should be
            transparent (default: ``False``). 
        :param position: The map corner where this widget will be placed. 

        TODO: The UI elements should reflect changes to the layer triggered by
              others. 
        """
        assert kind in ["stroke", "fill"]
        assert orientation in ["horizontal", "vertical"]

        def restyle(change):
            if change["type"] != "change":
                return
            owner = change["owner"]
            style_copy = copy.copy(getattr(layer, attr_name))
            attr_map = {
                p: "color" if kind == "stroke" else "fillColor",
                o: "opacity" if kind == "stroke" else "fillOpacity",
                w: "weight"
            }
            if owner in [p, o, w]:
                style_copy[attr_map[owner]] = owner.value
                setattr(layer, attr_name, style_copy)

        def close(button):
            a_map.remove_control(wc)

        attr = getattr(layer, attr_name)
        style = getattr(layer, "style")

        b = ToggleButton(description="Stroke",
                         value=True,
                         tooltip="Stroke or not?")
        dummy = ToggleButton(value=not b.value)
        b.layout.width = "80px"

        name = "color" if kind == "stroke" else "fillColor"
        p = ColorPicker(value=attr.get(name, style.get(name, "#3885ff")))
        p.layout.width = "100px"

        name = "opacity" if kind == "stroke" else "fillOpacity"
        o = FloatSlider(min=0,
                        max=1,
                        value=attr.get(name, style.get(name, 0.5)))
        o.layout.width = "200px"

        w = IntSlider(min=0,
                      max=50,
                      value=attr.get("weight", style.get("weight", 5)))
        w.layout.width = "200px"

        layout = Layout(width="28px", height="28px", padding="0px 0px 0px 4px")
        q = Button(tooltip="Close",
                   icon="close",
                   button_style="info",
                   layout=layout)

        for el in [p, o, w] if kind == "stroke" else [p, o]:
            link((dummy, "value"), (el, "disabled"))

        p.observe(restyle)
        o.observe(restyle)
        if kind == "stroke":
            w.observe(restyle)
        else:
            w.disabled = True
        q.on_click(close)

        desc = HTML(f"{kind} {attr_name}")

        if orientation == "horizontal":
            self.widget = HBox([desc, p, w, o, q])
        elif orientation == "vertical":
            self.widget = VBox([HBox([desc, q]), p, w, o])

        wc = WidgetControl(widget=self.widget,
                           position=position,
                           transparent_bg=transparent)
        a_map.add_control(wc)
Пример #28
0
# Add Earth Engine data
fc = ee.FeatureCollection('TIGER/2018/Counties')
Map.addLayer(fc, {}, 'US Counties')

states = ee.FeatureCollection('TIGER/2018/States')
# Map.addLayer(states, {}, 'US States')

Map

# Designe interactive widgets

style = {'description_width': 'initial'}

output_widget = widgets.Output(layout={'border': '1px solid black'})
output_control = WidgetControl(widget=output_widget, position='bottomright')


admin1_widget = widgets.Text(
    description='State:',
    value='Tennessee',
    width=200,
    style=style
)

admin2_widget = widgets.Text(
    description='County:',
    value='Knox',
    width=300,
    style=style
)
Пример #29
0
def addLayer(inMap, path, name, clip=[0, 0.8], bands=None):
    #Check the filetype: netcdf or geotiff
    if path.split('.')[-1] == 'nc':
        da = xr.open_dataset(path)
        if 't' in da.dims:
            da = da.drop('t').squeeze('t').to_array().astype(np.float32)
        elif 'time' in da.dims:
            da = da.drop('time').squeeze('time').to_array().astype(np.float32)
        else:
            da = da.to_array().astype(np.float32)
        if 'variable' in da.dims and 'bands' in da.dims:
            da = da.drop('variable').squeeze('variable').rename(
                {'bands': 'variable'})
    else:
        da = xr.open_rasterio(path)
        if 't' in da.dims:
            da = da.rename({
                'band': 'variable'
            }).drop('t').squeeze('t').astype(np.float32)
        else:
            da = da.rename({'band': 'variable'}).astype(np.float32)
    rds4326 = da.rio.reproject("epsg:4326")
    rds4326.name = name
    rds4326 = rds4326.rio.write_crs(4326)  # WGS 84
    if bands is not None:
        rds4326 = rds4326.loc[dict(variable=bands)]
    opacity_slider = FloatSlider(description=name + ' opacity:',
                                 min=0,
                                 max=1,
                                 value=1)

    def set_opacity(change):
        l.opacity = change['new']

    if (len(rds4326.variable) == 3):
        rds4326 = rds4326.clip(clip[0], clip[1]) / clip[1] * 255
        rds4326 = rds4326.fillna(0).rio.write_nodata(0)
        rds4326 = rds4326.chunk((1000, 1000))
        l = rds4326.leaflet.plot(inMap.map, rgb_dim='variable')

        opacity_slider.observe(set_opacity, names='value')
        slider_control = WidgetControl(widget=opacity_slider,
                                       position='bottomleft')
        inMap.map.add_control(slider_control)
    elif (len(rds4326.variable) == 1):
        rds4326 = rds4326[0]
        rds4326 = rds4326.clip(clip[0], clip[1])
        rds4326 = rds4326.fillna(0).rio.write_nodata(0)
        rds4326 = rds4326.chunk((1000, 1000))
        cmap = plt.cm.get_cmap('Greys_r')
        l = rds4326.leaflet.plot(inMap.map, colormap=cmap)

        def set_opacity(change):
            l.opacity = change['new']

        opacity_slider.observe(set_opacity, names='value')
        slider_control = WidgetControl(widget=opacity_slider,
                                       position='bottomleft')
        inMap.map.add_control(slider_control)
    else:
        rds4326 = rds4326[0]
        rds4326 = rds4326.fillna(0).rio.write_nodata(0)
        rds4326 = rds4326.chunk((1000, 1000))
        rds4326 = rds4326.clip(clip[0], clip[1])
        cmap = plt.cm.get_cmap('Greys_r')
        l = rds4326.leaflet.plot(inMap.map, colormap=cmap)

        def set_opacity(change):
            l.opacity = change['new']

        opacity_slider.observe(set_opacity, names='value')
        slider_control = WidgetControl(widget=opacity_slider,
                                       position='bottomleft')
        inMap.map.add_control(slider_control)
    return
Пример #30
0
def collect_samples(m):

    full_widget = widgets.VBox()
    layout = widgets.Layout(width="100px")
    prop_label = widgets.Label(
        value="Property",
        layout=widgets.Layout(display="flex", justify_content="center", width="100px"),
    )
    value_label = widgets.Label(
        value="Value",
        layout=widgets.Layout(display="flex", justify_content="center", width="100px"),
    )
    color_label = widgets.Label(
        value="Color",
        layout=widgets.Layout(display="flex", justify_content="center", width="100px"),
    )

    prop_text1 = widgets.Text(layout=layout, placeholder="Required")
    value_text1 = widgets.Text(layout=layout, placeholder="Integer")
    prop_text2 = widgets.Text(layout=layout, placeholder="Optional")
    value_text2 = widgets.Text(layout=layout, placeholder="String")

    color = widgets.ColorPicker(
        concise=False,
        value="#3388ff",
        layout=layout,
        style={"description_width": "initial"},
    )

    buttons = widgets.ToggleButtons(
        value=None,
        options=["Apply", "Clear", "Close"],
        tooltips=["Apply", "Clear", "Close"],
        button_style="primary",
    )
    buttons.style.button_width = "99px"

    def button_clicked(change):
        if change["new"] == "Apply":

            if len(color.value) != 7:
                color.value = "#3388ff"
            draw_control = DrawControl(
                marker={"shapeOptions": {"color": color.value}},
                rectangle={"shapeOptions": {"color": color.value}},
                polygon={"shapeOptions": {"color": color.value}},
                circlemarker={},
                polyline={},
                edit=False,
                remove=False,
            )

            controls = []
            old_draw_control = None
            for control in m.controls:
                if isinstance(control, DrawControl):
                    controls.append(draw_control)
                    old_draw_control = control

                else:
                    controls.append(control)

            m.controls = tuple(controls)
            old_draw_control.close()
            m.draw_control = draw_control

            train_props = {}

            if prop_text1.value != "" and value_text1.value != "":
                train_props[prop_text1.value] = int(value_text1.value)
            if prop_text2.value != "" and value_text2.value != "":
                train_props[prop_text2.value] = value_text2.value
            if color.value != "":
                train_props["color"] = color.value

            # Handles draw events
            def handle_draw(target, action, geo_json):
                from .geemap import ee_tile_layer

                try:
                    geom = geojson_to_ee(geo_json, False)
                    m.user_roi = geom

                    if len(train_props) > 0:
                        feature = ee.Feature(geom, train_props)
                    else:
                        feature = ee.Feature(geom)
                    m.draw_last_json = geo_json
                    m.draw_last_feature = feature
                    if action == "deleted" and len(m.draw_features) > 0:
                        m.draw_features.remove(feature)
                        m.draw_count -= 1
                    else:
                        m.draw_features.append(feature)
                        m.draw_count += 1
                    collection = ee.FeatureCollection(m.draw_features)
                    m.user_rois = collection
                    ee_draw_layer = ee_tile_layer(
                        collection, {"color": "blue"}, "Drawn Features", False, 0.5
                    )
                    draw_layer_index = m.find_layer_index("Drawn Features")

                    if draw_layer_index == -1:
                        m.add_layer(ee_draw_layer)
                        m.draw_layer = ee_draw_layer
                    else:
                        m.substitute_layer(m.draw_layer, ee_draw_layer)
                        m.draw_layer = ee_draw_layer

                except Exception as e:
                    m.draw_count = 0
                    m.draw_features = []
                    m.draw_last_feature = None
                    m.draw_layer = None
                    m.user_roi = None
                    m.roi_start = False
                    m.roi_end = False
                    print("There was an error creating Earth Engine Feature.")
                    raise Exception(e)

            draw_control.on_draw(handle_draw)

        elif change["new"] == "Clear":
            prop_text1.value = ""
            value_text1.value = ""
            prop_text2.value = ""
            value_text2.value = ""
            color.value = "#3388ff"
        elif change["new"] == "Close":
            m.toolbar_reset()
            if m.training_ctrl is not None and m.training_ctrl in m.controls:
                m.remove_control(m.training_ctrl)
            full_widget.close()
        buttons.value = None

    buttons.observe(button_clicked, "value")

    full_widget.children = [
        widgets.HBox([prop_label, value_label, color_label]),
        widgets.HBox([prop_text1, value_text1, color]),
        widgets.HBox([prop_text2, value_text2, color]),
        buttons,
    ]

    widget_control = WidgetControl(widget=full_widget, position="topright")
    m.add_control(widget_control)
    m.training_ctrl = widget_control