import gradio as gr import folium import requests import json from datetime import datetime, timedelta class RadarToggleApp: def __init__(self): # Canadian radar configuration 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" } # American CONUS radar configuration 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" } # Map bounds self.north_america_bounds = { "center": [50.0, -100.0], # Center of North America "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: # Create base map centered on North America m = folium.Map( location=self.north_america_bounds["center"], zoom_start=4, tiles="OpenStreetMap" ) if radar_system == "Canada": # Canadian radar system wms_url = self.canada_wms_url layer_name = self.canada_layers.get(layer_selection, "RADAR_1KM_RRAI") system_name = "Canadian Radar" attribution = 'ECCC' # Add Canadian radar overlay 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: # CONUS American radar # American CONUS radar system wms_url = self.conus_wms_url layer_name = self.conus_layers.get(layer_selection, "nexrad-n0r-900913") system_name = "CONUS American Radar" attribution = 'Iowa State University' # Add American radar overlay 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) # Add layer control folium.LayerControl().add_to(m) # Add info panel info_html = f"""
{system_name}
Layer: {layer_selection}
Opacity: {opacity:.1f}
Coverage: {"Canada & Northern US" if radar_system == "Canada" else "Continental US"}
{"Environment Canada MSC GeoMet" if radar_system == "Canada" else "NEXRAD via Iowa State Mesonet"}
""" m.get_root().html.add_child(folium.Element(info_html)) # Add major cities for reference 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: # Create error map error_map = folium.Map( location=self.north_america_bounds["center"], zoom_start=4 ) error_html = f"""

Error Loading Radar Data

Error: {str(e)}

System: {radar_system}

Layer: {layer_selection}

""" error_map.get_root().html.add_child(folium.Element(error_html)) return error_map # Initialize the app 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") # Create Gradio interface 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 selector radar_system = gr.Radio( choices=["Canada", "CONUS American"], value="Canada", label="Radar System", info="Choose between Canadian or American radar" ) # Layer selector (will update based on radar system) 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 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 button 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" ) # Event handlers 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") # Update layer dropdown when radar system changes radar_system.change( fn=update_layer_choices, inputs=[radar_system], outputs=[layer_dropdown] ) # Update map when any control changes 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] ) # Launch the app if __name__ == "__main__": interface.launch( server_name="0.0.0.0", server_port=7861, share=True, debug=True )