Spaces:
Sleeping
Sleeping
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) |