giswqs commited on
Commit
9beed3c
·
1 Parent(s): 0c0e9ec

Add helen and milton apps

Browse files
Files changed (5) hide show
  1. pages/01_morocco.py +66 -55
  2. pages/02_libya.py +66 -55
  3. pages/03_maui.py +66 -55
  4. pages/04_helen.py +274 -0
  5. pages/05_milton.py +275 -0
pages/01_morocco.py CHANGED
@@ -7,28 +7,28 @@ import geopandas as gpd
7
  import tempfile
8
  from shapely.geometry import Point
9
 
10
- event = 'Morocco-Earthquake-Sept-2023'
11
- url = 'https://raw.githubusercontent.com/opengeos/maxar-open-data/master'
12
- repo = 'https://github.com/opengeos/maxar-open-data/blob/master/datasets'
13
 
14
 
15
  def get_datasets():
16
- datasets = f'{url}/datasets.csv'
17
  df = pd.read_csv(datasets)
18
  return df
19
 
20
 
21
  def get_catalogs(name):
22
- dataset = f'{url}/datasets/{name}.tsv'
23
  basename = os.path.basename(dataset)
24
  tempdir = tempfile.gettempdir()
25
  tmp_dataset = os.path.join(tempdir, basename)
26
  if os.path.exists(tmp_dataset):
27
- dataset_df = pd.read_csv(tmp_dataset, sep='\t')
28
  else:
29
- dataset_df = pd.read_csv(dataset, sep='\t')
30
- dataset_df.to_csv(tmp_dataset, sep='\t', index=False)
31
- catalog_ids = dataset_df['catalog_id'].unique().tolist()
32
  catalog_ids.sort()
33
  return catalog_ids
34
 
@@ -36,30 +36,30 @@ def get_catalogs(name):
36
  def get_image_date(catalog_id, m):
37
  gdf = m.footprint
38
  image_date = pd.Timestamp(
39
- gdf[gdf['catalog_id'] == catalog_id]['datetime'].values[0]
40
- ).strftime('%Y-%m-%d %H:%M:%S')
41
  return image_date
42
 
43
 
44
  def add_widgets(m):
45
- datasets = get_datasets()['dataset'].tolist()
46
- setattr(m, 'zoom_to_layer', True)
47
  style = {"description_width": "initial"}
48
  padding = "0px 0px 0px 5px"
49
  dataset = widgets.Dropdown(
50
  options=datasets,
51
- description='Event:',
52
  value=event,
53
  style=style,
54
  layout=widgets.Layout(width="270px", padding=padding),
55
  )
56
 
57
  catalog_ids = get_catalogs(dataset.value)
58
- setattr(m, 'catalog_ids', catalog_ids)
59
 
60
  date_picker = widgets.DatePicker(
61
- description='Start date:',
62
- value=pd.to_datetime('2021-01-01').date(),
63
  style=style,
64
  layout=widgets.Layout(width="270px", padding=padding),
65
  )
@@ -67,30 +67,30 @@ def add_widgets(m):
67
  image = widgets.Dropdown(
68
  value=None,
69
  options=m.catalog_ids,
70
- description='Image:',
71
  style=style,
72
  layout=widgets.Layout(width="270px", padding=padding),
73
  )
74
 
75
  checkbox = widgets.Checkbox(
76
  value=True,
77
- description='Footprints',
78
  style=style,
79
  layout=widgets.Layout(width="90px", padding="0px"),
80
  )
81
 
82
  split = widgets.Checkbox(
83
  value=False,
84
- description='Split map',
85
  style=style,
86
  layout=widgets.Layout(width="92px", padding=padding),
87
  )
88
 
89
  reset = widgets.Checkbox(
90
  value=False,
91
- description='Reset',
92
  style=style,
93
- layout=widgets.Layout(width="75px", padding='0px'),
94
  )
95
 
96
  output = widgets.Output()
@@ -102,19 +102,23 @@ def add_widgets(m):
102
  m.layers = m.layers[:3]
103
  m.zoom_to_layer = True
104
  reset.value = False
105
- date_picker.value = pd.to_datetime('2021-01-01').date()
106
- m.remove_layer(m.find_layer('Footprint'))
 
107
  m.add_gdf(
108
- m.footprint, layer_name='Footprint', zoom_to_layer=False, info_mode=None
 
 
 
109
  )
110
- satellite_layer = m.find_layer('Google Satellite')
111
  satellite_layer.visible = False
112
  output.outputs = ()
113
 
114
- reset.observe(reset_map, names='value')
115
 
116
  def change_dataset(change):
117
- default_geojson = f'{url}/datasets/{change.new}_union.geojson'
118
  m.layers = m.layers[:2]
119
  m.controls = m.controls[:-1]
120
  basename = os.path.basename(default_geojson)
@@ -124,54 +128,58 @@ def add_widgets(m):
124
  default_geojson = tmp_geojson
125
  else:
126
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
127
- m.add_geojson(default_geojson, layer_name='Footprint', zoom_to_layer=True)
128
- setattr(m, 'gdf', gpd.read_file(default_geojson))
129
 
130
  image.options = get_catalogs(change.new)
131
 
132
- dataset.observe(change_dataset, names='value')
133
 
134
  def change_date(change):
135
  if change.new:
136
- start_date = change.new.strftime('%Y-%m-%d')
137
- sub_gdf = m.gdf[m.gdf['datetime'] >= start_date]
138
- sub_catalog_ids = sub_gdf['catalog_id'].values.tolist()
139
  image.options = sub_catalog_ids
140
- m.remove_layer(m.find_layer('Footprint'))
 
141
  m.add_gdf(
142
- sub_gdf, layer_name='Footprint', zoom_to_layer=False, info_mode=None
 
 
 
143
  )
144
  m.gdf = sub_gdf
145
 
146
- date_picker.observe(change_date, names='value')
147
 
148
  def change_image(change):
149
  if change.new:
150
  if change.new not in m.get_layer_names():
151
- mosaic = f'{url}/datasets/{dataset.value}/{image.value}.json'
152
  m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
153
  image_date = get_image_date(image.value, m)
154
  output.outputs = ()
155
  output.append_stdout(f"Image date: {image_date}\n")
156
 
157
- image.observe(change_image, names='value')
158
 
159
  def change_footprint(change):
160
- geojson_layer = m.find_layer('Footprint')
161
  if change.new:
162
  geojson_layer.visible = True
163
  else:
164
  geojson_layer.visible = False
165
 
166
- checkbox.observe(change_footprint, names='value')
167
 
168
  def change_split(change):
169
  if change.new:
170
  if image.value is not None:
171
  left_layer = m.find_layer(image.value)
172
- right_layer = m.find_layer('Google Satellite')
173
  right_layer.visible = True
174
- footprint_layer = m.find_layer('Footprint')
175
  footprint_layer.visible = False
176
  checkbox.value = False
177
  m.split_map(
@@ -179,22 +187,22 @@ def add_widgets(m):
179
  right_layer=right_layer,
180
  add_close_button=True,
181
  left_label=image.value,
182
- right_label='Google Satellite',
183
  )
184
  split.value = False
185
  else:
186
  left_layer = None
187
 
188
- split.observe(change_split, names='value')
189
 
190
  def handle_click(**kwargs):
191
- if kwargs.get('type') == 'click':
192
- latlon = kwargs.get('coordinates')
193
  geometry = Point(latlon[::-1])
194
  selected = m.gdf[m.gdf.intersects(geometry)]
195
- setattr(m, 'zoom_to_layer', False)
196
  if len(selected) > 0:
197
- catalog_ids = selected['catalog_id'].values.tolist()
198
 
199
  if len(catalog_ids) > 1:
200
  image.options = catalog_ids
@@ -207,7 +215,7 @@ def add_widgets(m):
207
  box = widgets.VBox(
208
  [dataset, date_picker, image, widgets.HBox([checkbox, split, reset]), output]
209
  )
210
- m.add_widget(box, position='topright', add_header=False)
211
 
212
 
213
  zoom = solara.reactive(2)
@@ -216,7 +224,7 @@ center = solara.reactive((20, 0))
216
 
217
  class Map(leafmap.Map):
218
  def __init__(self, **kwargs):
219
- kwargs['toolbar_control'] = False
220
  super().__init__(**kwargs)
