solara-geemap / pages /06_timeseries.py
giswqs's picture
Add more apps (#5)
7b68ac7 unverified
raw
history blame contribute delete
No virus
9.82 kB
import geemap
import ipywidgets as widgets
import solara
from geemap import get_current_year, jslink_slider_label
class Map(geemap.Map):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.add_basemap("Esri.WorldImagery")
self.add_ts_gui(position="topright")
def clean_up(self):
if hasattr(self, "slider_ctrl") and self.slider_ctrl is not None:
self.remove(self.slider_ctrl)
delattr(self, "slider_ctrl")
layer = self.find_layer("Time series")
if layer is not None:
self.remove(layer)
layer = self.find_layer("Image X")
if layer is not None:
self.remove(layer)
draw_layer = self.find_layer("Drawn Features")
if draw_layer is not None:
self.remove(draw_layer)
def add_ts_gui(self, position="topright", **kwargs):
widget_width = "350px"
padding = "0px 0px 0px 5px" # upper, right, bottom, left
style = {"description_width": "initial"}
current_year = get_current_year()
collection = widgets.Dropdown(
options=[
"Landsat TM-ETM-OLI Surface Reflectance",
],
value="Landsat TM-ETM-OLI Surface Reflectance",
description="Collection:",
layout=widgets.Layout(width=widget_width, padding=padding),
style=style,
)
bands = widgets.Dropdown(
description="Bands:",
options=[
"Red/Green/Blue",
"NIR/Red/Green",
"SWIR2/SWIR1/NIR",
"NIR/SWIR1/Red",
"SWIR2/NIR/Red",
"SWIR2/SWIR1/Red",
"SWIR1/NIR/Blue",
"NIR/SWIR1/Blue",
"SWIR2/NIR/Green",
"SWIR1/NIR/Red",
],
value="SWIR1/NIR/Red",
style=style,
layout=widgets.Layout(width="195px", padding=padding),
)
frequency = widgets.Dropdown(
description="Frequency:",
options=["year", "quarter", "month"],
value="year",
style=style,
layout=widgets.Layout(width="150px", padding=padding),
)
start_year = widgets.IntSlider(
description="Start Year:",
value=1984,
min=1984,
max=current_year,
readout=False,
style=style,
layout=widgets.Layout(width="138px", padding=padding),
)
start_year_label = widgets.Label("1984")
jslink_slider_label(start_year, start_year_label)
end_year = widgets.IntSlider(
description="End Year:",
value=current_year,
min=1984,
max=current_year,
readout=False,
style=style,
layout=widgets.Layout(width="138px", padding=padding),
)
end_year_label = widgets.Label(str(current_year))
jslink_slider_label(end_year, end_year_label)
start_month = widgets.IntSlider(
description="Start Month:",
value=5,
min=1,
max=12,
readout=False,
style=style,
layout=widgets.Layout(width="145px", padding=padding),
)
start_month_label = widgets.Label(
"5",
layout=widgets.Layout(width="20px", padding=padding),
)
jslink_slider_label(start_month, start_month_label)
end_month = widgets.IntSlider(
description="End Month:",
value=10,
min=1,
max=12,
readout=False,
style=style,
layout=widgets.Layout(width="155px", padding=padding),
)
end_month_label = widgets.Label("10")
jslink_slider_label(end_month, end_month_label)
output = widgets.Output()
button_width = "113px"
apply_btn = widgets.Button(
description="Time slider",
button_style="primary",
tooltip="Click to create timeseries",
style=style,
layout=widgets.Layout(padding="0px", width=button_width),
)
split_btn = widgets.Button(
description="Split map",
button_style="primary",
tooltip="Click to create timeseries",
style=style,
layout=widgets.Layout(padding="0px", width=button_width),
)
reset_btn = widgets.Button(
description="Reset",
button_style="primary",
style=style,
layout=widgets.Layout(padding="0px", width=button_width),
)
vbox = widgets.VBox(
[
collection,
widgets.HBox([bands, frequency]),
widgets.HBox([start_year, start_year_label, end_year, end_year_label]),
widgets.HBox(
[start_month, start_month_label, end_month, end_month_label]
),
widgets.HBox([apply_btn, split_btn, reset_btn]),
output,
]
)
self.add_widget(vbox, position=position, add_header=True)
def apply_btn_click(change):
if hasattr(self, "slider_ctrl") and self.slider_ctrl is not None:
self.remove(self.slider_ctrl)
delattr(self, "slider_ctrl")
with output:
output.clear_output()
if self.user_roi is None:
output.append_stdout("Please draw a ROI first.")
else:
output.append_stdout("Creating time series...")
collection = geemap.landsat_timeseries(
roi=self.user_roi,
start_year=start_year.value,
end_year=end_year.value,
start_date=str(start_month.value).zfill(2) + "-01",
end_date=str(end_month.value).zfill(2) + "-01",
frequency=frequency.value,
)
vis_params = {
"bands": bands.value.split("/"),
"min": 0,
"max": 0.4,
}
if frequency.value == "year":
date_format = "YYYY"
elif frequency.value == "quarter":
date_format = "YYYY-MM"
elif frequency.value == "month":
date_format = "YYYY-MM"
self.add_time_slider(
collection,
region=self.user_roi,
vis_params=vis_params,
date_format=date_format,
)
self._draw_control.clear()
draw_layer = self.find_layer("Drawn Features")
if draw_layer is not None:
self.remove(draw_layer)
output.clear_output()
apply_btn.on_click(apply_btn_click)
def split_btn_click(change):
if hasattr(self, "slider_ctrl") and self.slider_ctrl is not None:
self.remove(self.slider_ctrl)
delattr(self, "slider_ctrl")
with output:
output.clear_output()
if self.user_roi is None:
output.append_stdout("Please draw a ROI first.")
else:
output.append_stdout("Creating time series...")
collection = geemap.landsat_timeseries(
roi=self.user_roi,
start_year=start_year.value,
end_year=end_year.value,
start_date=str(start_month.value).zfill(2) + "-01",
end_date=str(end_month.value).zfill(2) + "-01",
frequency=frequency.value,
)
vis_params = {
"bands": bands.value.split("/"),
"min": 0,
"max": 0.4,
}
if frequency.value == "year":
date_format = "YYYY"
dates = geemap.image_dates(collection, date_format).getInfo()
elif frequency.value == "quarter":
date_format = "YYYY-MM"
dates = geemap.image_dates(collection, date_format).getInfo()
elif frequency.value == "month":
date_format = "YYYY-MM"
dates = geemap.image_dates(collection, date_format).getInfo()
self.ts_inspector(
collection,
left_names=dates,
left_vis=vis_params,
add_close_button=True,
)
output.clear_output()
try:
self._draw_control.clear()
draw_layer = self.find_layer("Drawn Features")
if draw_layer is not None:
self.remove(draw_layer)
except Exception as e:
print(e)
split_btn.on_click(split_btn_click)
def reset_btn_click(change):
output.clear_output()
self.clean_up()
reset_btn.on_click(reset_btn_click)
@solara.component
def Page():
with solara.Column(style={"min-width": "500px"}):
Map.element(
center=[20, -0],
zoom=2,
height="750px",
zoom_ctrl=False,
measure_ctrl=False,
)