github-actions[bot] commited on
Commit ·
c5d7790
1
Parent(s): d930228
Add all files with LFS support
Browse files- components.py +16 -3
- pages.py +68 -6
components.py
CHANGED
|
@@ -116,31 +116,44 @@ def render_admin_panel():
|
|
| 116 |
@timer(include_params=False)
|
| 117 |
def render_stations_map(stations_df: pd.DataFrame) -> None:
|
| 118 |
"""Render the interactive stations map"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
fig = px.scatter_mapbox(
|
| 120 |
stations_df,
|
| 121 |
lat="Latitude",
|
| 122 |
lon="Longitude",
|
| 123 |
hover_data={
|
| 124 |
"Number": True,
|
| 125 |
-
"U_of_F": True,
|
| 126 |
"Sector": True,
|
| 127 |
"WBID": True,
|
| 128 |
"Latitude": False,
|
| 129 |
"Longitude": False,
|
|
|
|
|
|
|
| 130 |
},
|
| 131 |
hover_name="Name",
|
| 132 |
-
zoom=10,
|
| 133 |
height=525,
|
| 134 |
labels={
|
| 135 |
"Number": "Station Number",
|
| 136 |
-
"U_of_F": "ID",
|
| 137 |
"Sector": "Sector",
|
| 138 |
"WBID": "WBID",
|
|
|
|
|
|
|
| 139 |
},
|
| 140 |
)
|
| 141 |
fig.update_layout(
|
| 142 |
mapbox_style="carto-positron",
|
| 143 |
margin={"r": 0, "t": 0, "l": 0, "b": 0},
|
|
|
|
| 144 |
)
|
| 145 |
st.plotly_chart(fig, use_container_width=True)
|
| 146 |
|
|
|
|
| 116 |
@timer(include_params=False)
|
| 117 |
def render_stations_map(stations_df: pd.DataFrame) -> None:
|
| 118 |
"""Render the interactive stations map"""
|
| 119 |
+
# Calculate center coordinates and zoom level
|
| 120 |
+
center_lat = stations_df["Latitude"].mean()
|
| 121 |
+
center_lon = stations_df["Longitude"].mean()
|
| 122 |
+
|
| 123 |
+
# Calculate zoom based on coordinate spread
|
| 124 |
+
lat_range = stations_df["Latitude"].max() - stations_df["Latitude"].min()
|
| 125 |
+
lon_range = stations_df["Longitude"].max() - stations_df["Longitude"].min()
|
| 126 |
+
zoom = min(
|
| 127 |
+
11, max(8, 12 - max(lat_range, lon_range) * 5)
|
| 128 |
+
) # Adjust multiplier as needed
|
| 129 |
+
|
| 130 |
fig = px.scatter_mapbox(
|
| 131 |
stations_df,
|
| 132 |
lat="Latitude",
|
| 133 |
lon="Longitude",
|
| 134 |
hover_data={
|
| 135 |
"Number": True,
|
|
|
|
| 136 |
"Sector": True,
|
| 137 |
"WBID": True,
|
| 138 |
"Latitude": False,
|
| 139 |
"Longitude": False,
|
| 140 |
+
"Most_Recent_Sample": True,
|
| 141 |
+
"Total_Samples": True,
|
| 142 |
},
|
| 143 |
hover_name="Name",
|
|
|
|
| 144 |
height=525,
|
| 145 |
labels={
|
| 146 |
"Number": "Station Number",
|
|
|
|
| 147 |
"Sector": "Sector",
|
| 148 |
"WBID": "WBID",
|
| 149 |
+
"Most_Recent_Sample": "Last Sample",
|
| 150 |
+
"Total_Samples": "Total Samples",
|
| 151 |
},
|
| 152 |
)
|
| 153 |
fig.update_layout(
|
| 154 |
mapbox_style="carto-positron",
|
| 155 |
margin={"r": 0, "t": 0, "l": 0, "b": 0},
|
| 156 |
+
mapbox=dict(center=dict(lat=center_lat, lon=center_lon), zoom=zoom),
|
| 157 |
)
|
| 158 |
st.plotly_chart(fig, use_container_width=True)
|
| 159 |
|
pages.py
CHANGED
|
@@ -102,22 +102,77 @@ def home_section():
|
|
| 102 |
map_col1, map_col2 = st.columns([3, 1])
|
| 103 |
with map_col2:
|
| 104 |
st.markdown("### Map Controls")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
sector_filter = st.multiselect(
|
| 106 |
"Filter by Sector",
|
| 107 |
-
options=
|
| 108 |
default=None,
|
| 109 |
key="map_sector_filter",
|
|
|
|
| 110 |
)
|
| 111 |
|
|
|
|
| 112 |
waterbody_filter = st.multiselect(
|
| 113 |
"Filter by Waterbody",
|
| 114 |
-
options=
|
| 115 |
default=None,
|
| 116 |
key="map_waterbody_filter",
|
|
|
|
| 117 |
)
|
| 118 |
|
| 119 |
st.markdown("### Station Statistics")
|
| 120 |
-
stations_df = get_stations_data()
|
| 121 |
if sector_filter:
|
| 122 |
stations_df = stations_df[stations_df["Sector"].isin(sector_filter)]
|
| 123 |
if waterbody_filter:
|
|
@@ -125,9 +180,16 @@ def home_section():
|
|
| 125 |
stations_df["WBID"].astype(str).isin(waterbody_filter)
|
| 126 |
]
|
| 127 |
|
| 128 |
-
|
| 129 |
-
|
| 130 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
|
| 132 |
with map_col1:
|
| 133 |
render_stations_map(stations_df)
|
|
|
|
| 102 |
map_col1, map_col2 = st.columns([3, 1])
|
| 103 |
with map_col2:
|
| 104 |
st.markdown("### Map Controls")
|
| 105 |
+
stations_df = get_stations_data()
|
| 106 |
+
|
| 107 |
+
# Get initial filter options
|
| 108 |
+
all_sectors = sorted(stations_df["Sector"].unique())
|
| 109 |
+
all_waterbodies = sorted(stations_df["WBID"].astype(str).unique())
|
| 110 |
+
|
| 111 |
+
# Initialize session state if needed
|
| 112 |
+
if "filtered_sectors" not in st.session_state:
|
| 113 |
+
st.session_state.filtered_sectors = all_sectors
|
| 114 |
+
if "filtered_waterbodies" not in st.session_state:
|
| 115 |
+
st.session_state.filtered_waterbodies = all_waterbodies
|
| 116 |
+
|
| 117 |
+
def update_waterbody_options():
|
| 118 |
+
"""Update available waterbody options based on selected sectors"""
|
| 119 |
+
stations_df = get_stations_data()
|
| 120 |
+
selected_sectors = st.session_state.map_sector_filter
|
| 121 |
+
if selected_sectors:
|
| 122 |
+
st.session_state.filtered_waterbodies = sorted(
|
| 123 |
+
stations_df[stations_df["Sector"].isin(selected_sectors)]["WBID"]
|
| 124 |
+
.astype(str)
|
| 125 |
+
.unique()
|
| 126 |
+
)
|
| 127 |
+
else:
|
| 128 |
+
st.session_state.filtered_waterbodies = all_waterbodies
|
| 129 |
+
|
| 130 |
+
# Clear waterbody selection if no longer valid
|
| 131 |
+
st.session_state.map_waterbody_filter = [
|
| 132 |
+
wb
|
| 133 |
+
for wb in st.session_state.map_waterbody_filter
|
| 134 |
+
if wb in st.session_state.filtered_waterbodies
|
| 135 |
+
]
|
| 136 |
+
|
| 137 |
+
def update_sector_options():
|
| 138 |
+
"""Update available sector options based on selected waterbodies"""
|
| 139 |
+
stations_df = get_stations_data()
|
| 140 |
+
selected_waterbodies = st.session_state.map_waterbody_filter
|
| 141 |
+
if selected_waterbodies:
|
| 142 |
+
st.session_state.filtered_sectors = sorted(
|
| 143 |
+
stations_df[
|
| 144 |
+
stations_df["WBID"].astype(str).isin(selected_waterbodies)
|
| 145 |
+
]["Sector"].unique()
|
| 146 |
+
)
|
| 147 |
+
else:
|
| 148 |
+
st.session_state.filtered_sectors = all_sectors
|
| 149 |
+
|
| 150 |
+
# Clear sector selection if no longer valid
|
| 151 |
+
st.session_state.map_sector_filter = [
|
| 152 |
+
s
|
| 153 |
+
for s in st.session_state.map_sector_filter
|
| 154 |
+
if s in st.session_state.filtered_sectors
|
| 155 |
+
]
|
| 156 |
+
|
| 157 |
+
# Apply sector filter with callback
|
| 158 |
sector_filter = st.multiselect(
|
| 159 |
"Filter by Sector",
|
| 160 |
+
options=st.session_state.filtered_sectors,
|
| 161 |
default=None,
|
| 162 |
key="map_sector_filter",
|
| 163 |
+
on_change=update_waterbody_options,
|
| 164 |
)
|
| 165 |
|
| 166 |
+
# Apply waterbody filter with callback
|
| 167 |
waterbody_filter = st.multiselect(
|
| 168 |
"Filter by Waterbody",
|
| 169 |
+
options=st.session_state.filtered_waterbodies,
|
| 170 |
default=None,
|
| 171 |
key="map_waterbody_filter",
|
| 172 |
+
on_change=update_sector_options,
|
| 173 |
)
|
| 174 |
|
| 175 |
st.markdown("### Station Statistics")
|
|
|
|
| 176 |
if sector_filter:
|
| 177 |
stations_df = stations_df[stations_df["Sector"].isin(sector_filter)]
|
| 178 |
if waterbody_filter:
|
|
|
|
| 180 |
stations_df["WBID"].astype(str).isin(waterbody_filter)
|
| 181 |
]
|
| 182 |
|
| 183 |
+
# Create two columns for station statistics
|
| 184 |
+
stat_col1, stat_col2 = st.columns(2)
|
| 185 |
+
|
| 186 |
+
with stat_col1:
|
| 187 |
+
st.metric("Active Stations", len(stations_df))
|
| 188 |
+
st.metric("Sectors", len(stations_df["Sector"].unique()))
|
| 189 |
+
st.metric("Waterbody IDs", len(stations_df["WBID"].unique()))
|
| 190 |
+
|
| 191 |
+
with stat_col2:
|
| 192 |
+
st.metric("Total Samples", int(stations_df["Total_Samples"].sum()))
|
| 193 |
|
| 194 |
with map_col1:
|
| 195 |
render_stations_map(stations_df)
|