push esri up and settings down
Browse files- app.py +99 -93
- functions.py +5 -2
app.py
CHANGED
@@ -82,6 +82,12 @@ else:
|
|
82 |
############################################
|
83 |
# App
|
84 |
############################################
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
with st.expander("Advanced Settings"):
|
86 |
st.write("Select the vegetation indices to calculate:")
|
87 |
all_veg_indices = ["NDVI", "EVI", "EVI2"]
|
@@ -152,32 +158,28 @@ wayback_url = (
|
|
152 |
)
|
153 |
# print(wayback_url)
|
154 |
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
elif map_type == "
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
|
|
|
|
|
|
|
|
170 |
|
171 |
-
|
172 |
-
|
173 |
-
# write_info(
|
174 |
-
# f"""
|
175 |
-
# <div style="text-align: center;">
|
176 |
-
# Latest Esri Imagery - {latest_date.replace('-', '/')}
|
177 |
-
# </div>
|
178 |
-
# """
|
179 |
-
# )
|
180 |
-
m.to_streamlit()
|
181 |
|
182 |
# Generate stats
|
183 |
centroid = geometry_gdf.to_crs(4326).centroid.item()
|
@@ -194,54 +196,52 @@ stats_df = pd.DataFrame(
|
|
194 |
)
|
195 |
|
196 |
gmaps_redirect_url = f"http://maps.google.com/maps?q={centroid_lat},{centroid_lon}&layer=satellite"
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
<
|
201 |
-
<
|
202 |
-
<
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
<
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
<
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
<
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
<
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
|
|
230 |
|
231 |
stats_csv = stats_df.to_csv(index=False)
|
232 |
-
|
|
|
|
|
|
|
233 |
|
234 |
# Run one-time setup
|
235 |
if "one_time_setup_done" not in st.session_state:
|
236 |
one_time_setup()
|
237 |
st.session_state.one_time_setup_done = True
|
238 |
|
239 |
-
st.write(
|
240 |
-
"<h3><div style='text-align: center;'>DEM and Slope from SRTM at 30m resolution</div></h3>",
|
241 |
-
unsafe_allow_html=True,
|
242 |
-
)
|
243 |
-
cols = st.columns(2)
|
244 |
-
|
245 |
if ("cached_dem_maps" in st.session_state) and (st.session_state.cached_file_url == file_url):
|
246 |
dem_map = st.session_state.dem_map
|
247 |
slope_map = st.session_state.slope_map
|
@@ -253,16 +253,22 @@ else:
|
|
253 |
st.session_state.slope_map = slope_map
|
254 |
st.session_state.cached_dem_maps = True
|
255 |
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
|
267 |
# Submit
|
268 |
m = st.markdown(
|
@@ -458,24 +464,6 @@ if "result" in st.session_state:
|
|
458 |
add_geometry_to_maps([m], geometry_gdf, buffer_geometry_gdf)
|
459 |
m.to_streamlit()
|
460 |
|
461 |
-
for name, key in zip(
|
462 |
-
["RGB (Least Cloud Tile Crop)", "RGB (Max NDVI Mosaic)"],
|
463 |
-
["image_visual_least_cloud", "mosaic_visual_max_ndvi"],
|
464 |
-
):
|
465 |
-
st.write(f"<h3><div style='text-align: center;'>{name}</div></h3>", unsafe_allow_html=True)
|
466 |
-
cols = st.columns(2)
|
467 |
-
for col, daterange_str in zip(cols, [year_1, year_2]):
|
468 |
-
start_date, end_date = daterange_str_to_dates(daterange_str)
|
469 |
-
mid_date = start_date + (end_date - start_date) / 2
|
470 |
-
with col:
|
471 |
-
m = gee_folium.Map()
|
472 |
-
visual_mosaic = result_df.loc[daterange_str, key]
|
473 |
-
# visual_layer = gee_folium.ee_tile_layer(mosaic, {"bands": ["R", "G", "B"], "min": min_all, "max": max_all})
|
474 |
-
|
475 |
-
m.add_layer(visual_mosaic.select(["R", "G", "B"]))
|
476 |
-
add_geometry_to_maps([m], geometry_gdf, buffer_geometry_gdf)
|
477 |
-
m.to_streamlit()
|
478 |
-
|
479 |
st.write("<h3><div style='text-align: center;'>Esri RGB Imagery</div></h3>", unsafe_allow_html=True)
|
480 |
cols = st.columns(2)
|
481 |
for col, daterange_str in zip(cols, [year_1, year_2]):
|
@@ -507,5 +495,23 @@ if "result" in st.session_state:
|
|
507 |
)
|
508 |
m.to_streamlit()
|
509 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
510 |
|
511 |
show_credits()
|
|
|
82 |
############################################
|
83 |
# App
|
84 |
############################################
|
85 |
+
container = st.container()
|
86 |
+
# metrics_view_placeholder = st.empty()
|
87 |
+
# view_on_google_maps_placeholder = st.empty()
|
88 |
+
# download_metrics_placeholder = st.empty()
|
89 |
+
# dem_placeholder = st.empty()
|
90 |
+
|
91 |
with st.expander("Advanced Settings"):
|
92 |
st.write("Select the vegetation indices to calculate:")
|
93 |
all_veg_indices = ["NDVI", "EVI", "EVI2"]
|
|
|
158 |
)
|
159 |
# print(wayback_url)
|
160 |
|
161 |
+
with container:
|
162 |
+
m = leaf_folium.Map()
|
163 |
+
if map_type == "Google Hybrid Map (displays place names)":
|
164 |
+
write_info("Google Hybrid Map (displays place names)", center_align=True)
|
165 |
+
m.add_basemap("HYBRID")
|
166 |
+
elif map_type == "Google Satellite Map":
|
167 |
+
write_info("Google Satellite Map", center_align=True)
|
168 |
+
m.add_basemap("SATELLITE")
|
169 |
+
elif map_type == "Esri Satellite Map":
|
170 |
+
write_info(wayback_title, center_align=True)
|
171 |
+
m.add_wms_layer(
|
172 |
+
wayback_url,
|
173 |
+
layers="0",
|
174 |
+
name=wayback_title,
|
175 |
+
attribution="Esri",
|
176 |
+
)
|
177 |
+
else:
|
178 |
+
st.error("Invalid map type")
|
179 |
+
force_stop()
|
180 |
|
181 |
+
add_geometry_to_maps([m], geometry_gdf, buffer_geometry_gdf, opacity=0.3)
|
182 |
+
m.to_streamlit()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
183 |
|
184 |
# Generate stats
|
185 |
centroid = geometry_gdf.to_crs(4326).centroid.item()
|
|
|
196 |
)
|
197 |
|
198 |
gmaps_redirect_url = f"http://maps.google.com/maps?q={centroid_lat},{centroid_lon}&layer=satellite"
|
199 |
+
with container:
|
200 |
+
st.markdown(
|
201 |
+
f"""
|
202 |
+
<div style="display: flex; justify-content: center;">
|
203 |
+
<table style="border-collapse: collapse; text-align: center;">
|
204 |
+
<tr>
|
205 |
+
<th style="border: 1px solid black; text-align: left;">Metric</th>
|
206 |
+
<th style="border: 1px solid black; text-align: right;">Value</th>
|
207 |
+
<th style="border: 1px solid black; text-align: left;">Unit</th>
|
208 |
+
</tr>
|
209 |
+
<tr>
|
210 |
+
<td style="border: 1px solid black; text-align: left;">Area</td>
|
211 |
+
<td style="border: 1px solid black; text-align: right;">{stats_df['Area (m^2)'].item()/10000:.2f}</td>
|
212 |
+
<td style="border: 1px solid black; text-align: left;">ha</td>
|
213 |
+
</tr>
|
214 |
+
<tr>
|
215 |
+
<td style="border: 1px solid black; text-align: left;">Perimeter</td>
|
216 |
+
<td style="border: 1px solid black; text-align: right;">{stats_df['Perimeter (m)'].item():.2f}</td>
|
217 |
+
<td style="border: 1px solid black; text-align: left;">m</td>
|
218 |
+
</tr>
|
219 |
+
<tr>
|
220 |
+
<td style="border: 1px solid black; text-align: left;">Centroid</td>
|
221 |
+
<td style="border: 1px solid black; text-align: right;">({centroid_lat:.6f}, {centroid_lon:.6f})</td>
|
222 |
+
<td style="border: 1px solid black; text-align: left;">(lat, lon)</td>
|
223 |
+
</table>
|
224 |
+
</div>
|
225 |
+
<div style="text-align: center; margin-bottom: 10px;">
|
226 |
+
<a href="{gmaps_redirect_url}" target="_blank">
|
227 |
+
<button>View on Google Maps</button>
|
228 |
+
</a>
|
229 |
+
</div>
|
230 |
+
""",
|
231 |
+
unsafe_allow_html=True,
|
232 |
+
)
|
233 |
|
234 |
stats_csv = stats_df.to_csv(index=False)
|
235 |
+
with container:
|
236 |
+
st.download_button(
|
237 |
+
"Download Geometry Metrics", stats_csv, "geometry_metrics.csv", "text/csv", use_container_width=True
|
238 |
+
)
|
239 |
|
240 |
# Run one-time setup
|
241 |
if "one_time_setup_done" not in st.session_state:
|
242 |
one_time_setup()
|
243 |
st.session_state.one_time_setup_done = True
|
244 |
|
|
|
|
|
|
|
|
|
|
|
|
|
245 |
if ("cached_dem_maps" in st.session_state) and (st.session_state.cached_file_url == file_url):
|
246 |
dem_map = st.session_state.dem_map
|
247 |
slope_map = st.session_state.slope_map
|
|
|
253 |
st.session_state.slope_map = slope_map
|
254 |
st.session_state.cached_dem_maps = True
|
255 |
|
256 |
+
with container:
|
257 |
+
st.write(
|
258 |
+
"<h3><div style='text-align: center;'>DEM and Slope from SRTM at 30m resolution</div></h3>",
|
259 |
+
unsafe_allow_html=True,
|
260 |
+
)
|
261 |
+
cols = st.columns(2)
|
262 |
+
for col, param_map, title in zip(cols, [dem_map, slope_map], ["DEM Map", "Slope Map"]):
|
263 |
+
with col:
|
264 |
+
param_map.add_gdf(
|
265 |
+
geometry_gdf,
|
266 |
+
layer_name="Geometry",
|
267 |
+
style_function=lambda x: {"color": "blue", "fillOpacity": 0.0, "fillColor": "blue"},
|
268 |
+
)
|
269 |
+
write_info(f"""<div style="text-align: center;">{title}</div>""")
|
270 |
+
param_map.addLayerControl()
|
271 |
+
param_map.to_streamlit()
|
272 |
|
273 |
# Submit
|
274 |
m = st.markdown(
|
|
|
464 |
add_geometry_to_maps([m], geometry_gdf, buffer_geometry_gdf)
|
465 |
m.to_streamlit()
|
466 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
467 |
st.write("<h3><div style='text-align: center;'>Esri RGB Imagery</div></h3>", unsafe_allow_html=True)
|
468 |
cols = st.columns(2)
|
469 |
for col, daterange_str in zip(cols, [year_1, year_2]):
|
|
|
495 |
)
|
496 |
m.to_streamlit()
|
497 |
|
498 |
+
for name, key in zip(
|
499 |
+
["RGB (Least Cloud Tile Crop)", "RGB (Max NDVI Mosaic)"],
|
500 |
+
["image_visual_least_cloud", "mosaic_visual_max_ndvi"],
|
501 |
+
):
|
502 |
+
st.write(f"<h3><div style='text-align: center;'>{name}</div></h3>", unsafe_allow_html=True)
|
503 |
+
cols = st.columns(2)
|
504 |
+
for col, daterange_str in zip(cols, [year_1, year_2]):
|
505 |
+
start_date, end_date = daterange_str_to_dates(daterange_str)
|
506 |
+
mid_date = start_date + (end_date - start_date) / 2
|
507 |
+
with col:
|
508 |
+
m = gee_folium.Map()
|
509 |
+
visual_mosaic = result_df.loc[daterange_str, key]
|
510 |
+
# visual_layer = gee_folium.ee_tile_layer(mosaic, {"bands": ["R", "G", "B"], "min": min_all, "max": max_all})
|
511 |
+
|
512 |
+
m.add_layer(visual_mosaic.select(["R", "G", "B"]))
|
513 |
+
add_geometry_to_maps([m], geometry_gdf, buffer_geometry_gdf)
|
514 |
+
m.to_streamlit()
|
515 |
+
|
516 |
|
517 |
show_credits()
|
functions.py
CHANGED
@@ -354,5 +354,8 @@ def process_date(
|
|
354 |
write_info(f"{prefix}{suffix}")
|
355 |
|
356 |
|
357 |
-
def write_info(info):
|
358 |
-
|
|
|
|
|
|
|
|
354 |
write_info(f"{prefix}{suffix}")
|
355 |
|
356 |
|
357 |
+
def write_info(info, center_align=False):
|
358 |
+
if center_align:
|
359 |
+
st.write(f"<div style='text-align: center; color:#006400;'>{info}</div>", unsafe_allow_html=True)
|
360 |
+
else:
|
361 |
+
st.write(f"<span style='color:#006400;'>{info}</span>", unsafe_allow_html=True)
|