rainViewerMap / app.py
nakas's picture
yo
f1d1dd9
raw
history blame
6.35 kB
import gradio as gr
import folium
import requests
import json
from datetime import datetime
import time
class RainViewerMap:
def __init__(self):
self.api_url = "https://api.rainviewer.com/public/weather-maps.json"
self.tile_host = "https://tilecache.rainviewer.com"
def get_radar_data(self):
"""Fetch available radar timestamps from RainViewer API"""
try:
response = requests.get(self.api_url)
data = response.json()
return data
except Exception as e:
print(f"Error fetching radar data: {e}")
return None
def create_map(self, lat=40.7128, lon=-74.0060, zoom=8, show_radar=True, time_index=0):
"""Create a Folium map with optional radar overlay"""
# Create base map
m = folium.Map(
location=[lat, lon],
zoom_start=zoom,
tiles='OpenStreetMap'
)
if show_radar:
radar_data = self.get_radar_data()
if radar_data and 'radar' in radar_data:
# Get available timestamps
past_data = radar_data['radar']['past']
nowcast_data = radar_data['radar']['nowcast']
all_times = past_data + nowcast_data
if all_times and time_index < len(all_times):
# Get the radar tile path for selected time
selected_time = all_times[time_index]
tile_path = selected_time['path']
timestamp = selected_time['time']
# Create tile URL template
tile_url = f"{self.tile_host}{tile_path}/512/{{z}}/{{x}}/{{y}}/2/1_1.png"
# Add radar overlay
folium.raster_layers.TileLayer(
tiles=tile_url,
attr='RainViewer',
name='Radar',
overlay=True,
control=True,
opacity=0.6
).add_to(m)
# Add timestamp info
dt = datetime.fromtimestamp(timestamp)
folium.Marker(
[lat + 0.1, lon + 0.1],
popup=f"Radar Time: {dt.strftime('%Y-%m-%d %H:%M:%S')}",
icon=folium.Icon(color='blue', icon='info-sign')
).add_to(m)
# Add layer control
folium.LayerControl().add_to(m)
return m._repr_html_()
def get_available_times(self):
"""Get list of available radar times for dropdown"""
radar_data = self.get_radar_data()
if radar_data and 'radar' in radar_data:
past_data = radar_data['radar']['past']
nowcast_data = radar_data['radar']['nowcast']
all_times = past_data + nowcast_data
time_options = []
for i, time_data in enumerate(all_times):
timestamp = time_data['time']
dt = datetime.fromtimestamp(timestamp)
time_options.append(f"{i}: {dt.strftime('%Y-%m-%d %H:%M:%S')}")
return time_options
return ["No data available"]
def create_gradio_app():
rain_viewer = RainViewerMap()
# Get available times for dropdown
time_options = rain_viewer.get_available_times()
with gr.Blocks(title="RainViewer Radar Map") as demo:
gr.Markdown("# RainViewer Radar Map")
gr.Markdown("Interactive weather radar map powered by RainViewer API")
with gr.Row():
with gr.Column(scale=1):
lat_input = gr.Number(
label="Latitude",
value=40.7128,
info="Map center latitude"
)
lon_input = gr.Number(
label="Longitude",
value=-74.0060,
info="Map center longitude"
)
zoom_input = gr.Slider(
minimum=1,
maximum=15,
value=8,
step=1,
label="Zoom Level"
)
show_radar = gr.Checkbox(
label="Show Radar",
value=True
)
time_dropdown = gr.Dropdown(
choices=time_options,
label="Radar Time",
value=time_options[-1] if time_options else None,
info="Select radar timestamp"
)
update_btn = gr.Button("Update Map", variant="primary")
refresh_times_btn = gr.Button("Refresh Times")
with gr.Column(scale=2):
map_html = gr.HTML(
value=rain_viewer.create_map(),
label="Radar Map"
)
def update_map(lat, lon, zoom, show_radar_flag, selected_time):
time_index = 0
if selected_time and ":" in selected_time:
time_index = int(selected_time.split(":")[0])
return rain_viewer.create_map(lat, lon, zoom, show_radar_flag, time_index)
def refresh_times():
new_times = rain_viewer.get_available_times()
return gr.Dropdown(choices=new_times, value=new_times[-1] if new_times else None)
update_btn.click(
fn=update_map,
inputs=[lat_input, lon_input, zoom_input, show_radar, time_dropdown],
outputs=map_html
)
refresh_times_btn.click(
fn=refresh_times,
outputs=time_dropdown
)
# Auto-update on input changes
for input_component in [lat_input, lon_input, zoom_input, show_radar, time_dropdown]:
input_component.change(
fn=update_map,
inputs=[lat_input, lon_input, zoom_input, show_radar, time_dropdown],
outputs=map_html
)
return demo
if __name__ == "__main__":
app = create_gradio_app()
app.launch(share=True)