File size: 6,352 Bytes
f1d1dd9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
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)