| import gradio as gr |
| import folium |
| import requests |
| import json |
| from datetime import datetime, timedelta |
|
|
| class RadarToggleApp: |
| def __init__(self): |
| |
| self.canada_wms_url = "https://geo.weather.gc.ca/geomet" |
| self.canada_layers = { |
| "Rain Radar (1km)": "RADAR_1KM_RRAI", |
| "Snow Radar (1km)": "RADAR_1KM_RSNO", |
| "Composite Radar": "RADAR_1KM_RDBR", |
| "24h Rain": "RDPA.24F_PR", |
| "6h Rain": "RDPA.6F_PR" |
| } |
| |
| |
| self.conus_wms_url = "https://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi" |
| self.conus_layers = { |
| "Base Reflectivity": "nexrad-n0r-900913", |
| "Storm Relative Motion": "nexrad-n1r-900913", |
| "Composite Reflectivity": "nexrad-ncr-900913", |
| "Echo Tops": "nexrad-net-900913" |
| } |
| |
| |
| self.north_america_bounds = { |
| "center": [50.0, -100.0], |
| "southwest": [25.0, -140.0], |
| "northeast": [70.0, -50.0] |
| } |
| |
| def create_radar_map(self, radar_system="Canada", layer_selection="Rain Radar (1km)", opacity=0.7): |
| """Create a Folium map with radar overlay based on selected system.""" |
| try: |
| |
| m = folium.Map( |
| location=self.north_america_bounds["center"], |
| zoom_start=4, |
| tiles="OpenStreetMap" |
| ) |
| |
| if radar_system == "Canada": |
| |
| wms_url = self.canada_wms_url |
| layer_name = self.canada_layers.get(layer_selection, "RADAR_1KM_RRAI") |
| system_name = "Canadian Radar" |
| attribution = '<a href="https://eccc-msc.github.io/open-data/licence/readme_en/">ECCC</a>' |
| |
| |
| wms_layer = folium.raster_layers.WmsTileLayer( |
| url=wms_url, |
| layers=layer_name, |
| version="1.3.0", |
| transparent=True, |
| format="image/png", |
| name=f"{system_name} - {layer_selection}", |
| overlay=True, |
| control=True, |
| opacity=opacity, |
| attr=attribution |
| ) |
| |
| else: |
| |
| wms_url = self.conus_wms_url |
| layer_name = self.conus_layers.get(layer_selection, "nexrad-n0r-900913") |
| system_name = "CONUS American Radar" |
| attribution = '<a href="https://mesonet.agron.iastate.edu/">Iowa State University</a>' |
| |
| |
| wms_layer = folium.raster_layers.WmsTileLayer( |
| url=wms_url, |
| layers=layer_name, |
| version="1.1.1", |
| transparent=True, |
| format="image/png", |
| name=f"{system_name} - {layer_selection}", |
| overlay=True, |
| control=True, |
| opacity=opacity, |
| attr=attribution |
| ) |
| |
| wms_layer.add_to(m) |
| |
| |
| folium.LayerControl().add_to(m) |
| |
| |
| info_html = f""" |
| <div style="position: fixed; |
| top: 10px; right: 10px; width: 250px; height: auto; |
| background-color: rgba(255,255,255,0.95); border:2px solid #007acc; z-index:9999; |
| font-size:12px; padding: 12px; border-radius: 6px;"> |
| <div style="font-weight: bold; margin-bottom: 6px; color: #007acc;">{system_name}</div> |
| <div><strong>Layer:</strong> {layer_selection}</div> |
| <div><strong>Opacity:</strong> {opacity:.1f}</div> |
| <div><strong>Coverage:</strong> {"Canada & Northern US" if radar_system == "Canada" else "Continental US"}</div> |
| <div style="font-size:10px; margin-top:8px; color: #666;"> |
| {"Environment Canada MSC GeoMet" if radar_system == "Canada" else "NEXRAD via Iowa State Mesonet"} |
| </div> |
| </div> |
| """ |
| |
| m.get_root().html.add_child(folium.Element(info_html)) |
| |
| |
| if radar_system == "Canada": |
| cities = [ |
| {"name": "Toronto", "coords": [43.6532, -79.3832]}, |
| {"name": "Vancouver", "coords": [49.2827, -123.1207]}, |
| {"name": "Montreal", "coords": [45.5017, -73.5673]}, |
| {"name": "Calgary", "coords": [51.0447, -114.0719]}, |
| {"name": "Ottawa", "coords": [45.4215, -75.6972]}, |
| {"name": "Winnipeg", "coords": [49.8951, -97.1384]} |
| ] |
| marker_color = "red" |
| else: |
| cities = [ |
| {"name": "New York", "coords": [40.7128, -74.0060]}, |
| {"name": "Los Angeles", "coords": [34.0522, -118.2437]}, |
| {"name": "Chicago", "coords": [41.8781, -87.6298]}, |
| {"name": "Houston", "coords": [29.7604, -95.3698]}, |
| {"name": "Miami", "coords": [25.7617, -80.1918]}, |
| {"name": "Seattle", "coords": [47.6062, -122.3321]} |
| ] |
| marker_color = "blue" |
| |
| for city in cities: |
| folium.Marker( |
| location=city["coords"], |
| popup=folium.Popup(city["name"], parse_html=True), |
| tooltip=city["name"], |
| icon=folium.Icon(color=marker_color, icon="info-sign") |
| ).add_to(m) |
| |
| return m |
| |
| except Exception as e: |
| |
| error_map = folium.Map( |
| location=self.north_america_bounds["center"], |
| zoom_start=4 |
| ) |
| |
| error_html = f""" |
| <div style="position: fixed; |
| top: 50%; left: 50%; transform: translate(-50%, -50%); |
| background-color: #ffebee; border: 2px solid #f44336; |
| padding: 20px; border-radius: 5px; z-index: 9999;"> |
| <h3 style="color: #f44336;">Error Loading Radar Data</h3> |
| <p>Error: {str(e)}</p> |
| <p>System: {radar_system}</p> |
| <p>Layer: {layer_selection}</p> |
| </div> |
| """ |
| |
| error_map.get_root().html.add_child(folium.Element(error_html)) |
| return error_map |
|
|
| |
| app = RadarToggleApp() |
|
|
| def update_radar_map(radar_system, layer_selection, opacity): |
| """Update the radar map based on user selections.""" |
| radar_map = app.create_radar_map(radar_system, layer_selection, opacity) |
| return radar_map._repr_html_() |
|
|
| def get_available_layers(radar_system): |
| """Get available layers for the selected radar system.""" |
| if radar_system == "Canada": |
| return gr.Dropdown(choices=list(app.canada_layers.keys()), value="Rain Radar (1km)") |
| else: |
| return gr.Dropdown(choices=list(app.conus_layers.keys()), value="Base Reflectivity") |
|
|
| |
| with gr.Blocks(title="North America Radar Toggle", theme=gr.themes.Soft()) as interface: |
| gr.Markdown("# 🌦️ North America Radar Toggle") |
| gr.Markdown("Switch between Canadian and American CONUS radar systems") |
| |
| with gr.Row(): |
| with gr.Column(scale=1): |
| gr.Markdown("## Radar Controls") |
| |
| |
| radar_system = gr.Radio( |
| choices=["Canada", "CONUS American"], |
| value="Canada", |
| label="Radar System", |
| info="Choose between Canadian or American radar" |
| ) |
| |
| |
| layer_dropdown = gr.Dropdown( |
| choices=list(app.canada_layers.keys()), |
| value="Rain Radar (1km)", |
| label="Radar Layer", |
| info="Choose the type of radar data to display" |
| ) |
| |
| |
| opacity_slider = gr.Slider( |
| minimum=0.1, |
| maximum=1.0, |
| value=0.7, |
| step=0.1, |
| label="Radar Opacity", |
| info="Adjust transparency of radar overlay" |
| ) |
| |
| |
| update_btn = gr.Button("Update Radar Map", variant="primary") |
| |
| gr.Markdown("---") |
| |
| with gr.Accordion("System Information", open=False): |
| gr.Markdown(""" |
| ## Canadian Radar System |
| - **Source**: Environment Canada MSC GeoMet |
| - **Coverage**: Canada and Northern US |
| - **Update**: Every 10 minutes |
| - **Layers**: Rain, Snow, Composite, Precipitation |
| |
| ## CONUS American Radar System |
| - **Source**: NEXRAD via Iowa State Mesonet |
| - **Coverage**: Continental United States |
| - **Update**: Real-time |
| - **Layers**: Base Reflectivity, Storm Motion, Composite |
| """) |
| |
| with gr.Column(scale=6): |
| radar_map = gr.HTML( |
| value=app.create_radar_map()._repr_html_(), |
| label="North America Radar Map" |
| ) |
| |
| |
| def update_layer_choices(system): |
| """Update available layers when radar system changes.""" |
| if system == "Canada": |
| return gr.Dropdown(choices=list(app.canada_layers.keys()), value="Rain Radar (1km)") |
| else: |
| return gr.Dropdown(choices=list(app.conus_layers.keys()), value="Base Reflectivity") |
| |
| |
| radar_system.change( |
| fn=update_layer_choices, |
| inputs=[radar_system], |
| outputs=[layer_dropdown] |
| ) |
| |
| |
| update_btn.click( |
| fn=update_radar_map, |
| inputs=[radar_system, layer_dropdown, opacity_slider], |
| outputs=[radar_map] |
| ) |
| |
| radar_system.change( |
| fn=update_radar_map, |
| inputs=[radar_system, layer_dropdown, opacity_slider], |
| outputs=[radar_map] |
| ) |
| |
| layer_dropdown.change( |
| fn=update_radar_map, |
| inputs=[radar_system, layer_dropdown, opacity_slider], |
| outputs=[radar_map] |
| ) |
| |
| opacity_slider.change( |
| fn=update_radar_map, |
| inputs=[radar_system, layer_dropdown, opacity_slider], |
| outputs=[radar_map] |
| ) |
|
|
| |
| if __name__ == "__main__": |
| interface.launch( |
| server_name="0.0.0.0", |
| server_port=7861, |
| share=True, |
| debug=True |
| ) |