221
  basemap = {
222
  "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
@@ -226,7 +234,7 @@ class Map(leafmap.Map):
226
  self.add_tile_layer(**basemap, shown=False)
227
  self.add_layer_manager(opened=False)
228
  add_widgets(self)
229
- default_geojson = f'{url}/datasets/{event}_union.geojson'
230
  basename = os.path.basename(default_geojson)
231
  tempdir = tempfile.gettempdir()
232
  tmp_geojson = os.path.join(tempdir, basename)
@@ -235,11 +243,14 @@ class Map(leafmap.Map):
235
  else:
236
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
237
  self.add_geojson(
238
- default_geojson, layer_name='Footprint', zoom_to_layer=True, info_mode=None
 
 
 
239
  )
240
  gdf = gpd.read_file(default_geojson)
241
- setattr(self, 'gdf', gdf)
242
- setattr(self, 'footprint', gdf)
243
 
244
 
245
  @solara.component
 
7
  import tempfile
8
  from shapely.geometry import Point
9
 
10
+ event = "Morocco-Earthquake-Sept-2023"
11
+ url = "https://raw.githubusercontent.com/opengeos/maxar-open-data/master"
12
+ repo = "https://github.com/opengeos/maxar-open-data/blob/master/datasets"
13
 
14
 
15
  def get_datasets():
16
+ datasets = f"{url}/datasets.csv"
17
  df = pd.read_csv(datasets)
18
  return df
19
 
20
 
21
  def get_catalogs(name):
22
+ dataset = f"{url}/datasets/{name}.tsv"
23
  basename = os.path.basename(dataset)
24
  tempdir = tempfile.gettempdir()
25
  tmp_dataset = os.path.join(tempdir, basename)
26
  if os.path.exists(tmp_dataset):
27
+ dataset_df = pd.read_csv(tmp_dataset, sep="\t")
28
  else:
29
+ dataset_df = pd.read_csv(dataset, sep="\t")
30
+ dataset_df.to_csv(tmp_dataset, sep="\t", index=False)
31
+ catalog_ids = dataset_df["catalog_id"].unique().tolist()
32
  catalog_ids.sort()
33
  return catalog_ids
34
 
 
36
  def get_image_date(catalog_id, m):
37
  gdf = m.footprint
38
  image_date = pd.Timestamp(
39
+ gdf[gdf["catalog_id"] == catalog_id]["datetime"].values[0]
40
+ ).strftime("%Y-%m-%d %H:%M:%S")
41
  return image_date
42
 
43
 
44
  def add_widgets(m):
45
+ datasets = get_datasets()["dataset"].tolist()
46
+ setattr(m, "zoom_to_layer", True)
47
  style = {"description_width": "initial"}
48
  padding = "0px 0px 0px 5px"
49
  dataset = widgets.Dropdown(
50
  options=datasets,
51
+ description="Event:",
52
  value=event,
53
  style=style,
54
  layout=widgets.Layout(width="270px", padding=padding),
55
  )
56
 
57
  catalog_ids = get_catalogs(dataset.value)
58
+ setattr(m, "catalog_ids", catalog_ids)
59
 
60
  date_picker = widgets.DatePicker(
61
+ description="Start date:",
62
+ value=pd.to_datetime("2021-01-01").date(),
63
  style=style,
64
  layout=widgets.Layout(width="270px", padding=padding),
65
  )
 
67
  image = widgets.Dropdown(
68
  value=None,
69
  options=m.catalog_ids,
70
+ description="Image:",
71
  style=style,
72
  layout=widgets.Layout(width="270px", padding=padding),
73
  )
74
 
75
  checkbox = widgets.Checkbox(
76
  value=True,
77
+ description="Footprints",
78
  style=style,
79
  layout=widgets.Layout(width="90px", padding="0px"),
80
  )
81
 
82
  split = widgets.Checkbox(
83
  value=False,
84
+ description="Split map",
85
  style=style,
86
  layout=widgets.Layout(width="92px", padding=padding),
87
  )
88
 
89
  reset = widgets.Checkbox(
90
  value=False,
91
+ description="Reset",
92
  style=style,
93
+ layout=widgets.Layout(width="75px", padding="0px"),
94
  )
95
 
96
  output = widgets.Output()
 
102
  m.layers = m.layers[:3]
103
  m.zoom_to_layer = True
104
  reset.value = False
105
+ date_picker.value = pd.to_datetime("2021-01-01").date()
106
+ m.remove_layer(m.find_layer("Footprint"))
107
+ m.controls = m.controls[:-1]
108
  m.add_gdf(
109
+ m.footprint,
110
+ layer_name="Footprint",
111
+ zoom_to_layer=False,
112
+ info_mode="on_hover",
113
  )
114
+ satellite_layer = m.find_layer("Google Satellite")
115
  satellite_layer.visible = False
116
  output.outputs = ()
117
 
118
+ reset.observe(reset_map, names="value")
119
 
120
  def change_dataset(change):
121
+ default_geojson = f"{url}/datasets/{change.new}_union.geojson"
122
  m.layers = m.layers[:2]
123
  m.controls = m.controls[:-1]
124
  basename = os.path.basename(default_geojson)
 
128
  default_geojson = tmp_geojson
129
  else:
130
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
131
+ m.add_geojson(default_geojson, layer_name="Footprint", zoom_to_layer=True)
132
+ setattr(m, "gdf", gpd.read_file(default_geojson))
133
 
134
  image.options = get_catalogs(change.new)
135
 
136
+ dataset.observe(change_dataset, names="value")
137
 
138
  def change_date(change):
139
  if change.new:
140
+ start_date = change.new.strftime("%Y-%m-%d")
141
+ sub_gdf = m.gdf[m.gdf["datetime"] >= start_date]
142
+ sub_catalog_ids = sub_gdf["catalog_id"].values.tolist()
143
  image.options = sub_catalog_ids
144
+ m.remove_layer(m.find_layer("Footprint"))
145
+ m.controls = m.controls[:-1]
146
  m.add_gdf(
147
+ sub_gdf,
148
+ layer_name="Footprint",
149
+ zoom_to_layer=False,
150
+ info_mode="on_hover",
151
  )
152
  m.gdf = sub_gdf
153
 
154
+ date_picker.observe(change_date, names="value")
155
 
156
  def change_image(change):
157
  if change.new:
158
  if change.new not in m.get_layer_names():
159
+ mosaic = f"{url}/datasets/{dataset.value}/{image.value}.json"
160
  m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
161
  image_date = get_image_date(image.value, m)
162
  output.outputs = ()
163
  output.append_stdout(f"Image date: {image_date}\n")
164
 
165
+ image.observe(change_image, names="value")
166
 
167
  def change_footprint(change):
168
+ geojson_layer = m.find_layer("Footprint")
169
  if change.new:
170
  geojson_layer.visible = True
171
  else:
172
  geojson_layer.visible = False
173
 
174
+ checkbox.observe(change_footprint, names="value")
175
 
176
  def change_split(change):
177
  if change.new:
178
  if image.value is not None:
179
  left_layer = m.find_layer(image.value)
180
+ right_layer = m.find_layer("Google Satellite")
181
  right_layer.visible = True
182
+ footprint_layer = m.find_layer("Footprint")
183
  footprint_layer.visible = False
184
  checkbox.value = False
185
  m.split_map(
 
187
  right_layer=right_layer,
188
  add_close_button=True,
189
  left_label=image.value,
190
+ right_label="Google Satellite",
191
  )
192
  split.value = False
193
  else:
194
  left_layer = None
195
 
196
+ split.observe(change_split, names="value")
197
 
198
  def handle_click(**kwargs):
199
+ if kwargs.get("type") == "click":
200
+ latlon = kwargs.get("coordinates")
201
  geometry = Point(latlon[::-1])
202
  selected = m.gdf[m.gdf.intersects(geometry)]
203
+ setattr(m, "zoom_to_layer", False)
204
  if len(selected) > 0:
205
+ catalog_ids = selected["catalog_id"].values.tolist()
206
 
207
  if len(catalog_ids) > 1:
208
  image.options = catalog_ids
 
215
  box = widgets.VBox(
216
  [dataset, date_picker, image, widgets.HBox([checkbox, split, reset]), output]
217
  )
218
+ m.add_widget(box, position="topright", add_header=False)
219
 
220
 
221
  zoom = solara.reactive(2)
 
224
 
225
  class Map(leafmap.Map):
226
  def __init__(self, **kwargs):
227
+ kwargs["toolbar_control"] = False
228
  super().__init__(**kwargs)
229
  basemap = {
230
  "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
 
234
  self.add_tile_layer(**basemap, shown=False)
235
  self.add_layer_manager(opened=False)
236
  add_widgets(self)
237
+ default_geojson = f"{url}/datasets/{event}_union.geojson"
238
  basename = os.path.basename(default_geojson)
239
  tempdir = tempfile.gettempdir()
240
  tmp_geojson = os.path.join(tempdir, basename)
 
243
  else:
244
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
245
  self.add_geojson(
246
+ default_geojson,
247
+ layer_name="Footprint",
248
+ zoom_to_layer=True,
249
+ info_mode="on_hover",
250
  )
251
  gdf = gpd.read_file(default_geojson)
252
+ setattr(self, "gdf", gdf)
253
+ setattr(self, "footprint", gdf)
254
 
255
 
256
  @solara.component
pages/02_libya.py CHANGED
@@ -7,28 +7,28 @@ import geopandas as gpd
7
  import tempfile
8
  from shapely.geometry import Point
9
 
10
- event = 'Libya-Floods-Sept-2023'
11
- url = 'https://raw.githubusercontent.com/opengeos/maxar-open-data/master'
12
- repo = 'https://github.com/opengeos/maxar-open-data/blob/master/datasets'
13
 
14
 
15
  def get_datasets():
16
- datasets = f'{url}/datasets.csv'
17
  df = pd.read_csv(datasets)
18
  return df
19
 
20
 
21
  def get_catalogs(name):
22
- dataset = f'{url}/datasets/{name}.tsv'
23
  basename = os.path.basename(dataset)
24
  tempdir = tempfile.gettempdir()
25
  tmp_dataset = os.path.join(tempdir, basename)
26
  if os.path.exists(tmp_dataset):
27
- dataset_df = pd.read_csv(tmp_dataset, sep='\t')
28
  else:
29
- dataset_df = pd.read_csv(dataset, sep='\t')
30
- dataset_df.to_csv(tmp_dataset, sep='\t', index=False)
31
- catalog_ids = dataset_df['catalog_id'].unique().tolist()
32
  catalog_ids.sort()
33
  return catalog_ids
34
 
@@ -36,30 +36,30 @@ def get_catalogs(name):
36
  def get_image_date(catalog_id, m):
37
  gdf = m.footprint
38
  image_date = pd.Timestamp(
39
- gdf[gdf['catalog_id'] == catalog_id]['datetime'].values[0]
40
- ).strftime('%Y-%m-%d %H:%M:%S')
41
  return image_date
42
 
43
 
44
  def add_widgets(m):
45
- datasets = get_datasets()['dataset'].tolist()
46
- setattr(m, 'zoom_to_layer', True)
47
  style = {"description_width": "initial"}
48
  padding = "0px 0px 0px 5px"
49
  dataset = widgets.Dropdown(
50
  options=datasets,
51
- description='Event:',
52
  value=event,
53
  style=style,
54
  layout=widgets.Layout(width="270px", padding=padding),
55
  )
56
 
57
  catalog_ids = get_catalogs(dataset.value)
58
- setattr(m, 'catalog_ids', catalog_ids)
59
 
60
  date_picker = widgets.DatePicker(
61
- description='Start date:',
62
- value=pd.to_datetime('2021-01-01').date(),
63
  style=style,
64
  layout=widgets.Layout(width="270px", padding=padding),
65
  )
@@ -67,30 +67,30 @@ def add_widgets(m):
67
  image = widgets.Dropdown(
68
  value=None,
69
  options=m.catalog_ids,
70
- description='Image:',
71
  style=style,
72
  layout=widgets.Layout(width="270px", padding=padding),
73
  )
74
 
75
  checkbox = widgets.Checkbox(
76
  value=True,
77
- description='Footprints',
78
  style=style,
79
  layout=widgets.Layout(width="90px", padding="0px"),
80
  )
81
 
82
  split = widgets.Checkbox(
83
  value=False,
84
- description='Split map',
85
  style=style,
86
  layout=widgets.Layout(width="92px", padding=padding),
87
  )
88
 
89
  reset = widgets.Checkbox(
90
  value=False,
91
- description='Reset',
92
  style=style,
93
- layout=widgets.Layout(width="75px", padding='0px'),
94
  )
95
 
96
  output = widgets.Output()
@@ -102,19 +102,23 @@ def add_widgets(m):
102
  m.layers = m.layers[:3]
103
  m.zoom_to_layer = True
104
  reset.value = False
105
- date_picker.value = pd.to_datetime('2021-01-01').date()
106
- m.remove_layer(m.find_layer('Footprint'))
 
107
  m.add_gdf(
108
- m.footprint, layer_name='Footprint', zoom_to_layer=False, info_mode=None
 
 
 
109
  )
110
- satellite_layer = m.find_layer('Google Satellite')
111
  satellite_layer.visible = False
112
  output.outputs = ()
113
 
114
- reset.observe(reset_map, names='value')
115
 
116
  def change_dataset(change):
117
- default_geojson = f'{url}/datasets/{change.new}_union.geojson'
118
  m.layers = m.layers[:2]
119
  m.controls = m.controls[:-1]
120
  basename = os.path.basename(default_geojson)
@@ -124,54 +128,58 @@ def add_widgets(m):
124
  default_geojson = tmp_geojson
125
  else:
126
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
127
- m.add_geojson(default_geojson, layer_name='Footprint', zoom_to_layer=True)
128
- setattr(m, 'gdf', gpd.read_file(default_geojson))
129
 
130
  image.options = get_catalogs(change.new)
131
 
132
- dataset.observe(change_dataset, names='value')
133
 
134
  def change_date(change):
135
  if change.new:
136
- start_date = change.new.strftime('%Y-%m-%d')
137
- sub_gdf = m.gdf[m.gdf['datetime'] >= start_date]
138
- sub_catalog_ids = sub_gdf['catalog_id'].values.tolist()
139
  image.options = sub_catalog_ids
140
- m.remove_layer(m.find_layer('Footprint'))
 
141
  m.add_gdf(
142
- sub_gdf, layer_name='Footprint', zoom_to_layer=False, info_mode=None
 
 
 
143
  )
144
  m.gdf = sub_gdf
145
 
146
- date_picker.observe(change_date, names='value')
147
 
148
  def change_image(change):
149
  if change.new:
150
  if change.new not in m.get_layer_names():
151
- mosaic = f'{url}/datasets/{dataset.value}/{image.value}.json'
152
  m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
153
  image_date = get_image_date(image.value, m)
154
  output.outputs = ()
155
  output.append_stdout(f"Image date: {image_date}\n")
156
 
157
- image.observe(change_image, names='value')
158
 
159
  def change_footprint(change):
160
- geojson_layer = m.find_layer('Footprint')
161
  if change.new:
162
  geojson_layer.visible = True
163
  else:
164
  geojson_layer.visible = False
165
 
166
- checkbox.observe(change_footprint, names='value')
167
 
168
  def change_split(change):
169
  if change.new:
170
  if image.value is not None:
171
  left_layer = m.find_layer(image.value)
172
- right_layer = m.find_layer('Google Satellite')
173
  right_layer.visible = True
174
- footprint_layer = m.find_layer('Footprint')
175
  footprint_layer.visible = False
176
  checkbox.value = False
177
  m.split_map(
@@ -179,22 +187,22 @@ def add_widgets(m):
179
  right_layer=right_layer,
180
  add_close_button=True,
181
  left_label=image.value,
182
- right_label='Google Satellite',
183
  )
184
  split.value = False
185
  else:
186
  left_layer = None
187
 
188
- split.observe(change_split, names='value')
189
 
190
  def handle_click(**kwargs):
191
- if kwargs.get('type') == 'click':
192
- latlon = kwargs.get('coordinates')
193
  geometry = Point(latlon[::-1])
194
  selected = m.gdf[m.gdf.intersects(geometry)]
195
- setattr(m, 'zoom_to_layer', False)
196
  if len(selected) > 0:
197
- catalog_ids = selected['catalog_id'].values.tolist()
198
 
199
  if len(catalog_ids) > 1:
200
  image.options = catalog_ids
@@ -207,7 +215,7 @@ def add_widgets(m):
207
  box = widgets.VBox(
208
  [dataset, date_picker, image, widgets.HBox([checkbox, split, reset]), output]
209
  )
210
- m.add_widget(box, position='topright', add_header=False)
211
 
212
 
213
  zoom = solara.reactive(2)
@@ -216,7 +224,7 @@ center = solara.reactive((20, 0))
216
 
217
  class Map(leafmap.Map):
218
  def __init__(self, **kwargs):
219
- kwargs['toolbar_control'] = False
220
  super().__init__(**kwargs)
221
  basemap = {
222
  "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
@@ -226,7 +234,7 @@ class Map(leafmap.Map):
226
  self.add_tile_layer(**basemap, shown=False)
227
  self.add_layer_manager(opened=False)
228
  add_widgets(self)
229
- default_geojson = f'{url}/datasets/{event}_union.geojson'
230
  basename = os.path.basename(default_geojson)
231
  tempdir = tempfile.gettempdir()
232
  tmp_geojson = os.path.join(tempdir, basename)
@@ -235,11 +243,14 @@ class Map(leafmap.Map):
235
  else:
236
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
237
  self.add_geojson(
238
- default_geojson, layer_name='Footprint', zoom_to_layer=True, info_mode=None
 
 
 
239
  )
240
  gdf = gpd.read_file(default_geojson)
241
- setattr(self, 'gdf', gdf)
242
- setattr(self, 'footprint', gdf)
243
 
244
 
245
  @solara.component
 
7
  import tempfile
8
  from shapely.geometry import Point
9
 
10
+ event = "Libya-Floods-Sept-2023"
11
+ url = "https://raw.githubusercontent.com/opengeos/maxar-open-data/master"
12
+ repo = "https://github.com/opengeos/maxar-open-data/blob/master/datasets"
13
 
14
 
15
  def get_datasets():
16
+ datasets = f"{url}/datasets.csv"
17
  df = pd.read_csv(datasets)
18
  return df
19
 
20
 
21
  def get_catalogs(name):
22
+ dataset = f"{url}/datasets/{name}.tsv"
23
  basename = os.path.basename(dataset)
24
  tempdir = tempfile.gettempdir()
25
  tmp_dataset = os.path.join(tempdir, basename)
26
  if os.path.exists(tmp_dataset):
27
+ dataset_df = pd.read_csv(tmp_dataset, sep="\t")
28
  else:
29
+ dataset_df = pd.read_csv(dataset, sep="\t")
30
+ dataset_df.to_csv(tmp_dataset, sep="\t", index=False)
31
+ catalog_ids = dataset_df["catalog_id"].unique().tolist()
32
  catalog_ids.sort()
33
  return catalog_ids
34
 
 
36
  def get_image_date(catalog_id, m):
37
  gdf = m.footprint
38
  image_date = pd.Timestamp(
39
+ gdf[gdf["catalog_id"] == catalog_id]["datetime"].values[0]
40
+ ).strftime("%Y-%m-%d %H:%M:%S")
41
  return image_date
42
 
43
 
44
  def add_widgets(m):
45
+ datasets = get_datasets()["dataset"].tolist()
46
+ setattr(m, "zoom_to_layer", True)
47
  style = {"description_width": "initial"}
48
  padding = "0px 0px 0px 5px"
49
  dataset = widgets.Dropdown(
50
  options=datasets,
51
+ description="Event:",
52
  value=event,
53
  style=style,
54
  layout=widgets.Layout(width="270px", padding=padding),
55
  )
56
 
57
  catalog_ids = get_catalogs(dataset.value)
58
+ setattr(m, "catalog_ids", catalog_ids)
59
 
60
  date_picker = widgets.DatePicker(
61
+ description="Start date:",
62
+ value=pd.to_datetime("2021-01-01").date(),
63
  style=style,
64
  layout=widgets.Layout(width="270px", padding=padding),
65
  )
 
67
  image = widgets.Dropdown(
68
  value=None,
69
  options=m.catalog_ids,
70
+ description="Image:",
71
  style=style,
72
  layout=widgets.Layout(width="270px", padding=padding),
73
  )
74
 
75
  checkbox = widgets.Checkbox(
76
  value=True,
77
+ description="Footprints",
78
  style=style,
79
  layout=widgets.Layout(width="90px", padding="0px"),
80
  )
81
 
82
  split = widgets.Checkbox(
83
  value=False,
84
+ description="Split map",
85
  style=style,
86
  layout=widgets.Layout(width="92px", padding=padding),
87
  )
88
 
89
  reset = widgets.Checkbox(
90
  value=False,
91
+ description="Reset",
92
  style=style,
93
+ layout=widgets.Layout(width="75px", padding="0px"),
94
  )
95
 
96
  output = widgets.Output()
 
102
  m.layers = m.layers[:3]
103
  m.zoom_to_layer = True
104
  reset.value = False
105
+ date_picker.value = pd.to_datetime("2021-01-01").date()
106
+ m.remove_layer(m.find_layer("Footprint"))
107
+ m.controls = m.controls[:-1]
108
  m.add_gdf(
109
+ m.footprint,
110
+ layer_name="Footprint",
111
+ zoom_to_layer=False,
112
+ info_mode="on_hover",
113
  )
114
+ satellite_layer = m.find_layer("Google Satellite")
115
  satellite_layer.visible = False
116
  output.outputs = ()
117
 
118
+ reset.observe(reset_map, names="value")
119
 
120
  def change_dataset(change):
121
+ default_geojson = f"{url}/datasets/{change.new}_union.geojson"
122
  m.layers = m.layers[:2]
123
  m.controls = m.controls[:-1]
124
  basename = os.path.basename(default_geojson)
 
128
  default_geojson = tmp_geojson
129
  else:
130
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
131
+ m.add_geojson(default_geojson, layer_name="Footprint", zoom_to_layer=True)
132
+ setattr(m, "gdf", gpd.read_file(default_geojson))
133
 
134
  image.options = get_catalogs(change.new)
135
 
136
+ dataset.observe(change_dataset, names="value")
137
 
138
  def change_date(change):
139
  if change.new:
140
+ start_date = change.new.strftime("%Y-%m-%d")
141
+ sub_gdf = m.gdf[m.gdf["datetime"] >= start_date]
142
+ sub_catalog_ids = sub_gdf["catalog_id"].values.tolist()
143
  image.options = sub_catalog_ids
144
+ m.remove_layer(m.find_layer("Footprint"))
145
+ m.controls = m.controls[:-1]
146
  m.add_gdf(
147
+ sub_gdf,
148
+ layer_name="Footprint",
149
+ zoom_to_layer=False,
150
+ info_mode="on_hover",
151
  )
152
  m.gdf = sub_gdf
153
 
154
+ date_picker.observe(change_date, names="value")
155
 
156
  def change_image(change):
157
  if change.new:
158
  if change.new not in m.get_layer_names():
159
+ mosaic = f"{url}/datasets/{dataset.value}/{image.value}.json"
160
  m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
161
  image_date = get_image_date(image.value, m)
162
  output.outputs = ()
163
  output.append_stdout(f"Image date: {image_date}\n")
164
 
165
+ image.observe(change_image, names="value")
166
 
167
  def change_footprint(change):
168
+ geojson_layer = m.find_layer("Footprint")
169
  if change.new:
170
  geojson_layer.visible = True
171
  else:
172
  geojson_layer.visible = False
173
 
174
+ checkbox.observe(change_footprint, names="value")
175
 
176
  def change_split(change):
177
  if change.new:
178
  if image.value is not None:
179
  left_layer = m.find_layer(image.value)
180
+ right_layer = m.find_layer("Google Satellite")
181
  right_layer.visible = True
182
+ footprint_layer = m.find_layer("Footprint")
183
  footprint_layer.visible = False
184
  checkbox.value = False
185
  m.split_map(
 
187
  right_layer=right_layer,
188
  add_close_button=True,
189
  left_label=image.value,
190
+ right_label="Google Satellite",
191
  )
192
  split.value = False
193
  else:
194
  left_layer = None
195
 
196
+ split.observe(change_split, names="value")
197
 
198
  def handle_click(**kwargs):
199
+ if kwargs.get("type") == "click":
200
+ latlon = kwargs.get("coordinates")
201
  geometry = Point(latlon[::-1])
202
  selected = m.gdf[m.gdf.intersects(geometry)]
203
+ setattr(m, "zoom_to_layer", False)
204
  if len(selected) > 0:
205
+ catalog_ids = selected["catalog_id"].values.tolist()
206
 
207
  if len(catalog_ids) > 1:
208
  image.options = catalog_ids
 
215
  box = widgets.VBox(
216
  [dataset, date_picker, image, widgets.HBox([checkbox, split, reset]), output]
217
  )
218
+ m.add_widget(box, position="topright", add_header=False)
219
 
220
 
221
  zoom = solara.reactive(2)
 
224
 
225
  class Map(leafmap.Map):
226
  def __init__(self, **kwargs):
227
+ kwargs["toolbar_control"] = False
228
  super().__init__(**kwargs)
229
  basemap = {
230
  "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
 
234
  self.add_tile_layer(**basemap, shown=False)
235
  self.add_layer_manager(opened=False)
236
  add_widgets(self)
237
+ default_geojson = f"{url}/datasets/{event}_union.geojson"
238
  basename = os.path.basename(default_geojson)
239
  tempdir = tempfile.gettempdir()
240
  tmp_geojson = os.path.join(tempdir, basename)
 
243
  else:
244
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
245
  self.add_geojson(
246
+ default_geojson,
247
+ layer_name="Footprint",
248
+ zoom_to_layer=True,
249
+ info_mode="on_hover",
250
  )
251
  gdf = gpd.read_file(default_geojson)
252
+ setattr(self, "gdf", gdf)
253
+ setattr(self, "footprint", gdf)
254
 
255
 
256
  @solara.component
pages/03_maui.py CHANGED
@@ -7,28 +7,28 @@ import geopandas as gpd
7
  import tempfile
8
  from shapely.geometry import Point
9
 
10
- event = 'Maui-Hawaii-fires-Aug-23'
11
- url = 'https://raw.githubusercontent.com/opengeos/maxar-open-data/master'
12
- repo = 'https://github.com/opengeos/maxar-open-data/blob/master/datasets'
13
 
14
 
15
  def get_datasets():
16
- datasets = f'{url}/datasets.csv'
17
  df = pd.read_csv(datasets)
18
  return df
19
 
20
 
21
  def get_catalogs(name):
22
- dataset = f'{url}/datasets/{name}.tsv'
23
  basename = os.path.basename(dataset)
24
  tempdir = tempfile.gettempdir()
25
  tmp_dataset = os.path.join(tempdir, basename)
26
  if os.path.exists(tmp_dataset):
27
- dataset_df = pd.read_csv(tmp_dataset, sep='\t')
28
  else:
29
- dataset_df = pd.read_csv(dataset, sep='\t')
30
- dataset_df.to_csv(tmp_dataset, sep='\t', index=False)
31
- catalog_ids = dataset_df['catalog_id'].unique().tolist()
32
  catalog_ids.sort()
33
  return catalog_ids
34
 
@@ -36,30 +36,30 @@ def get_catalogs(name):
36
  def get_image_date(catalog_id, m):
37
  gdf = m.footprint
38
  image_date = pd.Timestamp(
39
- gdf[gdf['catalog_id'] == catalog_id]['datetime'].values[0]
40
- ).strftime('%Y-%m-%d %H:%M:%S')
41
  return image_date
42
 
43
 
44
  def add_widgets(m):
45
- datasets = get_datasets()['dataset'].tolist()
46
- setattr(m, 'zoom_to_layer', True)
47
  style = {"description_width": "initial"}
48
  padding = "0px 0px 0px 5px"
49
  dataset = widgets.Dropdown(
50
  options=datasets,
51
- description='Event:',
52
  value=event,
53
  style=style,
54
  layout=widgets.Layout(width="270px", padding=padding),
55
  )
56
 
57
  catalog_ids = get_catalogs(dataset.value)
58
- setattr(m, 'catalog_ids', catalog_ids)
59
 
60
  date_picker = widgets.DatePicker(
61
- description='Start date:',
62
- value=pd.to_datetime('2021-01-01').date(),
63
  style=style,
64
  layout=widgets.Layout(width="270px", padding=padding),
65
  )
@@ -67,30 +67,30 @@ def add_widgets(m):
67
  image = widgets.Dropdown(
68
  value=None,
69
  options=m.catalog_ids,
70
- description='Image:',
71
  style=style,
72
  layout=widgets.Layout(width="270px", padding=padding),
73
  )
74
 
75
  checkbox = widgets.Checkbox(
76
  value=True,
77
- description='Footprints',
78
  style=style,
79
  layout=widgets.Layout(width="90px", padding="0px"),
80
  )
81
 
82
  split = widgets.Checkbox(
83
  value=False,
84
- description='Split map',
85
  style=style,
86
  layout=widgets.Layout(width="92px", padding=padding),
87
  )
88
 
89
  reset = widgets.Checkbox(
90
  value=False,
91
- description='Reset',
92
  style=style,
93
- layout=widgets.Layout(width="75px", padding='0px'),
94
  )
95
 
96
  output = widgets.Output()
@@ -102,19 +102,23 @@ def add_widgets(m):
102
  m.layers = m.layers[:3]
103
  m.zoom_to_layer = True
104
  reset.value = False
105
- date_picker.value = pd.to_datetime('2021-01-01').date()
106
- m.remove_layer(m.find_layer('Footprint'))
 
107
  m.add_gdf(
108
- m.footprint, layer_name='Footprint', zoom_to_layer=False, info_mode=None
 
 
 
109
  )
110
- satellite_layer = m.find_layer('Google Satellite')
111
  satellite_layer.visible = False
112
  output.outputs = ()
113
 
114
- reset.observe(reset_map, names='value')
115
 
116
  def change_dataset(change):
117
- default_geojson = f'{url}/datasets/{change.new}_union.geojson'
118
  m.layers = m.layers[:2]
119
  m.controls = m.controls[:-1]
120
  basename = os.path.basename(default_geojson)
@@ -124,54 +128,58 @@ def add_widgets(m):
124
  default_geojson = tmp_geojson
125
  else:
126
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
127
- m.add_geojson(default_geojson, layer_name='Footprint', zoom_to_layer=True)
128
- setattr(m, 'gdf', gpd.read_file(default_geojson))
129
 
130
  image.options = get_catalogs(change.new)
131
 
132
- dataset.observe(change_dataset, names='value')
133
 
134
  def change_date(change):
135
  if change.new:
136
- start_date = change.new.strftime('%Y-%m-%d')
137
- sub_gdf = m.gdf[m.gdf['datetime'] >= start_date]
138
- sub_catalog_ids = sub_gdf['catalog_id'].values.tolist()
139
  image.options = sub_catalog_ids
140
- m.remove_layer(m.find_layer('Footprint'))
 
141
  m.add_gdf(
142
- sub_gdf, layer_name='Footprint', zoom_to_layer=False, info_mode=None
 
 
 
143
  )
144
  m.gdf = sub_gdf
145
 
146
- date_picker.observe(change_date, names='value')
147
 
148
  def change_image(change):
149
  if change.new:
150
  if change.new not in m.get_layer_names():
151
- mosaic = f'{url}/datasets/{dataset.value}/{image.value}.json'
152
  m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
153
  image_date = get_image_date(image.value, m)
154
  output.outputs = ()
155
  output.append_stdout(f"Image date: {image_date}\n")
156
 
157
- image.observe(change_image, names='value')
158
 
159
  def change_footprint(change):
160
- geojson_layer = m.find_layer('Footprint')
161
  if change.new:
162
  geojson_layer.visible = True
163
  else:
164
  geojson_layer.visible = False
165
 
166
- checkbox.observe(change_footprint, names='value')
167
 
168
  def change_split(change):
169
  if change.new:
170
  if image.value is not None:
171
  left_layer = m.find_layer(image.value)
172
- right_layer = m.find_layer('Google Satellite')
173
  right_layer.visible = True
174
- footprint_layer = m.find_layer('Footprint')
175
  footprint_layer.visible = False
176
  checkbox.value = False
177
  m.split_map(
@@ -179,22 +187,22 @@ def add_widgets(m):
179
  right_layer=right_layer,
180
  add_close_button=True,
181
  left_label=image.value,
182
- right_label='Google Satellite',
183
  )
184
  split.value = False
185
  else:
186
  left_layer = None
187
 
188
- split.observe(change_split, names='value')
189
 
190
  def handle_click(**kwargs):
191
- if kwargs.get('type') == 'click':
192
- latlon = kwargs.get('coordinates')
193
  geometry = Point(latlon[::-1])
194
  selected = m.gdf[m.gdf.intersects(geometry)]
195
- setattr(m, 'zoom_to_layer', False)
196
  if len(selected) > 0:
197
- catalog_ids = selected['catalog_id'].values.tolist()
198
 
199
  if len(catalog_ids) > 1:
200
  image.options = catalog_ids
@@ -207,7 +215,7 @@ def add_widgets(m):
207
  box = widgets.VBox(
208
  [dataset, date_picker, image, widgets.HBox([checkbox, split, reset]), output]
209
  )
210
- m.add_widget(box, position='topright', add_header=False)
211
 
212
 
213
  zoom = solara.reactive(2)
@@ -216,7 +224,7 @@ center = solara.reactive((20, 0))
216
 
217
  class Map(leafmap.Map):
218
  def __init__(self, **kwargs):
219
- kwargs['toolbar_control'] = False
220
  super().__init__(**kwargs)
221
  basemap = {
222
  "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
@@ -226,7 +234,7 @@ class Map(leafmap.Map):
226
  self.add_tile_layer(**basemap, shown=False)
227
  self.add_layer_manager(opened=False)
228
  add_widgets(self)
229
- default_geojson = f'{url}/datasets/{event}_union.geojson'
230
  basename = os.path.basename(default_geojson)
231
  tempdir = tempfile.gettempdir()
232
  tmp_geojson = os.path.join(tempdir, basename)
@@ -235,11 +243,14 @@ class Map(leafmap.Map):
235
  else:
236
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
237
  self.add_geojson(
238
- default_geojson, layer_name='Footprint', zoom_to_layer=True, info_mode=None
 
 
 
239
  )
240
  gdf = gpd.read_file(default_geojson)
241
- setattr(self, 'gdf', gdf)
242
- setattr(self, 'footprint', gdf)
243
 
244
 
245
  @solara.component
 
7
  import tempfile
8
  from shapely.geometry import Point
9
 
10
+ event = "Maui-Hawaii-fires-Aug-23"
11
+ url = "https://raw.githubusercontent.com/opengeos/maxar-open-data/master"
12
+ repo = "https://github.com/opengeos/maxar-open-data/blob/master/datasets"
13
 
14
 
15
  def get_datasets():
16
+ datasets = f"{url}/datasets.csv"
17
  df = pd.read_csv(datasets)
18
  return df
19
 
20
 
21
  def get_catalogs(name):
22
+ dataset = f"{url}/datasets/{name}.tsv"
23
  basename = os.path.basename(dataset)
24
  tempdir = tempfile.gettempdir()
25
  tmp_dataset = os.path.join(tempdir, basename)
26
  if os.path.exists(tmp_dataset):
27
+ dataset_df = pd.read_csv(tmp_dataset, sep="\t")
28
  else:
29
+ dataset_df = pd.read_csv(dataset, sep="\t")
30
+ dataset_df.to_csv(tmp_dataset, sep="\t", index=False)
31
+ catalog_ids = dataset_df["catalog_id"].unique().tolist()
32
  catalog_ids.sort()
33
  return catalog_ids
34
 
 
36
  def get_image_date(catalog_id, m):
37
  gdf = m.footprint
38
  image_date = pd.Timestamp(
39
+ gdf[gdf["catalog_id"] == catalog_id]["datetime"].values[0]
40
+ ).strftime("%Y-%m-%d %H:%M:%S")
41
  return image_date
42
 
43
 
44
  def add_widgets(m):
45
+ datasets = get_datasets()["dataset"].tolist()
46
+ setattr(m, "zoom_to_layer", True)
47
  style = {"description_width": "initial"}
48
  padding = "0px 0px 0px 5px"
49
  dataset = widgets.Dropdown(
50
  options=datasets,
51
+ description="Event:",
52
  value=event,
53
  style=style,
54
  layout=widgets.Layout(width="270px", padding=padding),
55
  )
56
 
57
  catalog_ids = get_catalogs(dataset.value)
58
+ setattr(m, "catalog_ids", catalog_ids)
59
 
60
  date_picker = widgets.DatePicker(
61
+ description="Start date:",
62
+ value=pd.to_datetime("2021-01-01").date(),
63
  style=style,
64
  layout=widgets.Layout(width="270px", padding=padding),
65
  )
 
67
  image = widgets.Dropdown(
68
  value=None,
69
  options=m.catalog_ids,
70
+ description="Image:",
71
  style=style,
72
  layout=widgets.Layout(width="270px", padding=padding),
73
  )
74
 
75
  checkbox = widgets.Checkbox(
76
  value=True,
77
+ description="Footprints",
78
  style=style,
79
  layout=widgets.Layout(width="90px", padding="0px"),
80
  )
81
 
82
  split = widgets.Checkbox(
83
  value=False,
84
+ description="Split map",
85
  style=style,
86
  layout=widgets.Layout(width="92px", padding=padding),
87
  )
88
 
89
  reset = widgets.Checkbox(
90
  value=False,
91
+ description="Reset",
92
  style=style,
93
+ layout=widgets.Layout(width="75px", padding="0px"),
94
  )
95
 
96
  output = widgets.Output()
 
102
  m.layers = m.layers[:3]
103
  m.zoom_to_layer = True
104
  reset.value = False
105
+ date_picker.value = pd.to_datetime("2021-01-01").date()
106
+ m.remove_layer(m.find_layer("Footprint"))
107
+ m.controls = m.controls[:-1]
108
  m.add_gdf(
109
+ m.footprint,
110
+ layer_name="Footprint",
111
+ zoom_to_layer=False,
112
+ info_mode="on_hover",
113
  )
114
+ satellite_layer = m.find_layer("Google Satellite")
115
  satellite_layer.visible = False
116
  output.outputs = ()
117
 
118
+ reset.observe(reset_map, names="value")
119
 
120
  def change_dataset(change):
121
+ default_geojson = f"{url}/datasets/{change.new}_union.geojson"
122
  m.layers = m.layers[:2]
123
  m.controls = m.controls[:-1]
124
  basename = os.path.basename(default_geojson)
 
128
  default_geojson = tmp_geojson
129
  else:
130
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
131
+ m.add_geojson(default_geojson, layer_name="Footprint", zoom_to_layer=True)
132
+ setattr(m, "gdf", gpd.read_file(default_geojson))
133
 
134
  image.options = get_catalogs(change.new)
135
 
136
+ dataset.observe(change_dataset, names="value")
137
 
138
  def change_date(change):
139
  if change.new:
140
+ start_date = change.new.strftime("%Y-%m-%d")
141
+ sub_gdf = m.gdf[m.gdf["datetime"] >= start_date]
142
+ sub_catalog_ids = sub_gdf["catalog_id"].values.tolist()
143
  image.options = sub_catalog_ids
144
+ m.remove_layer(m.find_layer("Footprint"))
145
+ m.controls = m.controls[:-1]
146
  m.add_gdf(
147
+ sub_gdf,
148
+ layer_name="Footprint",
149
+ zoom_to_layer=False,
150
+ info_mode="on_hover",
151
  )
152
  m.gdf = sub_gdf
153
 
154
+ date_picker.observe(change_date, names="value")
155
 
156
  def change_image(change):
157
  if change.new:
158
  if change.new not in m.get_layer_names():
159
+ mosaic = f"{url}/datasets/{dataset.value}/{image.value}.json"
160
  m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
161
  image_date = get_image_date(image.value, m)
162
  output.outputs = ()
163
  output.append_stdout(f"Image date: {image_date}\n")
164
 
165
+ image.observe(change_image, names="value")
166
 
167
  def change_footprint(change):
168
+ geojson_layer = m.find_layer("Footprint")
169
  if change.new:
170
  geojson_layer.visible = True
171
  else:
172
  geojson_layer.visible = False
173
 
174
+ checkbox.observe(change_footprint, names="value")
175
 
176
  def change_split(change):
177
  if change.new:
178
  if image.value is not None:
179
  left_layer = m.find_layer(image.value)
180
+ right_layer = m.find_layer("Google Satellite")
181
  right_layer.visible = True
182
+ footprint_layer = m.find_layer("Footprint")
183
  footprint_layer.visible = False
184
  checkbox.value = False
185
  m.split_map(
 
187
  right_layer=right_layer,
188
  add_close_button=True,
189
  left_label=image.value,
190
+ right_label="Google Satellite",
191
  )
192
  split.value = False
193
  else:
194
  left_layer = None
195
 
196
+ split.observe(change_split, names="value")
197
 
198
  def handle_click(**kwargs):
199
+ if kwargs.get("type") == "click":
200
+ latlon = kwargs.get("coordinates")
201
  geometry = Point(latlon[::-1])
202
  selected = m.gdf[m.gdf.intersects(geometry)]
203
+ setattr(m, "zoom_to_layer", False)
204
  if len(selected) > 0:
205
+ catalog_ids = selected["catalog_id"].values.tolist()
206
 
207
  if len(catalog_ids) > 1:
208
  image.options = catalog_ids
 
215
  box = widgets.VBox(
216
  [dataset, date_picker, image, widgets.HBox([checkbox, split, reset]), output]
217
  )
218
+ m.add_widget(box, position="topright", add_header=False)
219
 
220
 
221
  zoom = solara.reactive(2)
 
224
 
225
  class Map(leafmap.Map):
226
  def __init__(self, **kwargs):
227
+ kwargs["toolbar_control"] = False
228
  super().__init__(**kwargs)
229
  basemap = {
230
  "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
 
234
  self.add_tile_layer(**basemap, shown=False)
235
  self.add_layer_manager(opened=False)
236
  add_widgets(self)
237
+ default_geojson = f"{url}/datasets/{event}_union.geojson"
238
  basename = os.path.basename(default_geojson)
239
  tempdir = tempfile.gettempdir()
240
  tmp_geojson = os.path.join(tempdir, basename)
 
243
  else:
244
  leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
245
  self.add_geojson(
246
+ default_geojson,
247
+ layer_name="Footprint",
248
+ zoom_to_layer=True,
249
+ info_mode="on_hover",
250
  )
251
  gdf = gpd.read_file(default_geojson)
252
+ setattr(self, "gdf", gdf)
253
+ setattr(self, "footprint", gdf)
254
 
255
 
256
  @solara.component
pages/04_helen.py ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import leafmap
3
+ import solara
4
+ import ipywidgets as widgets
5
+ import pandas as pd
6
+ import geopandas as gpd
7
+ import tempfile
8
+ from shapely.geometry import Point
9
+
10
+ event = "HurricaneHelene-Oct24"
11
+ url = "https://raw.githubusercontent.com/opengeos/maxar-open-data/master"
12
+ repo = "https://github.com/opengeos/maxar-open-data/blob/master/datasets"
13
+
14
+
15
+ def get_datasets():
16
+ datasets = f"{url}/datasets.csv"
17
+ df = pd.read_csv(datasets)
18
+ return df
19
+
20
+
21
+ def get_catalogs(name):
22
+ dataset = f"{url}/datasets/{name}.tsv"
23
+ basename = os.path.basename(dataset)
24
+ tempdir = tempfile.gettempdir()
25
+ tmp_dataset = os.path.join(tempdir, basename)
26
+ if os.path.exists(tmp_dataset):
27
+ dataset_df = pd.read_csv(tmp_dataset, sep="\t")
28
+ else:
29
+ dataset_df = pd.read_csv(dataset, sep="\t")
30
+ dataset_df.to_csv(tmp_dataset, sep="\t", index=False)
31
+ catalog_ids = dataset_df["catalog_id"].unique().tolist()
32
+ catalog_ids.sort()
33
+ return catalog_ids
34
+
35
+
36
+ def get_image_date(catalog_id, m):
37
+ gdf = m.footprint
38
+ image_date = pd.Timestamp(
39
+ gdf[gdf["catalog_id"] == catalog_id]["datetime"].values[0]
40
+ ).strftime("%Y-%m-%d %H:%M:%S")
41
+ return image_date
42
+
43
+
44
+ def add_widgets(m):
45
+ datasets = get_datasets()["dataset"].tolist()
46
+ setattr(m, "zoom_to_layer", True)
47
+ style = {"description_width": "initial"}
48
+ padding = "0px 0px 0px 5px"
49
+ dataset = widgets.Dropdown(
50
+ options=datasets,
51
+ description="Event:",
52
+ value=event,
53
+ style=style,
54
+ layout=widgets.Layout(width="270px", padding=padding),
55
+ )
56
+
57
+ catalog_ids = get_catalogs(dataset.value)
58
+ setattr(m, "catalog_ids", catalog_ids)
59
+
60
+ date_picker = widgets.DatePicker(
61
+ description="Start date:",
62
+ value=pd.to_datetime("2021-01-01").date(),
63
+ style=style,
64
+ layout=widgets.Layout(width="270px", padding=padding),
65
+ )
66
+
67
+ image = widgets.Dropdown(
68
+ value=None,
69
+ options=m.catalog_ids,
70
+ description="Image:",
71
+ style=style,
72
+ layout=widgets.Layout(width="270px", padding=padding),
73
+ )
74
+
75
+ checkbox = widgets.Checkbox(
76
+ value=True,
77
+ description="Footprints",
78
+ style=style,
79
+ layout=widgets.Layout(width="90px", padding="0px"),
80
+ )
81
+
82
+ split = widgets.Checkbox(
83
+ value=False,
84
+ description="Split map",
85
+ style=style,
86
+ layout=widgets.Layout(width="92px", padding=padding),
87
+ )
88
+
89
+ reset = widgets.Checkbox(
90
+ value=False,
91
+ description="Reset",
92
+ style=style,
93
+ layout=widgets.Layout(width="75px", padding="0px"),
94
+ )
95
+
96
+ output = widgets.Output()
97
+
98
+ def reset_map(change):
99
+ if change.new:
100
+ image.value = None
101
+ image.options = m.catalog_ids
102
+ m.layers = m.layers[:3]
103
+ m.zoom_to_layer = True
104
+ reset.value = False
105
+ date_picker.value = pd.to_datetime("2021-01-01").date()
106
+ m.remove_layer(m.find_layer("Footprint"))
107
+ m.controls = m.controls[:-1]
108
+ m.add_gdf(
109
+ m.footprint,
110
+ layer_name="Footprint",
111
+ zoom_to_layer=False,
112
+ info_mode="on_hover",
113
+ )
114
+ satellite_layer = m.find_layer("Google Satellite")
115
+ satellite_layer.visible = False
116
+ output.outputs = ()
117
+
118
+ reset.observe(reset_map, names="value")
119
+
120
+ def change_dataset(change):
121
+ default_geojson = f"{url}/datasets/{change.new}_union.geojson"
122
+ m.layers = m.layers[:2]
123
+ m.controls = m.controls[:-1]
124
+ basename = os.path.basename(default_geojson)
125
+ tempdir = tempfile.gettempdir()
126
+ tmp_geojson = os.path.join(tempdir, basename)
127
+ if os.path.exists(tmp_geojson):
128
+ default_geojson = tmp_geojson
129
+ else:
130
+ leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
131
+ m.add_geojson(default_geojson, layer_name="Footprint", zoom_to_layer=True)
132
+ setattr(m, "gdf", gpd.read_file(default_geojson))
133
+
134
+ image.options = get_catalogs(change.new)
135
+
136
+ dataset.observe(change_dataset, names="value")
137
+
138
+ def change_date(change):
139
+ if change.new:
140
+ start_date = change.new.strftime("%Y-%m-%d")
141
+ sub_gdf = m.gdf[m.gdf["datetime"] >= start_date]
142
+ sub_catalog_ids = sub_gdf["catalog_id"].values.tolist()
143
+ image.options = sub_catalog_ids
144
+ m.remove_layer(m.find_layer("Footprint"))
145
+ m.controls = m.controls[:-1]
146
+ m.add_gdf(
147
+ sub_gdf,
148
+ layer_name="Footprint",
149
+ zoom_to_layer=False,
150
+ info_mode="on_hover",
151
+ )
152
+ m.gdf = sub_gdf
153
+
154
+ date_picker.observe(change_date, names="value")
155
+
156
+ def change_image(change):
157
+ if change.new:
158
+ if change.new not in m.get_layer_names():
159
+ mosaic = f"{url}/datasets/{dataset.value}/{image.value}.json"
160
+ m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
161
+ image_date = get_image_date(image.value, m)
162
+ output.outputs = ()
163
+ output.append_stdout(f"Image date: {image_date}\n")
164
+
165
+ image.observe(change_image, names="value")
166
+
167
+ def change_footprint(change):
168
+ geojson_layer = m.find_layer("Footprint")
169
+ if change.new:
170
+ geojson_layer.visible = True
171
+ else:
172
+ geojson_layer.visible = False
173
+
174
+ checkbox.observe(change_footprint, names="value")
175
+
176
+ def change_split(change):
177
+ if change.new:
178
+ if image.value is not None:
179
+ left_layer = m.find_layer(image.value)
180
+ right_layer = m.find_layer("Google Satellite")
181
+ right_layer.visible = True
182
+ footprint_layer = m.find_layer("Footprint")
183
+ footprint_layer.visible = False
184
+ checkbox.value = False
185
+ m.split_map(
186
+ left_layer=left_layer,
187
+ right_layer=right_layer,
188
+ add_close_button=True,
189
+ left_label=image.value,
190
+ right_label="Google Satellite",
191
+ )
192
+ split.value = False
193
+ else:
194
+ left_layer = None
195
+
196
+ split.observe(change_split, names="value")
197
+
198
+ def handle_click(**kwargs):
199
+ if kwargs.get("type") == "click":
200
+ latlon = kwargs.get("coordinates")
201
+ geometry = Point(latlon[::-1])
202
+ selected = m.gdf[m.gdf.intersects(geometry)]
203
+ setattr(m, "zoom_to_layer", False)
204
+ if len(selected) > 0:
205
+ catalog_ids = selected["catalog_id"].values.tolist()
206
+
207
+ if len(catalog_ids) > 1:
208
+ image.options = catalog_ids
209
+ image.value = catalog_ids[0]
210
+ else:
211
+ image.value = None
212
+
213
+ m.on_interaction(handle_click)
214
+
215
+ box = widgets.VBox(
216
+ [dataset, date_picker, image, widgets.HBox([checkbox, split, reset]), output]
217
+ )
218
+ m.add_widget(box, position="topright", add_header=False)
219
+
220
+
221
+ zoom = solara.reactive(2)
222
+ center = solara.reactive((20, 0))
223
+
224
+
225
+ class Map(leafmap.Map):
226
+ def __init__(self, **kwargs):
227
+ kwargs["toolbar_control"] = False
228
+ super().__init__(**kwargs)
229
+ basemap = {
230
+ "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
231
+ "attribution": "Google",
232
+ "name": "Google Satellite",
233
+ }
234
+ self.add_tile_layer(**basemap, shown=False)
235
+ self.add_layer_manager(opened=False)
236
+ add_widgets(self)
237
+ default_geojson = f"{url}/datasets/{event}_union.geojson"
238
+ basename = os.path.basename(default_geojson)
239
+ tempdir = tempfile.gettempdir()
240
+ tmp_geojson = os.path.join(tempdir, basename)
241
+ if os.path.exists(tmp_geojson):
242
+ default_geojson = tmp_geojson
243
+ else:
244
+ leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
245
+ self.add_geojson(
246
+ default_geojson,
247
+ layer_name="Footprint",
248
+ zoom_to_layer=True,
249
+ info_mode="on_hover",
250
+ )
251
+ gdf = gpd.read_file(default_geojson)
252
+ setattr(self, "gdf", gdf)
253
+ setattr(self, "footprint", gdf)
254
+
255
+
256
+ @solara.component
257
+ def Page():
258
+ with solara.Column(style={"min-width": "500px"}):
259
+ # solara components support reactive variables
260
+ # solara.SliderInt(label="Zoom level", value=zoom, min=1, max=20)
261
+ # using 3rd party widget library require wiring up the events manually
262
+ # using zoom.value and zoom.set
263
+ Map.element( # type: ignore
264
+ zoom=zoom.value,
265
+ on_zoom=zoom.set,
266
+ center=center.value,
267
+ on_center=center.set,
268
+ scroll_wheel_zoom=True,
269
+ toolbar_ctrl=False,
270
+ data_ctrl=False,
271
+ height="780px",
272
+ )
273
+ solara.Text(f"Center: {center.value}")
274
+ solara.Text(f"Zoom: {zoom.value}")
pages/05_milton.py ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import leafmap
3
+ import solara
4
+ import ipywidgets as widgets
5
+ import pandas as pd
6
+ import geopandas as gpd
7
+ import tempfile
8
+ from shapely.geometry import Point
9
+
10
+ event = "HurricaneMilton-Oct24"
11
+ url = "https://raw.githubusercontent.com/opengeos/maxar-open-data/master"
12
+ repo = "https://github.com/opengeos/maxar-open-data/blob/master/datasets"
13
+
14
+
15
+ def get_datasets():
16
+ datasets = f"{url}/datasets.csv"
17
+ df = pd.read_csv(datasets)
18
+ return df
19
+
20
+
21
+ def get_catalogs(name):
22
+ dataset = f"{url}/datasets/{name}.tsv"
23
+ basename = os.path.basename(dataset)
24
+ tempdir = tempfile.gettempdir()
25
+ tmp_dataset = os.path.join(tempdir, basename)
26
+ if os.path.exists(tmp_dataset):
27
+ dataset_df = pd.read_csv(tmp_dataset, sep="\t")
28
+ else:
29
+ dataset_df = pd.read_csv(dataset, sep="\t")
30
+ dataset_df.to_csv(tmp_dataset, sep="\t", index=False)
31
+ catalog_ids = dataset_df["catalog_id"].unique().tolist()
32
+ catalog_ids.sort()
33
+ return catalog_ids
34
+
35
+
36
+ def get_image_date(catalog_id, m):
37
+ gdf = m.footprint
38
+ image_date = pd.Timestamp(
39
+ gdf[gdf["catalog_id"] == catalog_id]["datetime"].values[0]
40
+ ).strftime("%Y-%m-%d %H:%M:%S")
41
+ return image_date
42
+
43
+
44
+ def add_widgets(m):
45
+ datasets = get_datasets()["dataset"].tolist()
46
+ setattr(m, "zoom_to_layer", True)
47
+ style = {"description_width": "initial"}
48
+ padding = "0px 0px 0px 5px"
49
+ dataset = widgets.Dropdown(
50
+ options=datasets,
51
+ description="Event:",
52
+ value=event,
53
+ style=style,
54
+ layout=widgets.Layout(width="270px", padding=padding),
55
+ )
56
+
57
+ catalog_ids = get_catalogs(dataset.value)
58
+ setattr(m, "catalog_ids", catalog_ids)
59
+
60
+ date_picker = widgets.DatePicker(
61
+ description="Start date:",
62
+ value=pd.to_datetime("2021-01-01").date(),
63
+ style=style,
64
+ layout=widgets.Layout(width="270px", padding=padding),
65
+ )
66
+
67
+ image = widgets.Dropdown(
68
+ value=None,
69
+ options=m.catalog_ids,
70
+ description="Image:",
71
+ style=style,
72
+ layout=widgets.Layout(width="270px", padding=padding),
73
+ )
74
+
75
+ checkbox = widgets.Checkbox(
76
+ value=True,
77
+ description="Footprints",
78
+ style=style,
79
+ layout=widgets.Layout(width="90px", padding="0px"),
80
+ )
81
+
82
+ split = widgets.Checkbox(
83
+ value=False,
84
+ description="Split map",
85
+ style=style,
86
+ layout=widgets.Layout(width="92px", padding=padding),
87
+ )
88
+
89
+ reset = widgets.Checkbox(
90
+ value=False,
91
+ description="Reset",
92
+ style=style,
93
+ layout=widgets.Layout(width="75px", padding="0px"),
94
+ )
95
+
96
+ output = widgets.Output()
97
+
98
+ def reset_map(change):
99
+ if change.new:
100
+ image.value = None
101
+ image.options = m.catalog_ids
102
+ m.layers = m.layers[:3]
103
+ m.zoom_to_layer = True
104
+ reset.value = False
105
+ date_picker.value = pd.to_datetime("2021-01-01").date()
106
+ m.remove_layer(m.find_layer("Footprint"))
107
+ m.controls = m.controls[:-1]
108
+ m.add_gdf(
109
+ m.footprint,
110
+ layer_name="Footprint",
111
+ zoom_to_layer=False,
112
+ info_mode="on_hover",
113
+ )
114
+ satellite_layer = m.find_layer("Google Satellite")
115
+ satellite_layer.visible = False
116
+ output.outputs = ()
117
+
118
+ reset.observe(reset_map, names="value")
119
+
120
+ def change_dataset(change):
121
+ default_geojson = f"{url}/datasets/{change.new}_union.geojson"
122
+ m.layers = m.layers[:2]
123
+ m.controls = m.controls[:-1]
124
+ basename = os.path.basename(default_geojson)
125
+ tempdir = tempfile.gettempdir()
126
+ tmp_geojson = os.path.join(tempdir, basename)
127
+ if os.path.exists(tmp_geojson):
128
+ default_geojson = tmp_geojson
129
+ else:
130
+ leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
131
+ m.add_geojson(default_geojson, layer_name="Footprint", zoom_to_layer=True)
132
+ setattr(m, "gdf", gpd.read_file(default_geojson))
133
+
134
+ image.options = get_catalogs(change.new)
135
+
136
+ dataset.observe(change_dataset, names="value")
137
+
138
+ def change_date(change):
139
+ if change.new:
140
+ start_date = change.new.strftime("%Y-%m-%d")
141
+ sub_gdf = m.gdf[m.gdf["datetime"] >= start_date]
142
+ sub_catalog_ids = sub_gdf["catalog_id"].values.tolist()
143
+ image.options = sub_catalog_ids
144
+ m.remove_layer(m.find_layer("Footprint"))
145
+ m.controls = m.controls[:-1]
146
+ m.controls = m.controls[:-1]
147
+ m.add_gdf(
148
+ sub_gdf,
149
+ layer_name="Footprint",
150
+ zoom_to_layer=False,
151
+ info_mode="on_hover",
152
+ )
153
+ m.gdf = sub_gdf
154
+
155
+ date_picker.observe(change_date, names="value")
156
+
157
+ def change_image(change):
158
+ if change.new:
159
+ if change.new not in m.get_layer_names():
160
+ mosaic = f"{url}/datasets/{dataset.value}/{image.value}.json"
161
+ m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
162
+ image_date = get_image_date(image.value, m)
163
+ output.outputs = ()
164
+ output.append_stdout(f"Image date: {image_date}\n")
165
+
166
+ image.observe(change_image, names="value")
167
+
168
+ def change_footprint(change):
169
+ geojson_layer = m.find_layer("Footprint")
170
+ if change.new:
171
+ geojson_layer.visible = True
172
+ else:
173
+ geojson_layer.visible = False
174
+
175
+ checkbox.observe(change_footprint, names="value")
176
+
177
+ def change_split(change):
178
+ if change.new:
179
+ if image.value is not None:
180
+ left_layer = m.find_layer(image.value)
181
+ right_layer = m.find_layer("Google Satellite")
182
+ right_layer.visible = True
183
+ footprint_layer = m.find_layer("Footprint")
184
+ footprint_layer.visible = False
185
+ checkbox.value = False
186
+ m.split_map(
187
+ left_layer=left_layer,
188
+ right_layer=right_layer,
189
+ add_close_button=True,
190
+ left_label=image.value,
191
+ right_label="Google Satellite",
192
+ )
193
+ split.value = False
194
+ else:
195
+ left_layer = None
196
+
197
+ split.observe(change_split, names="value")
198
+
199
+ def handle_click(**kwargs):
200
+ if kwargs.get("type") == "click":
201
+ latlon = kwargs.get("coordinates")
202
+ geometry = Point(latlon[::-1])
203
+ selected = m.gdf[m.gdf.intersects(geometry)]
204
+ setattr(m, "zoom_to_layer", False)
205
+ if len(selected) > 0:
206
+ catalog_ids = selected["catalog_id"].values.tolist()
207
+
208
+ if len(catalog_ids) > 1:
209
+ image.options = catalog_ids
210
+ image.value = catalog_ids[0]
211
+ else:
212
+ image.value = None
213
+
214
+ m.on_interaction(handle_click)
215
+
216
+ box = widgets.VBox(
217
+ [dataset, date_picker, image, widgets.HBox([checkbox, split, reset]), output]
218
+ )
219
+ m.add_widget(box, position="topright", add_header=False)
220
+
221
+
222
+ zoom = solara.reactive(2)
223
+ center = solara.reactive((20, 0))
224
+
225
+
226
+ class Map(leafmap.Map):
227
+ def __init__(self, **kwargs):
228
+ kwargs["toolbar_control"] = False
229
+ super().__init__(**kwargs)
230
+ basemap = {
231
+ "url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
232
+ "attribution": "Google",
233
+ "name": "Google Satellite",
234
+ }
235
+ self.add_tile_layer(**basemap, shown=False)
236
+ self.add_layer_manager(opened=False)
237
+ add_widgets(self)
238
+ default_geojson = f"{url}/datasets/{event}_union.geojson"
239
+ basename = os.path.basename(default_geojson)
240
+ tempdir = tempfile.gettempdir()
241
+ tmp_geojson = os.path.join(tempdir, basename)
242
+ if os.path.exists(tmp_geojson):
243
+ default_geojson = tmp_geojson
244
+ else:
245
+ leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
246
+ self.add_geojson(
247
+ default_geojson,
248
+ layer_name="Footprint",
249
+ zoom_to_layer=True,
250
+ info_mode="on_hover",
251
+ )
252
+ gdf = gpd.read_file(default_geojson)
253
+ setattr(self, "gdf", gdf)
254
+ setattr(self, "footprint", gdf)
255
+
256
+
257
+ @solara.component
258
+ def Page():
259
+ with solara.Column(style={"min-width": "500px"}):
260
+ # solara components support reactive variables
261
+ # solara.SliderInt(label="Zoom level", value=zoom, min=1, max=20)
262
+ # using 3rd party widget library require wiring up the events manually
263
+ # using zoom.value and zoom.set
264
+ Map.element( # type: ignore
265
+ zoom=zoom.value,
266
+ on_zoom=zoom.set,
267
+ center=center.value,
268
+ on_center=center.set,
269
+ scroll_wheel_zoom=True,
270
+ toolbar_ctrl=False,
271
+ data_ctrl=False,
272
+ height="780px",
273
+ )
274
+ solara.Text(f"Center: {center.value}")
275
+ solara.Text(f"Zoom: {zoom.value}")