nakas commited on
Commit
25b2ed0
·
verified ·
1 Parent(s): ff1b91d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +146 -17
app.py CHANGED
@@ -14,7 +14,132 @@ MONTANA_PEAKS = {
14
  "Pioneer Mountain": (45.231835, -111.450505) # 45°13′55″N 111°27′2″W
15
  }
16
 
17
- [previous code remains the same until the peak_button_click function]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  def make_peak_click_handler(peak_name):
20
  """Creates a click handler for a specific peak."""
@@ -44,23 +169,9 @@ with gr.Blocks(title="Montana Mountain Weather") as demo:
44
 
45
  # Quick access buttons for Montana peaks
46
  gr.Markdown("### Quick Access - Montana Peaks")
 
47
  for peak_name in MONTANA_PEAKS.keys():
48
- button = gr.Button(f"📍 {peak_name}")
49
- button.click(
50
- fn=make_peak_click_handler(peak_name),
51
- inputs=[],
52
- outputs=[lat_input, lon_input]
53
- ).then(
54
- fn=update_weather,
55
- inputs=[lat_input, lon_input],
56
- outputs=[
57
- forecast_output,
58
- current_radar,
59
- forecast_6hr,
60
- forecast_12hr,
61
- map_display
62
- ]
63
- )
64
 
65
  submit_btn = gr.Button("Get Weather", variant="primary")
66
 
@@ -110,6 +221,24 @@ with gr.Blocks(title="Montana Mountain Weather") as demo:
110
  ]
111
  )
