nakas commited on
Commit
f1d1dd9
·
1 Parent(s): 2c4d364
Files changed (2) hide show
  1. app.py +172 -0
  2. requirements.txt +3 -0
app.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import folium
3
+ import requests
4
+ import json
5
+ from datetime import datetime
6
+ import time
7
+
8
+ class RainViewerMap:
9
+ def __init__(self):
10
+ self.api_url = "https://api.rainviewer.com/public/weather-maps.json"
11
+ self.tile_host = "https://tilecache.rainviewer.com"
12
+
13
+ def get_radar_data(self):
14
+ """Fetch available radar timestamps from RainViewer API"""
15
+ try:
16
+ response = requests.get(self.api_url)
17
+ data = response.json()
18
+ return data
19
+ except Exception as e:
20
+ print(f"Error fetching radar data: {e}")
21
+ return None
22
+
23
+ def create_map(self, lat=40.7128, lon=-74.0060, zoom=8, show_radar=True, time_index=0):
24
+ """Create a Folium map with optional radar overlay"""
25
+ # Create base map
26
+ m = folium.Map(
27
+ location=[lat, lon],
28
+ zoom_start=zoom,
29
+ tiles='OpenStreetMap'
30
+ )
31
+
32
+ if show_radar:
33
+ radar_data = self.get_radar_data()
34
+ if radar_data and 'radar' in radar_data:
35
+ # Get available timestamps
36
+ past_data = radar_data['radar']['past']
37
+ nowcast_data = radar_data['radar']['nowcast']
38
+ all_times = past_data + nowcast_data
39
+
40
+ if all_times and time_index < len(all_times):
41
+ # Get the radar tile path for selected time
42
+ selected_time = all_times[time_index]
43
+ tile_path = selected_time['path']
44
+ timestamp = selected_time['time']
45
+
46
+ # Create tile URL template
47
+ tile_url = f"{self.tile_host}{tile_path}/512/{{z}}/{{x}}/{{y}}/2/1_1.png"
48
+
49
+ # Add radar overlay
50
+ folium.raster_layers.TileLayer(
51
+ tiles=tile_url,
52
+ attr='RainViewer',
53
+ name='Radar',
54
+ overlay=True,
55
+ control=True,
56
+ opacity=0.6
57
+ ).add_to(m)
58
+
59
+ # Add timestamp info
60
+ dt = datetime.fromtimestamp(timestamp)
61
+ folium.Marker(
62
+ [lat + 0.1, lon + 0.1],
63
+ popup=f"Radar Time: {dt.strftime('%Y-%m-%d %H:%M:%S')}",
64
+ icon=folium.Icon(color='blue', icon='info-sign')
65
+ ).add_to(m)
66
+
67
+ # Add layer control
68
+ folium.LayerControl().add_to(m)
69
+
70
+ return m._repr_html_()
71
+
72
+ def get_available_times(self):
73
+ """Get list of available radar times for dropdown"""
74
+ radar_data = self.get_radar_data()
75
+ if radar_data and 'radar' in radar_data:
76
+ past_data = radar_data['radar']['past']
77
+ nowcast_data = radar_data['radar']['nowcast']
78
+ all_times = past_data + nowcast_data
79
+
80
+ time_options = []
81
+ for i, time_data in enumerate(all_times):
82
+ timestamp = time_data['time']
83
+ dt = datetime.fromtimestamp(timestamp)
84
+ time_options.append(f"{i}: {dt.strftime('%Y-%m-%d %H:%M:%S')}")
85
+
86
+ return time_options
87
+ return ["No data available"]
88
+
89
+ def create_gradio_app():
90
+ rain_viewer = RainViewerMap()
91
+
92
+ # Get available times for dropdown
93
+ time_options = rain_viewer.get_available_times()
94
+
95
+ with gr.Blocks(title="RainViewer Radar Map") as demo:
96
+ gr.Markdown("# RainViewer Radar Map")
97
+ gr.Markdown("Interactive weather radar map powered by RainViewer API")
98
+
99
+ with gr.Row():
100
+ with gr.Column(scale=1):
101
+ lat_input = gr.Number(
102
+ label="Latitude",
103
+ value=40.7128,
104
+ info="Map center latitude"
105
+ )
106
+ lon_input = gr.Number(
107
+ label="Longitude",
108
+ value=-74.0060,
109
+ info="Map center longitude"
110
+ )
111
+ zoom_input = gr.Slider(
112
+ minimum=1,
113
+ maximum=15,
114
+ value=8,
115
+ step=1,
116
+ label="Zoom Level"
117
+ )
118
+ show_radar = gr.Checkbox(
119
+ label="Show Radar",
120
+ value=True
121
+ )
122
+ time_dropdown = gr.Dropdown(
123
+ choices=time_options,
124
+ label="Radar Time",
125
+ value=time_options[-1] if time_options else None,
126
+ info="Select radar timestamp"
127
+ )
128
+
129
+ update_btn = gr.Button("Update Map", variant="primary")
130
+ refresh_times_btn = gr.Button("Refresh Times")
131
+
132
+ with gr.Column(scale=2):
133
+ map_html = gr.HTML(
134
+ value=rain_viewer.create_map(),
135
+ label="Radar Map"
136
+ )
137
+
138
+ def update_map(lat, lon, zoom, show_radar_flag, selected_time):
139
+ time_index = 0
140
+ if selected_time and ":" in selected_time:
141
+ time_index = int(selected_time.split(":")[0])
142
+
143
+ return rain_viewer.create_map(lat, lon, zoom, show_radar_flag, time_index)
144
+
145
+ def refresh_times():
146
+ new_times = rain_viewer.get_available_times()
147
+ return gr.Dropdown(choices=new_times, value=new_times[-1] if new_times else None)
148
+
149
+ update_btn.click(
150
+ fn=update_map,
151
+ inputs=[lat_input, lon_input, zoom_input, show_radar, time_dropdown],
152
+ outputs=map_html
153
+ )
154
+
155
+ refresh_times_btn.click(
156
+ fn=refresh_times,
157
+ outputs=time_dropdown
158
+ )
159
+
160
+ # Auto-update on input changes
161
+ for input_component in [lat_input, lon_input, zoom_input, show_radar, time_dropdown]:
162
+ input_component.change(
163
+ fn=update_map,
164
+ inputs=[lat_input, lon_input, zoom_input, show_radar, time_dropdown],
165
+ outputs=map_html
166
+ )
167
+
168
+ return demo
169
+
170
+ if __name__ == "__main__":
171
+ app = create_gradio_app()
172
+ app.launch(share=True)
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio>=4.0.0
2
+ folium>=0.14.0
3
+ requests>=2.28.0