firesmoke / app.py
Darren Wiens
add download button
b86162e unverified
raw
history blame
2.92 kB
import datetime
import io
import os
import requests
import geopandas as gpd
import matplotlib.pyplot as plt
import numpy as np
import streamlit as st
import xarray as xr
from geogif import gif
from rasterio import features
provinces = gpd.read_file("./data/prov_stat.geojson")
geoms = provinces.geometry.boundary
image = features.rasterize(
geoms,
out_shape=[381, 1081],
transform=(0.10000000149011612, 0.0, -160.0, 0.0, 0.10000000149011612, 32.0),
)
cmap = st.selectbox("Colormap", plt.colormaps(), index=1)
fps = st.slider("Frames per second", 0.01, 50.0, 16.0)
show_dt = st.checkbox("Show timestamp", True)
fetch_data = st.checkbox("Refresh data", False)
if st.button("Create GIF"):
smoke_url = "https://firesmoke.ca/forecasts/current/dispersion.nc"
smoke_nc = "./data/dispersion.nc"
if not os.path.isfile(smoke_nc) or fetch_data:
response = requests.head(smoke_url)
total_size = int(response.headers.get("Content-Length"))
progress_text = "Downloading data. Please wait."
progress_bar = st.progress(0, text=progress_text)
size_downloaded = 0
chunk_size = 8192
with requests.get(smoke_url, stream=True) as r:
r.raise_for_status()
with open(smoke_nc, "wb") as f:
for chunk in r.iter_content(chunk_size=chunk_size):
f.write(chunk)
size_downloaded += chunk_size
percent_complete = min(size_downloaded / total_size, 1)
progress_bar.progress(percent_complete, text=progress_text)
progress_bar.empty()
ds_disk = xr.open_dataset(smoke_nc)
tstep = ds_disk.TFLAG
dts = []
for i in tstep:
data = i.data[0]
dt = datetime.datetime.strptime(
str(data[0]) + str(data[1]).zfill(6), "%Y%j%H%M%S"
)
dts.append(dt)
pm25 = ds_disk.PM25
pm25["TSTEP"] = dts
for idx, i in enumerate(pm25.data):
pm25[idx].data[0] = np.maximum(i[0], image * 6)
buffer = io.BytesIO()
if show_dt:
date_format = "%Y-%m-%d %H:%M:%S"
else:
date_format = None
gif(
pm25[:, :, ::-1, :],
date_format=date_format,
fps=fps,
cmap=cmap,
date_color=(255, 255, 255),
to=buffer,
)
first_dt = dts[0]
last_dt = dts[-1]
st.image(buffer, caption=f"{first_dt} to {last_dt}")
st.download_button(
label="Download GIF", data=buffer, file_name="firesmoke.gif", mime="image/gif"
)
with st.expander("Data Sources"):
st.markdown(f"Smoke forecast: [FireSmoke Canada](https://firesmoke.ca/)")
st.markdown(
f"Administrative boundaries: [Natural Earth, 1:50M Admin 1 – States, provinces](https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/cultural/ne_50m_admin_1_states_provinces.zip)"
)