112
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  gr.Markdown("""
114
  ## Instructions
115
  1. Use the quick access buttons to check specific Montana peaks
 
14
  "Pioneer Mountain": (45.231835, -111.450505) # 45°13′55″N 111°27′2″W
15
  }
16
 
17
+ def download_image(url):
18
+ """Download image from URL and return as PIL Image."""
19
+ try:
20
+ response = requests.get(url, timeout=10)
21
+ response.raise_for_status()
22
+ image = Image.open(io.BytesIO(response.content))
23
+ return image
24
+ except Exception as e:
25
+ print(f"Error downloading image from {url}: {str(e)}")
26
+ return None
27
+
28
+ def get_noaa_forecast(lat, lon):
29
+ """Get NOAA forecast data for given coordinates."""
30
+ points_url = f"https://api.weather.gov/points/{lat},{lon}"
31
+
32
+ try:
33
+ # Get the forecast URL for the coordinates
34
+ response = requests.get(points_url, timeout=10)
35
+ response.raise_for_status()
36
+ forecast_url = response.json()['properties']['forecast']
37
+
38
+ # Get the actual forecast
39
+ forecast_response = requests.get(forecast_url, timeout=10)
40
+ forecast_response.raise_for_status()
41
+ forecast_data = forecast_response.json()
42
+
43
+ # Format the forecast text
44
+ periods = forecast_data['properties']['periods']
45
+ forecast_text = ""
46
+ for period in periods[:6]: # Show next 3 days (day and night)
47
+ forecast_text += f"\n{period['name']}:\n"
48
+ forecast_text += f"Temperature: {period['temperature']}°{period['temperatureUnit']}\n"
49
+ forecast_text += f"Wind: {period['windSpeed']} {period['windDirection']}\n"
50
+ forecast_text += f"{period['detailedForecast']}\n"
51
+
52
+ return forecast_text.strip()
53
+ except requests.exceptions.RequestException as e:
54
+ return f"Error fetching forecast: {str(e)}"
55
+
56
+ def get_radar_images():
57
+ """Get current radar and forecast radar images."""
58
+ try:
59
+ # Current radar - National composite
60
+ current_radar_url = "https://radar.weather.gov/ridge/standard/CONUS_0.gif"
61
+ current_radar = download_image(current_radar_url)
62
+
63
+ # Get forecast time for NDFD products
64
+ now = datetime.utcnow()
65
+ forecast_date = now.strftime("%Y%m%d")
66
+
67
+ # Alternative URLs that might be more reliable
68
+ forecast_6hr_url = "https://graphical.weather.gov/images/conus/QPF06_conus.png"
69
+ forecast_12hr_url = "https://graphical.weather.gov/images/conus/QPF12_conus.png"
70
+
71
+ forecast_6hr = download_image(forecast_6hr_url)
72
+ forecast_12hr = download_image(forecast_12hr_url)
73
+
74
+ return {
75
+ "current": current_radar,
76
+ "forecast_6hr": forecast_6hr,
77
+ "forecast_12hr": forecast_12hr
78
+ }
79
+ except Exception as e:
80
+ print(f"Error getting radar images: {str(e)}")
81
+ return None
82
+
83
+ def create_map():
84
+ """Create a folium map centered on Montana with optional markers."""
85
+ # Center on Montana
86
+ m = folium.Map(location=[45.5, -111.0], zoom_start=7)
87
+
88
+ # Add markers for Montana peaks
89
+ for peak_name, coords in MONTANA_PEAKS.items():
90
+ folium.Marker(
91
+ coords,
92
+ popup=f"{peak_name}<br>Lat: {coords[0]:.4f}, Lon: {coords[1]:.4f}",
93
+ tooltip=peak_name
94
+ ).add_to(m)
95
+
96
+ m.add_child(folium.ClickForLatLng()) # Enable click events
97
+ return m._repr_html_()
98
+
99
+ def update_weather(lat, lon):
100
+ """Update weather information based on coordinates."""
101
+ try:
102
+ # Validate coordinates
103
+ lat = float(lat)
104
+ lon = float(lon)
105
+ if not (-90 <= lat <= 90 and -180 <= lon <= 180):
106
+ return "Invalid coordinates. Latitude must be between -90 and 90, longitude between -180 and 180.", None, None, None, create_map()
107
+
108
+ # Get forecast and radar
109
+ forecast = get_noaa_forecast(lat, lon)
110
+ radar_images = get_radar_images()
111
+
112
+ if radar_images is None:
113
+ return forecast, None, None, None, create_map()
114
+
115
+ # Create updated map with marker
116
+ m = folium.Map(location=[lat, lon], zoom_start=9)
117
+
118
+ # Add all Montana peaks
119
+ for peak_name, coords in MONTANA_PEAKS.items():
120
+ folium.Marker(
121
+ coords,
122
+ popup=f"{peak_name}<br>Lat: {coords[0]:.4f}, Lon: {coords[1]:.4f}",
123
+ tooltip=peak_name
124
+ ).add_to(m)
125
+
126
+ # Add current location marker if not a peak
127
+ if (lat, lon) not in MONTANA_PEAKS.values():
128
+ folium.Marker([lat, lon], popup=f"Selected Location<br>Lat: {lat:.4f}, Lon: {lon:.4f}").add_to(m)
129
+
130
+ m.add_child(folium.ClickForLatLng()) # Enable click events
131
+
132
+ return (
133
+ forecast,
134
+ radar_images["current"],
135
+ radar_images["forecast_6hr"],
136
+ radar_images["forecast_12hr"],
137
+ m._repr_html_()
138
+ )
139
+ except ValueError as e:
140
+ return f"Error: Invalid coordinate format - {str(e)}", None, None, None, create_map()
141
+ except Exception as e:
142
+ return f"Error: {str(e)}", None, None, None, create_map()
143
 
144
  def make_peak_click_handler(peak_name):
145
  """Creates a click handler for a specific peak."""
 
169
 
170
  # Quick access buttons for Montana peaks
171
  gr.Markdown("### Quick Access - Montana Peaks")
172
+ peak_buttons = []
173
  for peak_name in MONTANA_PEAKS.keys():
174
+ peak_buttons.append(gr.Button(f"📍 {peak_name}"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
 
176
  submit_btn = gr.Button("Get Weather", variant="primary")
177
 
 
221
  ]
222
  )
223
 
224
+ # Handle peak button clicks
225
+ for i, peak_name in enumerate(MONTANA_PEAKS.keys()):
226
+ peak_buttons[i].click(
227
+ fn=make_peak_click_handler(peak_name),
228
+ inputs=[],
229
+ outputs=[lat_input, lon_input]
230
+ ).then(
231
+ fn=update_weather,
232
+ inputs=[lat_input, lon_input],
233
+ outputs=[
234
+ forecast_output,
235
+ current_radar,
236
+ forecast_6hr,
237
+ forecast_12hr,
238
+ map_display
239
+ ]
240
+ )
241
+
242
  gr.Markdown("""
243
  ## Instructions
244
  1. Use the quick access buttons to check specific Montana peaks