Spaces:
Running
Running
Add analysis gui
Browse files- .gitignore +1 -0
- pages/00_home.py +2 -1
- pages/01_gswis.py +160 -3
.gitignore
CHANGED
|
@@ -2,6 +2,7 @@
|
|
| 2 |
__pycache__/
|
| 3 |
*.py[cod]
|
| 4 |
*$py.class
|
|
|
|
| 5 |
|
| 6 |
# C extensions
|
| 7 |
*.so
|
|
|
|
| 2 |
__pycache__/
|
| 3 |
*.py[cod]
|
| 4 |
*$py.class
|
| 5 |
+
private/
|
| 6 |
|
| 7 |
# C extensions
|
| 8 |
*.so
|
pages/00_home.py
CHANGED
|
@@ -12,7 +12,8 @@ def Page():
|
|
| 12 |
We have used five global datasets viz., ESA, ESRI, JRC, OSM and HydroLAKES,
|
| 13 |
to generate a processed multi-band gridded GSWE dataset at 10 m spatial
|
| 14 |
resolution, with each band corresponding to one of the five datasets used.
|
| 15 |
-
The dataset comprises of a total of 5153 grids, each grid having a 2°×2° dimension.
|
|
|
|
| 16 |
|
| 17 |
### Datasets
|
| 18 |
|
|
|
|
| 12 |
We have used five global datasets viz., ESA, ESRI, JRC, OSM and HydroLAKES,
|
| 13 |
to generate a processed multi-band gridded GSWE dataset at 10 m spatial
|
| 14 |
resolution, with each band corresponding to one of the five datasets used.
|
| 15 |
+
The dataset comprises of a total of 5153 grids, each grid having a 2°×2° dimension.
|
| 16 |
+
**Click on the GSWIS tab above to visualize the datasets interactively.**
|
| 17 |
|
| 18 |
### Datasets
|
| 19 |
|
pages/01_gswis.py
CHANGED
|
@@ -1,17 +1,173 @@
|
|
| 1 |
import ee
|
| 2 |
import geemap
|
| 3 |
-
|
| 4 |
import solara
|
|
|
|
|
|
|
| 5 |
|
| 6 |
zoom = solara.reactive(3)
|
| 7 |
center = solara.reactive([20, 0])
|
| 8 |
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
class Map(geemap.Map):
|
| 11 |
def __init__(self, **kwargs):
|
| 12 |
super().__init__(**kwargs)
|
|
|
|
| 13 |
self.add_ee_data()
|
| 14 |
self.add_layer_manager()
|
|
|
|
| 15 |
# self.add_inspector()
|
| 16 |
|
| 17 |
def add_ee_data(self):
|
|
@@ -27,9 +183,9 @@ class Map(geemap.Map):
|
|
| 27 |
'ESRI': 'ffff00',
|
| 28 |
'JRC': '0000ff',
|
| 29 |
'OSM': '00ff00',
|
| 30 |
-
'Hydrolakes': '800080'
|
| 31 |
}
|
| 32 |
-
self.add_legend(legend_dict=legend_dict, position='
|
| 33 |
fc = ee.FeatureCollection('users/giswqs/public/countries')
|
| 34 |
style = {'color': '000000ff', 'width': 1, 'fillColor': '00000000'}
|
| 35 |
self.addLayer(fc.style(**style), {}, 'Countries', False)
|
|
@@ -46,4 +202,5 @@ def Page():
|
|
| 46 |
scroll_wheel_zoom=True,
|
| 47 |
add_google_map=True,
|
| 48 |
height="800px",
|
|
|
|
| 49 |
)
|
|
|
|
| 1 |
import ee
|
| 2 |
import geemap
|
| 3 |
+
import ipyleaflet
|
| 4 |
import solara
|
| 5 |
+
import ipywidgets as widgets
|
| 6 |
+
from IPython.display import display
|
| 7 |
|
| 8 |
zoom = solara.reactive(3)
|
| 9 |
center = solara.reactive([20, 0])
|
| 10 |
|
| 11 |
|
| 12 |
+
def zonal_stats_chart(image, vector, **kwargs):
|
| 13 |
+
if isinstance(vector, ee.Geometry):
|
| 14 |
+
fc = ee.FeatureCollection(vector)
|
| 15 |
+
elif isinstance(vector, ee.FeatureCollection):
|
| 16 |
+
fc = vector
|
| 17 |
+
else:
|
| 18 |
+
raise ValueError(
|
| 19 |
+
"The vector argument must be an ee.Geometry or ee.FeatureCollection."
|
| 20 |
+
)
|
| 21 |
+
result = geemap.zonal_stats(
|
| 22 |
+
image, fc, statistics_type="SUM", return_fc=True, verbose=False, **kwargs
|
| 23 |
+
)
|
| 24 |
+
df = geemap.ee_to_df(result).T
|
| 25 |
+
df.reset_index(inplace=True)
|
| 26 |
+
df.columns = ["Type", "Area"]
|
| 27 |
+
chart = geemap.bar_chart(df, "Type", "Area", x_label='', y_label="Area (m2)")
|
| 28 |
+
chart.update_layout(
|
| 29 |
+
margin=dict(l=0, r=0, t=10, b=0),
|
| 30 |
+
height=280,
|
| 31 |
+
)
|
| 32 |
+
|
| 33 |
+
return chart
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def add_analysis_gui(m=None, position='topright', opened=True):
|
| 37 |
+
"""Create a toolbar widget.
|
| 38 |
+
|
| 39 |
+
Args:
|
| 40 |
+
m (geemap.Map, optional): The geemap.Map instance. Defaults to None.
|
| 41 |
+
opened (bool, optional): Whether to open the toolbar. Defaults to True.
|
| 42 |
+
"""
|
| 43 |
+
|
| 44 |
+
fc = ee.FeatureCollection('users/giswqs/public/countries')
|
| 45 |
+
gswe = ee.ImageCollection("users/h2i_lab/gswe/gswe_datasets")
|
| 46 |
+
image = gswe.mosaic()
|
| 47 |
+
# esa = gswe.select("esa").mosaic()
|
| 48 |
+
# esri = gswe.select("esri").mosaic()
|
| 49 |
+
# jrc = gswe.select("jrc").mosaic()
|
| 50 |
+
# osm = gswe.select("osm").mosaic()
|
| 51 |
+
# hydrolakes = gswe.select("hydrolakes").mosaic()
|
| 52 |
+
|
| 53 |
+
widget_width = "270px"
|
| 54 |
+
padding = "0px 0px 0px 5px" # upper, right, bottom, left
|
| 55 |
+
|
| 56 |
+
toolbar_button = widgets.ToggleButton(
|
| 57 |
+
value=False,
|
| 58 |
+
tooltip="Toolbar",
|
| 59 |
+
icon="bar-chart",
|
| 60 |
+
layout=widgets.Layout(width="28px", height="28px", padding="0px 0px 0px 4px"),
|
| 61 |
+
)
|
| 62 |
+
|
| 63 |
+
close_button = widgets.ToggleButton(
|
| 64 |
+
value=False,
|
| 65 |
+
tooltip="Close the tool",
|
| 66 |
+
icon="times",
|
| 67 |
+
button_style="primary",
|
| 68 |
+
layout=widgets.Layout(height="28px", width="28px", padding="0px 0px 0px 4px"),
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
options = ["Draw an area", "Select a country"]
|
| 72 |
+
|
| 73 |
+
radio = widgets.RadioButtons(
|
| 74 |
+
options=options,
|
| 75 |
+
layout=widgets.Layout(width=widget_width, padding=padding),
|
| 76 |
+
style={"description_width": "initial"},
|
| 77 |
+
)
|
| 78 |
+
|
| 79 |
+
buttons = widgets.ToggleButtons(
|
| 80 |
+
value=None,
|
| 81 |
+
options=["Apply", "Reset", "Close"],
|
| 82 |
+
tooltips=["Apply", "Reset", "Close"],
|
| 83 |
+
button_style="primary",
|
| 84 |
+
)
|
| 85 |
+
buttons.style.button_width = "88px"
|
| 86 |
+
label = widgets.Label("Draw an area on the map first.")
|
| 87 |
+
|
| 88 |
+
output = widgets.Output(layout=widgets.Layout(width=widget_width, padding=padding))
|
| 89 |
+
|
| 90 |
+
toolbar_widget = widgets.VBox()
|
| 91 |
+
toolbar_widget.children = [toolbar_button]
|
| 92 |
+
toolbar_header = widgets.HBox()
|
| 93 |
+
toolbar_header.children = [close_button, toolbar_button]
|
| 94 |
+
toolbar_footer = widgets.VBox()
|
| 95 |
+
toolbar_footer.children = [
|
| 96 |
+
radio,
|
| 97 |
+
buttons,
|
| 98 |
+
output,
|
| 99 |
+
]
|
| 100 |
+
|
| 101 |
+
def toolbar_btn_click(change):
|
| 102 |
+
if change["new"]:
|
| 103 |
+
close_button.value = False
|
| 104 |
+
toolbar_widget.children = [toolbar_header, toolbar_footer]
|
| 105 |
+
else:
|
| 106 |
+
if not close_button.value:
|
| 107 |
+
toolbar_widget.children = [toolbar_button]
|
| 108 |
+
|
| 109 |
+
toolbar_button.observe(toolbar_btn_click, "value")
|
| 110 |
+
|
| 111 |
+
def close_btn_click(change):
|
| 112 |
+
if change["new"]:
|
| 113 |
+
toolbar_button.value = False
|
| 114 |
+
if m is not None:
|
| 115 |
+
if m.tool_control is not None and m.tool_control in m.controls:
|
| 116 |
+
m.remove_control(m.tool_control)
|
| 117 |
+
m.tool_control = None
|
| 118 |
+
toolbar_widget.close()
|
| 119 |
+
|
| 120 |
+
close_button.observe(close_btn_click, "value")
|
| 121 |
+
|
| 122 |
+
def button_clicked(change):
|
| 123 |
+
if change["new"] == "Apply":
|
| 124 |
+
with output:
|
| 125 |
+
output.clear_output()
|
| 126 |
+
# com_label = widgets.Label("PLEASE WAIT ...")
|
| 127 |
+
# display(com_label)
|
| 128 |
+
buttons.value = None
|
| 129 |
+
|
| 130 |
+
if radio.value == "Draw an area":
|
| 131 |
+
if m.user_roi is None:
|
| 132 |
+
display(label)
|
| 133 |
+
buttons.value = None
|
| 134 |
+
else:
|
| 135 |
+
chart = zonal_stats_chart(image, m.user_roi, scale=100)
|
| 136 |
+
display(chart)
|
| 137 |
+
|
| 138 |
+
elif change["new"] == "Reset":
|
| 139 |
+
output.clear_output()
|
| 140 |
+
elif change["new"] == "Close":
|
| 141 |
+
if m is not None:
|
| 142 |
+
if m.tool_control is not None and m.tool_control in m.controls:
|
| 143 |
+
m.remove_control(m.tool_control)
|
| 144 |
+
m.tool_control = None
|
| 145 |
+
toolbar_widget.close()
|
| 146 |
+
|
| 147 |
+
buttons.value = None
|
| 148 |
+
|
| 149 |
+
buttons.observe(button_clicked, "value")
|
| 150 |
+
|
| 151 |
+
toolbar_button.value = opened
|
| 152 |
+
if m is not None:
|
| 153 |
+
toolbar_control = ipyleaflet.WidgetControl(
|
| 154 |
+
widget=toolbar_widget, position=position
|
| 155 |
+
)
|
| 156 |
+
|
| 157 |
+
if toolbar_control not in m.controls:
|
| 158 |
+
m.add_control(toolbar_control)
|
| 159 |
+
m.tool_control = toolbar_control
|
| 160 |
+
else:
|
| 161 |
+
return toolbar_widget
|
| 162 |
+
|
| 163 |
+
|
| 164 |
class Map(geemap.Map):
|
| 165 |
def __init__(self, **kwargs):
|
| 166 |
super().__init__(**kwargs)
|
| 167 |
+
self.add_basemap('SATELLITE', show=False)
|
| 168 |
self.add_ee_data()
|
| 169 |
self.add_layer_manager()
|
| 170 |
+
add_analysis_gui(self)
|
| 171 |
# self.add_inspector()
|
| 172 |
|
| 173 |
def add_ee_data(self):
|
|
|
|
| 183 |
'ESRI': 'ffff00',
|
| 184 |
'JRC': '0000ff',
|
| 185 |
'OSM': '00ff00',
|
| 186 |
+
'Hydrolakes': '800080',
|
| 187 |
}
|
| 188 |
+
self.add_legend(legend_dict=legend_dict, position='bottomleft')
|
| 189 |
fc = ee.FeatureCollection('users/giswqs/public/countries')
|
| 190 |
style = {'color': '000000ff', 'width': 1, 'fillColor': '00000000'}
|
| 191 |
self.addLayer(fc.style(**style), {}, 'Countries', False)
|
|
|
|
| 202 |
scroll_wheel_zoom=True,
|
| 203 |
add_google_map=True,
|
| 204 |
height="800px",
|
| 205 |
+
data_ctrl=False,
|
| 206 |
)
|