giswqs commited on
Commit
7007026
Β·
1 Parent(s): 53ef1d3

Add timeseries app

Browse files
pages/02_timeseries.py ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import ee
3
+ import geemap
4
+ import ipywidgets as widgets
5
+ from IPython.display import display
6
+ import solara
7
+ from geemap import get_current_year, jslink_slider_label
8
+
9
+
10
+ class Map(geemap.Map):
11
+ def __init__(self, **kwargs):
12
+ super().__init__(**kwargs)
13
+ self.add_basemap("Esri.WorldImagery")
14
+ self.add_ts_gui(position="topright")
15
+
16
+ def clean_up(self):
17
+ if hasattr(self, "slider_ctrl") and self.slider_ctrl is not None:
18
+ self.remove(self.slider_ctrl)
19
+ delattr(self, "slider_ctrl")
20
+
21
+ layer = self.find_layer("Time series")
22
+ if layer is not None:
23
+ self.remove(layer)
24
+ layer = self.find_layer("Image X")
25
+ if layer is not None:
26
+ self.remove(layer)
27
+
28
+ draw_layer = self.find_layer("Drawn Features")
29
+ if draw_layer is not None:
30
+ self.remove(draw_layer)
31
+
32
+ def add_ts_gui(self, position="topright", **kwargs):
33
+
34
+ widget_width = "350px"
35
+ padding = "0px 0px 0px 5px" # upper, right, bottom, left
36
+ style = {"description_width": "initial"}
37
+ current_year = get_current_year()
38
+
39
+ collection = widgets.Dropdown(
40
+ options=[
41
+ "Landsat TM-ETM-OLI Surface Reflectance",
42
+ ],
43
+ value="Landsat TM-ETM-OLI Surface Reflectance",
44
+ description="Collection:",
45
+ layout=widgets.Layout(width=widget_width, padding=padding),
46
+ style=style,
47
+ )
48
+ bands = widgets.Dropdown(
49
+ description="Bands:",
50
+ options=[
51
+ "Red/Green/Blue",
52
+ "NIR/Red/Green",
53
+ "SWIR2/SWIR1/NIR",
54
+ "NIR/SWIR1/Red",
55
+ "SWIR2/NIR/Red",
56
+ "SWIR2/SWIR1/Red",
57
+ "SWIR1/NIR/Blue",
58
+ "NIR/SWIR1/Blue",
59
+ "SWIR2/NIR/Green",
60
+ "SWIR1/NIR/Red",
61
+ ],
62
+ value="SWIR1/NIR/Red",
63
+ style=style,
64
+ layout=widgets.Layout(width="195px", padding=padding),
65
+ )
66
+
67
+ frequency = widgets.Dropdown(
68
+ description="Frequency:",
69
+ options=["year", "quarter", "month"],
70
+ value="year",
71
+ style=style,
72
+ layout=widgets.Layout(width="150px", padding=padding),
73
+ )
74
+
75
+ start_year = widgets.IntSlider(
76
+ description="Start Year:",
77
+ value=1984,
78
+ min=1984,
79
+ max=current_year,
80
+ readout=False,
81
+ style=style,
82
+ layout=widgets.Layout(width="138px", padding=padding),
83
+ )
84
+
85
+ start_year_label = widgets.Label("1984")
86
+ jslink_slider_label(start_year, start_year_label)
87
+
88
+ end_year = widgets.IntSlider(
89
+ description="End Year:",
90
+ value=current_year,
91
+ min=1984,
92
+ max=current_year,
93
+ readout=False,
94
+ style=style,
95
+ layout=widgets.Layout(width="138px", padding=padding),
96
+ )
97
+ end_year_label = widgets.Label(str(current_year))
98
+ jslink_slider_label(end_year, end_year_label)
99
+
100
+ start_month = widgets.IntSlider(
101
+ description="Start Month:",
102
+ value=5,
103
+ min=1,
104
+ max=12,
105
+ readout=False,
106
+ style=style,
107
+ layout=widgets.Layout(width="145px", padding=padding),
108
+ )
109
+
110
+ start_month_label = widgets.Label(
111
+ "5",
112
+ layout=widgets.Layout(width="20px", padding=padding),
113
+ )
114
+ jslink_slider_label(start_month, start_month_label)
115
+
116
+ end_month = widgets.IntSlider(
117
+ description="End Month:",
118
+ value=10,
119
+ min=1,
120
+ max=12,
121
+ readout=False,
122
+ style=style,
123
+ layout=widgets.Layout(width="155px", padding=padding),
124
+ )
125
+
126
+ end_month_label = widgets.Label("10")
127
+ jslink_slider_label(end_month, end_month_label)
128
+
129
+ output = widgets.Output()
130
+
131
+ button_width = "113px"
132
+ apply_btn = widgets.Button(
133
+ description="Time slider",
134
+ button_style="primary",
135
+ tooltip="Click to create timeseries",
136
+ style=style,
137
+ layout=widgets.Layout(padding="0px", width=button_width),
138
+ )
139
+
140
+ split_btn = widgets.Button(
141
+ description="Split map",
142
+ button_style="primary",
143
+ tooltip="Click to create timeseries",
144
+ style=style,
145
+ layout=widgets.Layout(padding="0px", width=button_width),
146
+ )
147
+
148
+ reset_btn = widgets.Button(
149
+ description="Reset",
150
+ button_style="primary",
151
+ style=style,
152
+ layout=widgets.Layout(padding="0px", width=button_width),
153
+ )
154
+
155
+ vbox = widgets.VBox(
156
+ [
157
+ collection,
158
+ widgets.HBox([bands, frequency]),
159
+ widgets.HBox([start_year, start_year_label, end_year, end_year_label]),
160
+ widgets.HBox(
161
+ [start_month, start_month_label, end_month, end_month_label]
162
+ ),
163
+ widgets.HBox([apply_btn, split_btn, reset_btn]),
164
+ output,
165
+ ]
166
+ )
167
+ self.add_widget(vbox, position=position, add_header=True)
168
+
169
+ def apply_btn_click(change):
170
+
171
+ if hasattr(self, "slider_ctrl") and self.slider_ctrl is not None:
172
+ self.remove(self.slider_ctrl)
173
+ delattr(self, "slider_ctrl")
174
+
175
+ with output:
176
+ output.clear_output()
177
+ if self.user_roi is None:
178
+ output.append_stdout("Please draw a ROI first.")
179
+ else:
180
+ output.append_stdout("Creating time series...")
181
+ collection = geemap.landsat_timeseries(
182
+ roi=self.user_roi,
183
+ start_year=start_year.value,
184
+ end_year=end_year.value,
185
+ start_date=str(start_month.value).zfill(2) + "-01",
186
+ end_date=str(end_month.value).zfill(2) + "-01",
187
+ frequency=frequency.value,
188
+ )
189
+ vis_params = {
190
+ "bands": bands.value.split("/"),
191
+ "min": 0,
192
+ "max": 0.4,
193
+ }
194
+
195
+ if frequency.value == "year":
196
+ date_format = "YYYY"
197
+ elif frequency.value == "quarter":
198
+ date_format = "YYYY-MM"
199
+ elif frequency.value == "month":
200
+ date_format = "YYYY-MM"
201
+
202
+ self.add_time_slider(
203
+ collection,
204
+ region=self.user_roi,
205
+ vis_params=vis_params,
206
+ date_format=date_format,
207
+ )
208
+ self._draw_control.clear()
209
+ draw_layer = self.find_layer("Drawn Features")
210
+ if draw_layer is not None:
211
+ self.remove(draw_layer)
212
+ output.clear_output()
213
+
214
+ apply_btn.on_click(apply_btn_click)
215
+
216
+ def split_btn_click(change):
217
+
218
+ if hasattr(self, "slider_ctrl") and self.slider_ctrl is not None:
219
+ self.remove(self.slider_ctrl)
220
+ delattr(self, "slider_ctrl")
221
+
222
+ with output:
223
+ output.clear_output()
224
+ if self.user_roi is None:
225
+ output.append_stdout("Please draw a ROI first.")
226
+ else:
227
+ output.append_stdout("Creating time series...")
228
+ collection = geemap.landsat_timeseries(
229
+ roi=self.user_roi,
230
+ start_year=start_year.value,
231
+ end_year=end_year.value,
232
+ start_date=str(start_month.value).zfill(2) + "-01",
233
+ end_date=str(end_month.value).zfill(2) + "-01",
234
+ frequency=frequency.value,
235
+ )
236
+ vis_params = {
237
+ "bands": bands.value.split("/"),
238
+ "min": 0,
239
+ "max": 0.4,
240
+ }
241
+
242
+ if frequency.value == "year":
243
+ date_format = "YYYY"
244
+ dates = geemap.image_dates(collection, date_format).getInfo()
245
+ elif frequency.value == "quarter":
246
+ date_format = "YYYY-MM"
247
+ dates = geemap.image_dates(collection, date_format).getInfo()
248
+ elif frequency.value == "month":
249
+ date_format = "YYYY-MM"
250
+ dates = geemap.image_dates(collection, date_format).getInfo()
251
+
252
+ self.ts_inspector(
253
+ collection,
254
+ left_names=dates,
255
+ left_vis=vis_params,
256
+ add_close_button=True,
257
+ )
258
+ output.clear_output()
259
+
260
+ self._draw_control.clear()
261
+ draw_layer = self.find_layer("Drawn Features")
262
+ if draw_layer is not None:
263
+ self.remove(draw_layer)
264
+
265
+ split_btn.on_click(split_btn_click)
266
+
267
+ def reset_btn_click(change):
268
+ output.clear_output()
269
+ self.clean_up()
270
+
271
+ reset_btn.on_click(reset_btn_click)
272
+
273
+
274
+ @solara.component
275
+ def Page():
276
+ with solara.Column(style={"min-width": "500px"}):
277
+ Map.element(
278
+ center=[20, -0],
279
+ zoom=2,
280
+ height="750px",
281
+ zoom_ctrl=False,
282
+ measure_ctrl=False,
283
+ )
pages/{02_jrc.py β†’ 03_jrc.py} RENAMED
File without changes
pages/03_plotting.py DELETED
@@ -1,41 +0,0 @@
1
- import os
2
- import ee
3
- import geemap
4
-
5
- import solara
6
-
7
-
8
- class Map(geemap.Map):
9
- def __init__(self, **kwargs):
10
- super().__init__(**kwargs)
11
- self.add_ee_data()
12
- self.add_plot_gui()
13
-
14
- def add_ee_data(self):
15
- landsat7 = ee.Image("LANDSAT/LE7_TOA_5YEAR/1999_2003").select(
16
- ["B1", "B2", "B3", "B4", "B5", "B7"]
17
- )
18
-
19
- landsat_vis = {"bands": ["B4", "B3", "B2"], "gamma": 1.4}
20
- self.addLayer(landsat7, landsat_vis, "Landsat")
21
-
22
- hyperion = ee.ImageCollection("EO1/HYPERION").filter(
23
- ee.Filter.date("2016-01-01", "2017-03-01")
24
- )
25
-
26
- hyperion_vis = {
27
- "min": 1000.0,
28
- "max": 14000.0,
29
- "gamma": 2.5,
30
- }
31
- self.addLayer(hyperion, hyperion_vis, "Hyperion")
32
-
33
-
34
- @solara.component
35
- def Page():
36
- with solara.Column(style={"min-width": "500px"}):
37
- Map.element(
38
- center=[40, -100],
39
- zoom=4,
40
- height="750px",
41
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pages/{03_landsat.py β†’ 04_compare.py} RENAMED
File without changes
pages/04_split_map.py DELETED
@@ -1,59 +0,0 @@
1
- import os
2
- import ee
3
- import geemap
4
-
5
- import solara
6
-
7
-
8
- class Map(geemap.Map):
9
- def __init__(self, **kwargs):
10
- super().__init__(**kwargs)
11
- self.add_ee_data()
12
-
13
- def add_ee_data(self):
14
- # Select the eight NLCD epochs after 2000.
15
- years = ["2001", "2004", "2006", "2008", "2011", "2013", "2016", "2019"]
16
-
17
- # Get an NLCD image by year.
18
- def getNLCD(year):
19
- # Import the NLCD collection.
20
- dataset = ee.ImageCollection("USGS/NLCD_RELEASES/2019_REL/NLCD")
21
-
22
- # Filter the collection by year.
23
- nlcd = dataset.filter(ee.Filter.eq("system:index", year)).first()
24
-
25
- # Select the land cover band.
26
- landcover = nlcd.select("landcover")
27
- return landcover
28
-
29
- ## Create an NLCD image collection for the selected years.
30
- collection = ee.ImageCollection(ee.List(years).map(lambda year: getNLCD(year)))
31
-
32
- # Create a list of labels to populate the dropdown list.
33
- labels = [f"NLCD {year}" for year in years]
34
-
35
- # Add a split-panel map for visualizing NLCD land cover change.
36
- self.ts_inspector(
37
- left_ts=collection,
38
- right_ts=collection,
39
- left_names=labels,
40
- right_names=labels,
41
- )
42
-
43
- # Add the NLCD legend to the map.
44
- self.add_legend(
45
- title="NLCD Land Cover Type",
46
- builtin_legend="NLCD",
47
- height="460px",
48
- add_header=False,
49
- )
50
-
51
-
52
- @solara.component
53
- def Page():
54
- with solara.Column(style={"min-width": "500px"}):
55
- Map.element(
56
- center=[40, -100],
57
- zoom=4,
58
- height="750px",
59
- )