|
19 | 19 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 | 20 |
|
21 | 21 | """ |
| 22 | + |
22 | 23 | import os |
23 | 24 | import pathlib |
24 | 25 | import starplot |
25 | 26 | import streamlit as st |
26 | 27 | from datetime import datetime, date |
27 | 28 | from zoneinfo import ZoneInfo |
| 29 | + |
| 30 | +import starplot.data.constellations as condata |
| 31 | +import starplot.data.stars as stardata |
| 32 | + |
28 | 33 | from scripts.glasgow_horizon import make_horizon_plot |
29 | 34 | from scripts.glasgow_zenith import make_zenith_plot |
30 | 35 |
|
31 | | -# Writable folder for Starplot / DuckDB extensions |
| 36 | +# ─────────────────────────────────────────────── |
| 37 | +# Setup Starplot writable library (DuckDB extensions etc.) |
| 38 | +# ─────────────────────────────────────────────── |
32 | 39 | starplot_writable = pathlib.Path("starplot_library") |
33 | 40 | os.makedirs(starplot_writable, exist_ok=True) |
34 | | -# redirect internal library |
35 | 41 | starplot.data.library_path = starplot_writable |
36 | 42 |
|
| 43 | +# Preload datasets to avoid slow first-run |
| 44 | +try: |
| 45 | + condata.table() |
| 46 | + stardata.table() |
| 47 | +except Exception as e: |
| 48 | + print("Warning: preload failed:", e) |
| 49 | + |
| 50 | +# ─────────────────────────────────────────────── |
| 51 | +# Streamlit App |
| 52 | +# ─────────────────────────────────────────────── |
| 53 | +st.set_page_config(page_title="Glasgow Starplot Viewer", page_icon="🌌") |
37 | 54 |
|
38 | 55 | st.title("🌌 Glasgow Starplot Viewer") |
39 | 56 |
|
40 | | -# Sidebar: Plot type |
| 57 | +# Sidebar: controls |
41 | 58 | plot_type = st.sidebar.radio("Select Plot Type", ["Horizon", "Zenith"]) |
42 | | - |
43 | | -# Sidebar: Date and time |
44 | 59 | obs_date = st.sidebar.date_input("Date", value=date.today()) |
45 | 60 | obs_time = st.sidebar.time_input("Time", value=datetime.now().time()) |
46 | | - |
47 | | -# Magnitude limit (stars) |
48 | 61 | mag_limit = st.sidebar.slider("Magnitude Limit", 1, 8, 5) |
49 | 62 |
|
50 | | -# Ensure image remains displayed when download button pressed |
| 63 | +# Session state to persist chart path |
51 | 64 | if "chart_path" not in st.session_state: |
52 | 65 | st.session_state.chart_path = None |
53 | 66 |
|
54 | | -# Generate chart |
| 67 | +# ─────────────────────────────────────────────── |
| 68 | +# Cached plot generator |
| 69 | +# ─────────────────────────────────────────────── |
| 70 | +@st.cache_resource(show_spinner=False) |
| 71 | +def generate_plot(plot_type: str, dt: datetime, mag_limit: int) -> str: |
| 72 | + """Generate and return path to starplot image.""" |
| 73 | + if plot_type == "Horizon": |
| 74 | + return make_horizon_plot( |
| 75 | + output_path="images/glasgow_horizon.png", |
| 76 | + dt=dt, |
| 77 | + mag_limit=mag_limit, |
| 78 | + resolution=1600, # smaller for speed |
| 79 | + ) |
| 80 | + else: |
| 81 | + return make_zenith_plot( |
| 82 | + output_path="images/glasgow_zenith.png", |
| 83 | + dt=dt, |
| 84 | + mag_limit=mag_limit, |
| 85 | + resolution=1600, # smaller for speed |
| 86 | + ) |
| 87 | + |
| 88 | +# ─────────────────────────────────────────────── |
| 89 | +# Generate chart button |
| 90 | +# ─────────────────────────────────────────────── |
55 | 91 | if st.sidebar.button("Generate Chart"): |
56 | 92 | tz = ZoneInfo("Europe/London") |
57 | 93 | dt = datetime.combine(obs_date, obs_time).replace(tzinfo=tz) |
58 | 94 |
|
59 | 95 | with st.spinner("Generating chart, please wait..."): |
60 | | - if plot_type == "Horizon": |
61 | | - path = make_horizon_plot(output_path="images/glasgow_horizon.png", dt=dt, mag_limit=mag_limit) |
62 | | - else: |
63 | | - path = make_zenith_plot(output_path="images/glasgow_zenith.png", dt=dt, mag_limit=mag_limit) |
| 96 | + path = generate_plot(plot_type, dt, mag_limit) |
64 | 97 |
|
65 | | - st.session_state.chart_path = path # store path in session state |
66 | | - st.success("Chart generated!") |
| 98 | + st.session_state.chart_path = path |
| 99 | + st.success("✅ Chart generated!") |
67 | 100 |
|
68 | | -# Display the image if it exists in session state |
| 101 | +# ─────────────────────────────────────────────── |
| 102 | +# Display chart + download button |
| 103 | +# ─────────────────────────────────────────────── |
69 | 104 | if st.session_state.chart_path: |
70 | | - st.image(st.session_state.chart_path, caption=f"{plot_type} chart from Glasgow", width="content") |
| 105 | + st.image( |
| 106 | + st.session_state.chart_path, |
| 107 | + caption=f"{plot_type} chart from Glasgow", |
| 108 | + width="content", |
| 109 | + ) |
71 | 110 |
|
72 | 111 | with open(st.session_state.chart_path, "rb") as f: |
73 | 112 | st.download_button( |
74 | | - label="Download chart", |
| 113 | + label="⬇️ Download chart", |
75 | 114 | data=f, |
76 | 115 | file_name=f"glasgow_{plot_type.lower()}.png", |
77 | | - mime="image/png" |
| 116 | + mime="image/png", |
78 | 117 | ) |
0 commit comments