Spaces:
Running on Zero
Running on Zero
Upload folder using huggingface_hub
Browse files- src/gradio_app.py +18 -20
src/gradio_app.py
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import argparse
|
| 2 |
import sys
|
| 3 |
from pathlib import Path
|
|
@@ -266,13 +274,9 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 266 |
gr.Markdown("# River Network Explorer")
|
| 267 |
|
| 268 |
with gr.Row():
|
| 269 |
-
view_radio = gr.Radio(
|
| 270 |
-
basin_radio = gr.Radio(choices=
|
| 271 |
-
type="index")
|
| 272 |
-
# Update labels nicely for radio buttons
|
| 273 |
-
basin_radio.choices = [(name, idx) for idx, name in BASIN_NAMES.items()]
|
| 274 |
|
| 275 |
-
# Dynamic containers
|
| 276 |
explore_group = gr.Group()
|
| 277 |
with explore_group:
|
| 278 |
status_md = gr.Markdown("Loading datasets...")
|
|
@@ -306,7 +310,6 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 306 |
val_plot_output = gr.Plot(label="Reach Graph Validation")
|
| 307 |
val_snap_caption = gr.Markdown("")
|
| 308 |
|
| 309 |
-
# --- Event Handlers & Logic ---
|
| 310 |
def update_view(view_val, basin_id):
|
| 311 |
basin_name = BASIN_NAMES[basin_id]
|
| 312 |
color = _PALETTE[basin_id % len(_PALETTE)]
|
|
@@ -366,11 +369,9 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 366 |
slider: 50
|
| 367 |
}
|
| 368 |
|
| 369 |
-
# Bind view and basin switcher
|
| 370 |
view_radio.change(update_view, inputs=[view_radio, basin_radio], outputs=[explore_group, validation_group, status_md, plot_output, slider])
|
| 371 |
basin_radio.change(update_view, inputs=[view_radio, basin_radio], outputs=[explore_group, validation_group, status_md, plot_output, slider])
|
| 372 |
|
| 373 |
-
# Handle slider or map clicks
|
| 374 |
def compute_position(basin_id, percent):
|
| 375 |
fraction = percent / 100.0
|
| 376 |
basin_name = BASIN_NAMES[basin_id]
|
|
@@ -379,7 +380,7 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 379 |
try:
|
| 380 |
nodes, edges = get_graph(DATA_ROOT)
|
| 381 |
except Exception:
|
| 382 |
-
return None
|
| 383 |
|
| 384 |
centerlines = get_centerlines(DATA_ROOT, nodes)
|
| 385 |
gw_df = get_groundwater(DATA_ROOT)
|
|
@@ -387,7 +388,7 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 387 |
|
| 388 |
fig2 = None
|
| 389 |
elev, lat, lon, dist_label, dist_sub = None, 0, 0, "", ""
|
| 390 |
-
nearest_station
|
| 391 |
|
| 392 |
if has_centerline:
|
| 393 |
info = centerlines[basin_id]
|
|
@@ -396,7 +397,7 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 396 |
lat, lon = cp.latitude, cp.longitude
|
| 397 |
dist_label = f"{cp.distance_from_mouth_km:.2f} km"
|
| 398 |
dist_sub = f"from mouth, of {cp.total_length_km:.0f} km total"
|
| 399 |
-
nearest_station
|
| 400 |
fig2 = build_figure_real(info, basin_name, color, wells_df=gw_df, marker_lon=lon, marker_lat=lat)
|
| 401 |
else:
|
| 402 |
targets = schematic_click_targets(nodes, edges, basin_id)
|
|
@@ -405,7 +406,7 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 405 |
lat, lon = point.latitude, point.longitude
|
| 406 |
dist_label = f"{point.distance_from_upstream_km:.2f} km"
|
| 407 |
dist_sub = f"of {point.edge_length_km:.2f} km segment"
|
| 408 |
-
nearest_station
|
| 409 |
x_pos = fraction * (len(targets) - 1)
|
| 410 |
fig2 = build_figure_schematic(targets, basin_name, color, marker_x=x_pos, marker_y=elev)
|
| 411 |
|
|
@@ -418,7 +419,6 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 418 |
|
| 419 |
gw_text = f"{gwl:.1f} m" if gwl is not None else (f"No well (nearest {nearest_well_km:.0f}km away)" if nearest_well_km else "No data")
|
| 420 |
|
| 421 |
-
# Hydrometric plots
|
| 422 |
hydro = get_hydrometric(DATA_ROOT)
|
| 423 |
fig_wl, fig_disc, fig_rc = None, None, None
|
| 424 |
if hydro is not None:
|
|
@@ -438,17 +438,16 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 438 |
except Exception:
|
| 439 |
pass
|
| 440 |
|
| 441 |
-
return
|
| 442 |
fig2, elev, dist_label, gw_text, f"Coordinates: {lat:.4f}, {lon:.4f}",
|
| 443 |
fig_wl, fig_disc, fig_rc
|
| 444 |
-
|
| 445 |
|
| 446 |
slider.change(compute_position, inputs=[basin_radio, slider], outputs=[plot_output, metric_elev, metric_dist, metric_gw, coords_md, plot_waterlevel, plot_discharge, plot_rating])
|
| 447 |
|
| 448 |
def on_plot_select(basin_id, select_data: gr.SelectData):
|
| 449 |
if not select_data or select_data.index is None:
|
| 450 |
return gr.skip()
|
| 451 |
-
# Customdata carries distance or fraction
|
| 452 |
try:
|
| 453 |
point_idx = select_data.index
|
| 454 |
nodes, edges = get_graph(DATA_ROOT)
|
|
@@ -470,8 +469,7 @@ with gr.Blocks(title="River Network Explorer") as demo:
|
|
| 470 |
|
| 471 |
plot_output.select(on_plot_select, inputs=[basin_radio], outputs=[slider])
|
| 472 |
|
| 473 |
-
# Initial load trigger
|
| 474 |
demo.load(update_view, inputs=[view_radio, basin_radio], outputs=[explore_group, validation_group, status_md, plot_output, slider])
|
| 475 |
|
| 476 |
-
if __name__ == "__main__":
|
| 477 |
-
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Gradio river network explorer — click directly on the river line (or
|
| 3 |
+
use the slider) to read interpolated elevation and estimated groundwater
|
| 4 |
+
level at that point.
|
| 5 |
+
|
| 6 |
+
Usage:
|
| 7 |
+
python app.py --data-root datasets
|
| 8 |
+
"""
|
| 9 |
import argparse
|
| 10 |
import sys
|
| 11 |
from pathlib import Path
|
|
|
|
| 274 |
gr.Markdown("# River Network Explorer")
|
| 275 |
|
| 276 |
with gr.Row():
|
| 277 |
+
view_radio = gr.Radio(choices=["Explore", "Network validation"], value="Explore", label="View", interactive=True)
|
| 278 |
+
basin_radio = gr.Radio(choices=[(name, idx) for idx, name in BASIN_NAMES.items()], value=0, label="River", interactive=True)
|
|
|
|
|
|
|
|
|
|
| 279 |
|
|
|
|
| 280 |
explore_group = gr.Group()
|
| 281 |
with explore_group:
|
| 282 |
status_md = gr.Markdown("Loading datasets...")
|
|
|
|
| 310 |
val_plot_output = gr.Plot(label="Reach Graph Validation")
|
| 311 |
val_snap_caption = gr.Markdown("")
|
| 312 |
|
|
|
|
| 313 |
def update_view(view_val, basin_id):
|
| 314 |
basin_name = BASIN_NAMES[basin_id]
|
| 315 |
color = _PALETTE[basin_id % len(_PALETTE)]
|
|
|
|
| 369 |
slider: 50
|
| 370 |
}
|
| 371 |
|
|
|
|
| 372 |
view_radio.change(update_view, inputs=[view_radio, basin_radio], outputs=[explore_group, validation_group, status_md, plot_output, slider])
|
| 373 |
basin_radio.change(update_view, inputs=[view_radio, basin_radio], outputs=[explore_group, validation_group, status_md, plot_output, slider])
|
| 374 |
|
|
|
|
| 375 |
def compute_position(basin_id, percent):
|
| 376 |
fraction = percent / 100.0
|
| 377 |
basin_name = BASIN_NAMES[basin_id]
|
|
|
|
| 380 |
try:
|
| 381 |
nodes, edges = get_graph(DATA_ROOT)
|
| 382 |
except Exception:
|
| 383 |
+
return [None] * 8
|
| 384 |
|
| 385 |
centerlines = get_centerlines(DATA_ROOT, nodes)
|
| 386 |
gw_df = get_groundwater(DATA_ROOT)
|
|
|
|
| 388 |
|
| 389 |
fig2 = None
|
| 390 |
elev, lat, lon, dist_label, dist_sub = None, 0, 0, "", ""
|
| 391 |
+
nearest_station = ""
|
| 392 |
|
| 393 |
if has_centerline:
|
| 394 |
info = centerlines[basin_id]
|
|
|
|
| 397 |
lat, lon = cp.latitude, cp.longitude
|
| 398 |
dist_label = f"{cp.distance_from_mouth_km:.2f} km"
|
| 399 |
dist_sub = f"from mouth, of {cp.total_length_km:.0f} km total"
|
| 400 |
+
nearest_station = info["gauges"].iloc[(info["gauges"]["centerline_km"] - cp.distance_from_mouth_km).abs().idxmin()]["station_code"]
|
| 401 |
fig2 = build_figure_real(info, basin_name, color, wells_df=gw_df, marker_lon=lon, marker_lat=lat)
|
| 402 |
else:
|
| 403 |
targets = schematic_click_targets(nodes, edges, basin_id)
|
|
|
|
| 406 |
lat, lon = point.latitude, point.longitude
|
| 407 |
dist_label = f"{point.distance_from_upstream_km:.2f} km"
|
| 408 |
dist_sub = f"of {point.edge_length_km:.2f} km segment"
|
| 409 |
+
nearest_station = point.upstream_station
|
| 410 |
x_pos = fraction * (len(targets) - 1)
|
| 411 |
fig2 = build_figure_schematic(targets, basin_name, color, marker_x=x_pos, marker_y=elev)
|
| 412 |
|
|
|
|
| 419 |
|
| 420 |
gw_text = f"{gwl:.1f} m" if gwl is not None else (f"No well (nearest {nearest_well_km:.0f}km away)" if nearest_well_km else "No data")
|
| 421 |
|
|
|
|
| 422 |
hydro = get_hydrometric(DATA_ROOT)
|
| 423 |
fig_wl, fig_disc, fig_rc = None, None, None
|
| 424 |
if hydro is not None:
|
|
|
|
| 438 |
except Exception:
|
| 439 |
pass
|
| 440 |
|
| 441 |
+
return [
|
| 442 |
fig2, elev, dist_label, gw_text, f"Coordinates: {lat:.4f}, {lon:.4f}",
|
| 443 |
fig_wl, fig_disc, fig_rc
|
| 444 |
+
]
|
| 445 |
|
| 446 |
slider.change(compute_position, inputs=[basin_radio, slider], outputs=[plot_output, metric_elev, metric_dist, metric_gw, coords_md, plot_waterlevel, plot_discharge, plot_rating])
|
| 447 |
|
| 448 |
def on_plot_select(basin_id, select_data: gr.SelectData):
|
| 449 |
if not select_data or select_data.index is None:
|
| 450 |
return gr.skip()
|
|
|
|
| 451 |
try:
|
| 452 |
point_idx = select_data.index
|
| 453 |
nodes, edges = get_graph(DATA_ROOT)
|
|
|
|
| 469 |
|
| 470 |
plot_output.select(on_plot_select, inputs=[basin_radio], outputs=[slider])
|
| 471 |
|
|
|
|
| 472 |
demo.load(update_view, inputs=[view_radio, basin_radio], outputs=[explore_group, validation_group, status_md, plot_output, slider])
|
| 473 |
|
| 474 |
+
# if __name__ == "__main__":
|
| 475 |
+
demo.launch()
|