Spaces:
Running
Running
Add Maui
Browse files- pages/01_morocco.py +1 -0
- pages/02_libya.py +1 -0
- pages/03_maui.py +214 -0
pages/01_morocco.py
CHANGED
@@ -130,6 +130,7 @@ def add_widgets(m):
|
|
130 |
right_layer.visible = True
|
131 |
footprint_layer = m.find_layer('Footprint')
|
132 |
footprint_layer.visible = False
|
|
|
133 |
m.split_map(
|
134 |
left_layer=left_layer,
|
135 |
right_layer=right_layer,
|
|
|
130 |
right_layer.visible = True
|
131 |
footprint_layer = m.find_layer('Footprint')
|
132 |
footprint_layer.visible = False
|
133 |
+
checkbox.value = False
|
134 |
m.split_map(
|
135 |
left_layer=left_layer,
|
136 |
right_layer=right_layer,
|
pages/02_libya.py
CHANGED
@@ -130,6 +130,7 @@ def add_widgets(m):
|
|
130 |
right_layer.visible = True
|
131 |
footprint_layer = m.find_layer('Footprint')
|
132 |
footprint_layer.visible = False
|
|
|
133 |
m.split_map(
|
134 |
left_layer=left_layer,
|
135 |
right_layer=right_layer,
|
|
|
130 |
right_layer.visible = True
|
131 |
footprint_layer = m.find_layer('Footprint')
|
132 |
footprint_layer.visible = False
|
133 |
+
checkbox.value = False
|
134 |
m.split_map(
|
135 |
left_layer=left_layer,
|
136 |
right_layer=right_layer,
|
pages/03_maui.py
ADDED
@@ -0,0 +1,214 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 = '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 |
+
|
35 |
+
|
36 |
+
def add_widgets(m):
|
37 |
+
datasets = get_datasets()['dataset'].tolist()
|
38 |
+
setattr(m, 'zoom_to_layer', True)
|
39 |
+
style = {"description_width": "initial"}
|
40 |
+
padding = "0px 0px 0px 5px"
|
41 |
+
dataset = widgets.Dropdown(
|
42 |
+
options=datasets,
|
43 |
+
description='Event:',
|
44 |
+
value=event,
|
45 |
+
style=style,
|
46 |
+
layout=widgets.Layout(width="270px", padding=padding),
|
47 |
+
)
|
48 |
+
|
49 |
+
catalog_ids = get_catalogs(dataset.value)
|
50 |
+
setattr(m, 'catalog_ids', catalog_ids)
|
51 |
+
|
52 |
+
image = widgets.Dropdown(
|
53 |
+
value=None,
|
54 |
+
options=m.catalog_ids,
|
55 |
+
description='Image:',
|
56 |
+
style=style,
|
57 |
+
layout=widgets.Layout(width="270px", padding=padding),
|
58 |
+
)
|
59 |
+
|
60 |
+
checkbox = widgets.Checkbox(
|
61 |
+
value=True,
|
62 |
+
description='Footprints',
|
63 |
+
style=style,
|
64 |
+
layout=widgets.Layout(width="90px", padding="0px"),
|
65 |
+
)
|
66 |
+
|
67 |
+
split = widgets.Checkbox(
|
68 |
+
value=False,
|
69 |
+
description='Split map',
|
70 |
+
style=style,
|
71 |
+
layout=widgets.Layout(width="92px", padding=padding),
|
72 |
+
)
|
73 |
+
|
74 |
+
reset = widgets.Checkbox(
|
75 |
+
value=False,
|
76 |
+
description='Reset',
|
77 |
+
style=style,
|
78 |
+
layout=widgets.Layout(width="75px", padding='0px'),
|
79 |
+
)
|
80 |
+
|
81 |
+
def reset_map(change):
|
82 |
+
if change.new:
|
83 |
+
image.value = None
|
84 |
+
image.options = m.catalog_ids
|
85 |
+
m.layers = m.layers[:3]
|
86 |
+
m.zoom_to_layer = True
|
87 |
+
reset.value = False
|
88 |
+
|
89 |
+
reset.observe(reset_map, names='value')
|
90 |
+
|
91 |
+
def change_dataset(change):
|
92 |
+
default_geojson = f'{url}/datasets/{change.new}_union.geojson'
|
93 |
+
m.layers = m.layers[:2]
|
94 |
+
m.controls = m.controls[:-1]
|
95 |
+
basename = os.path.basename(default_geojson)
|
96 |
+
tempdir = tempfile.gettempdir()
|
97 |
+
tmp_geojson = os.path.join(tempdir, basename)
|
98 |
+
if os.path.exists(tmp_geojson):
|
99 |
+
default_geojson = tmp_geojson
|
100 |
+
else:
|
101 |
+
leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
|
102 |
+
m.add_geojson(default_geojson, layer_name='Footprint', zoom_to_layer=True)
|
103 |
+
setattr(m, 'gdf', gpd.read_file(default_geojson))
|
104 |
+
|
105 |
+
image.options = get_catalogs(change.new)
|
106 |
+
|
107 |
+
dataset.observe(change_dataset, names='value')
|
108 |
+
|
109 |
+
def change_image(change):
|
110 |
+
if change.new:
|
111 |
+
mosaic = f'{url}/datasets/{dataset.value}/{image.value}.json'
|
112 |
+
m.add_stac_layer(mosaic, name=image.value, fit_bounds=m.zoom_to_layer)
|
113 |
+
|
114 |
+
image.observe(change_image, names='value')
|
115 |
+
|
116 |
+
def change_footprint(change):
|
117 |
+
geojson_layer = m.find_layer('Footprint')
|
118 |
+
if change.new:
|
119 |
+
geojson_layer.visible = True
|
120 |
+
else:
|
121 |
+
geojson_layer.visible = False
|
122 |
+
|
123 |
+
checkbox.observe(change_footprint, names='value')
|
124 |
+
|
125 |
+
def change_split(change):
|
126 |
+
if change.new:
|
127 |
+
if image.value is not None:
|
128 |
+
left_layer = m.find_layer(image.value)
|
129 |
+
right_layer = m.find_layer('Google Satellite')
|
130 |
+
right_layer.visible = True
|
131 |
+
footprint_layer = m.find_layer('Footprint')
|
132 |
+
footprint_layer.visible = False
|
133 |
+
checkbox.value = False
|
134 |
+
m.split_map(
|
135 |
+
left_layer=left_layer,
|
136 |
+
right_layer=right_layer,
|
137 |
+
add_close_button=True,
|
138 |
+
left_label=image.value,
|
139 |
+
right_label='Google Satellite',
|
140 |
+
)
|
141 |
+
split.value = False
|
142 |
+
else:
|
143 |
+
left_layer = None
|
144 |
+
|
145 |
+
split.observe(change_split, names='value')
|
146 |
+
|
147 |
+
def handle_click(**kwargs):
|
148 |
+
if kwargs.get('type') == 'click':
|
149 |
+
latlon = kwargs.get('coordinates')
|
150 |
+
geometry = Point(latlon[::-1])
|
151 |
+
selected = m.gdf[m.gdf.intersects(geometry)]
|
152 |
+
setattr(m, 'zoom_to_layer', False)
|
153 |
+
if len(selected) > 0:
|
154 |
+
catalog_ids = selected['catalog_id'].values.tolist()
|
155 |
+
|
156 |
+
if len(catalog_ids) > 1:
|
157 |
+
image.options = catalog_ids
|
158 |
+
image.value = catalog_ids[0]
|
159 |
+
else:
|
160 |
+
image.value = None
|
161 |
+
|
162 |
+
m.on_interaction(handle_click)
|
163 |
+
|
164 |
+
box = widgets.VBox([dataset, image, widgets.HBox([checkbox, split, reset])])
|
165 |
+
m.add_widget(box, position='topright', add_header=False)
|
166 |
+
|
167 |
+
|
168 |
+
zoom = solara.reactive(2)
|
169 |
+
center = solara.reactive((20, 0))
|
170 |
+
|
171 |
+
|
172 |
+
class Map(leafmap.Map):
|
173 |
+
def __init__(self, **kwargs):
|
174 |
+
kwargs['toolbar_control'] = False
|
175 |
+
super().__init__(**kwargs)
|
176 |
+
basemap = {
|
177 |
+
"url": "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
|
178 |
+
"attribution": "Google",
|
179 |
+
"name": "Google Satellite",
|
180 |
+
}
|
181 |
+
self.add_tile_layer(**basemap, shown=False)
|
182 |
+
self.add_layer_manager(opened=False)
|
183 |
+
add_widgets(self)
|
184 |
+
default_geojson = f'{url}/datasets/{event}_union.geojson'
|
185 |
+
basename = os.path.basename(default_geojson)
|
186 |
+
tempdir = tempfile.gettempdir()
|
187 |
+
tmp_geojson = os.path.join(tempdir, basename)
|
188 |
+
if os.path.exists(tmp_geojson):
|
189 |
+
default_geojson = tmp_geojson
|
190 |
+
else:
|
191 |
+
leafmap.download_file(default_geojson, tmp_geojson, quiet=True)
|
192 |
+
self.add_geojson(default_geojson, layer_name='Footprint', zoom_to_layer=True)
|
193 |
+
setattr(self, 'gdf', gpd.read_file(default_geojson))
|
194 |
+
|
195 |
+
|
196 |
+
@solara.component
|
197 |
+
def Page():
|
198 |
+
with solara.Column(style={"min-width": "500px"}):
|
199 |
+
# solara components support reactive variables
|
200 |
+
# solara.SliderInt(label="Zoom level", value=zoom, min=1, max=20)
|
201 |
+
# using 3rd party widget library require wiring up the events manually
|
202 |
+
# using zoom.value and zoom.set
|
203 |
+
Map.element( # type: ignore
|
204 |
+
zoom=zoom.value,
|
205 |
+
on_zoom=zoom.set,
|
206 |
+
center=center.value,
|
207 |
+
on_center=center.set,
|
208 |
+
scroll_wheel_zoom=True,
|
209 |
+
toolbar_ctrl=False,
|
210 |
+
data_ctrl=False,
|
211 |
+
height="780px",
|
212 |
+
)
|
213 |
+
solara.Text(f"Center: {center.value}")
|
214 |
+
solara.Text(f"Zoom: {zoom.value}")
|