File size: 2,915 Bytes
1d1e199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498fe27
8d51846
b86162e
1d1e199
 
8d51846
1d1e199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b86162e
 
 
498fe27
 
 
b86162e
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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)"
        )