Spaces:
Runtime error
Runtime error
| 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") | |
| 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) | |
| 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=True, | |
| height="800px", | |
| data_ctrl=False, | |
| ) |