import ee import geemap import ipyleaflet import solara import ipywidgets as widgets from IPython.display import display zoom = solara.reactive(3) center = solara.reactive([20, 0]) def zonal_stats_chart(image, vector, **kwargs): if isinstance(vector, ee.Geometry): fc = ee.FeatureCollection(vector) elif isinstance(vector, ee.FeatureCollection): fc = vector else: raise ValueError( "The vector argument must be an ee.Geometry or ee.FeatureCollection." ) result = geemap.zonal_stats( image, fc, statistics_type="SUM", return_fc=True, verbose=False, **kwargs ) df = geemap.ee_to_df(result).T df.reset_index(inplace=True) df.columns = ["Type", "Area"] chart = geemap.bar_chart(df, "Type", "Area", x_label="", y_label="Area (m2)") chart.update_layout( margin=dict(l=0, r=0, t=10, b=0), height=280, ) return chart def add_analysis_gui(m=None, position="topright", opened=True): """Create a toolbar widget. Args: m (geemap.Map, optional): The geemap.Map instance. Defaults to None. opened (bool, optional): Whether to open the toolbar. Defaults to True. """ fc = ee.FeatureCollection("users/giswqs/public/countries") countries = fc.aggregate_array("NAME").getInfo() countries.sort() gswe = ee.ImageCollection("users/h2i_lab/gswe/gswe_datasets") image = gswe.mosaic() # esa = gswe.select("esa").mosaic() # esri = gswe.select("esri").mosaic() # jrc = gswe.select("jrc").mosaic() # osm = gswe.select("osm").mosaic() # hydrolakes = gswe.select("hydrolakes").mosaic() widget_width = "270px" padding = "0px 0px 0px 5px" # upper, right, bottom, left toolbar_button = widgets.ToggleButton( value=False, tooltip="Toolbar", icon="bar-chart", 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"), ) options = ["Draw an area", "Select a country"] radio = widgets.RadioButtons( options=options, layout=widgets.Layout(width=widget_width, padding=padding), style={"description_width": "initial"}, ) country = widgets.Dropdown( options=countries, value=None, layout=widgets.Layout(width=widget_width, padding=padding), ) buttons = widgets.ToggleButtons( value=None, options=["Apply", "Reset", "Close"], tooltips=["Apply", "Reset", "Close"], button_style="primary", layout=widgets.Layout(padding="0px 2px 4px 2px"), ) buttons.style.button_width = "88px" label = widgets.Label("Draw an area on the map first.") 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 = [ radio, buttons, ] def change_radio(change): if change["new"] == "Select a country": toolbar_footer.children = [radio, country, buttons] else: toolbar_footer.children = [radio, buttons] radio.observe(change_radio, "value") m.selected_country = None def change_country(change): if change["new"]: country_name = country.value country_fc = fc.filter(ee.Filter.eq("NAME", country_name)) vec_style = {"color": "000000ff", "width": 3, "fillColor": "00000000"} m.addLayer(country_fc.style(**vec_style), {}, "Selected Country") m.centerObject(country_fc) m.selected_country = country_fc toolbar_footer.children = [radio, country, buttons] country.observe(change_country, "value") 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 is not None: 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": output = widgets.Output( layout=widgets.Layout(width=widget_width, padding=padding) ) if radio.value == "Select a country": toolbar_footer.children = [radio, country, buttons, output] else: toolbar_footer.children = [radio, buttons, output] with output: output.clear_output() buttons.value = None if radio.value == "Draw an area": if m.user_roi is None: display(label) buttons.value = None else: chart = zonal_stats_chart(image, m.user_roi, scale=100) display(chart) elif radio.value == "Select a country": if m.selected_country is not None: chart = zonal_stats_chart( image, m.selected_country.geometry(), scale=100 ) display(chart) elif change["new"] == "Reset": country.value = None radio.value = "Draw an area" toolbar_footer.children = [radio, buttons] elif change["new"] == "Close": if m is not None: 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_button.value = opened if m is not None: toolbar_control = ipyleaflet.WidgetControl( widget=toolbar_widget, position=position ) if toolbar_control not in m.controls: m.add_control(toolbar_control) m.tool_control = toolbar_control else: return toolbar_widget class Map(geemap.Map): def __init__(self, **kwargs): super().__init__(**kwargs) self.add_basemap("SATELLITE", show=False) self.add_ee_data() self.add_layer_manager() # add_analysis_gui(self) # self.add_inspector() def add_ee_data(self): # gswe = ee.ImageCollection("users/h2i_lab/gswe/gswe_datasets") # self.addLayer(gswe.select("esa"), {'palette': ['red']}, "ESA") # self.addLayer(gswe.select("esri"), {'palette': ['yellow']}, "ESRI") # self.addLayer(gswe.select("jrc"), {'palette': ['blue']}, "JRC") # self.addLayer(gswe.select("osm"), {'palette': ['green']}, "OSM") # self.addLayer(gswe.select("hydrolakes"), {'palette': ['purple']}, "Hydrolakes") gswe = ee.ImageCollection("users/h2i_lab/gswe/datasets") gswe = gswe.select( ["b1", "b2", "b3", "b4", "b5"], ["esa", "esri", "osm", "jrc", "hydrolakes"] ) self.addLayer(gswe.select("esa"), {"palette": ["red"]}, "ESA") self.addLayer(gswe.select("osm"), {"palette": ["green"]}, "OSM") self.addLayer(gswe.select("jrc"), {"palette": ["blue"]}, "JRC") self.addLayer(gswe.select("esri"), {"palette": ["yellow"]}, "ESRI") self.addLayer(gswe.select("hydrolakes"), {"palette": ["purple"]}, "Hydrolakes") water_grids = ee.ImageCollection( "projects/h2i-lab/assets/DynamicWorld_v1/Main/GlobalGrids_10m" ) water_classVis = {"min": 1, "max": 3, "palette": ["blue", "yellow", "red"]} water_occurrence_vis = { "min": 0, "max": 100, "palette": ["red", "yellow", "green", "blue"], } water_variability_vis = { "min": 0, "max": 100, "palette": ["blue", "green", "yellow", "red"], } waterclass_dict = { "Permanent": "0000FF", "Seasonal": "FFFF00", "Land": "FF0000", } self.addLayer( water_grids.select("b3"), water_variability_vis, "DW Water Variability", False, ) self.addLayer( water_grids.select("b2"), water_occurrence_vis, "DW Water Occurrence", False ) self.addLayer(water_grids.select("b1"), water_classVis, "DW Water Class", False) # self.add_colorbar( # vis_params=water_variability_vis, # label="DW Water Variability (%)", # orientation="horizontal", # layer_name="DW Water Variability", # ) # self.add_colorbar( # vis_params=water_occurrence_vis, # label="DW Water Occurrence (%)", # orientation="horizontal", # layer_name="DW Water Occurrence", # ) # self.add_legend( # legend_dict=waterclass_dict, # title="DW Water Class", # layer_name="DW Water Class", # ) legend_dict = { "ESA": "ff0000", "ESRI": "ffff00", "JRC": "0000ff", "OSM": "00ff00", "Hydrolakes": "800080", } # self.add_legend(legend_dict=legend_dict, position='bottomleft') fc = ee.FeatureCollection("users/giswqs/public/countries") style = {"color": "000000ff", "width": 1, "fillColor": "00000000"} self.addLayer(fc.style(**style), {}, "Countries", False) @solara.component def Page(): with solara.Column(style={"min-width": "500px"}): Map.element( # type: ignore zoom=zoom.value, on_zoom=zoom.set, center=center.value, on_center=center.set, scroll_wheel_zoom=True, add_google_map=False, height="800px", data_ctrl=False, )