mirix commited on
Commit
1d85ced
·
verified ·
1 Parent(s): 1ea7483

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +126 -7
app.py CHANGED
@@ -2,9 +2,7 @@ import gradio as gr
2
  import pandas as pd
3
  import numpy as np
4
  import json
5
- from datetime import datetime, timezone
6
 
7
- import geopy
8
  from geopy import distance
9
  from geopy.geocoders import Nominatim
10
  import srtm
@@ -18,12 +16,14 @@ import plotly.graph_objects as go
18
  # --- GLOBAL SETUP ---
19
 
20
  elevation_data = srtm.get_data()
 
21
  with open("weather_icons_custom.json", "r") as f:
22
  icons = json.load(f)
23
 
24
  cache_session = requests_cache.CachedSession(".cache", expire_after=3600)
25
  retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
26
  openmeteo = openmeteo_requests.Client(session=retry_session)
 
27
  geolocator = Nominatim(user_agent="snow_finder")
28
 
29
  OVERPASS_URL = "https://maps.mail.ru/osm/tools/overpass/api/interpreter"
@@ -68,6 +68,8 @@ def get_elevation_from_srtm(lat, lon):
68
  return None
69
 
70
 
 
 
71
  def get_peaks_from_overpass(lat, lon, dist_km):
72
  bbox = compute_bbox(lat, lon, dist_km)
73
 
@@ -168,6 +170,7 @@ def get_weather_for_peaks_iteratively(df_peaks, min_snow_cm, max_results=20, max
168
  continue
169
 
170
  idx = 0
 
171
  snow_depth_cm = float(hourly.Variables(3).ValuesAsNumpy()[idx]) * 100
172
 
173
  if snow_depth_cm >= min_snow_cm:
@@ -213,14 +216,29 @@ def format_weather_data(df):
213
  return df
214
 
215
 
 
 
 
 
 
 
 
 
 
 
216
  # --- CORE LOGIC ---
217
 
218
  def find_snowy_peaks(min_snow_cm, radius_km, lat, lon):
219
  if lat is None or lon is None:
220
- fig = create_map_with_center(DEFAULT_LAT, DEFAULT_LON)
221
  fig.update_layout(title_text="Enter valid coordinates.")
222
  return fig, "Please enter coordinates."
223
 
 
 
 
 
 
224
  df_peaks = get_peaks_from_overpass(lat, lon, radius_km)
225
  if df_peaks.empty:
226
  fig = create_map_with_center(lat, lon)
@@ -239,12 +257,113 @@ def find_snowy_peaks(min_snow_cm, radius_km, lat, lon):
239
  return fig, f"🎉 Showing {len(df_final)} snowy peaks with ≥ {min_snow_cm} cm of snow."
240
 
241
 
242
- # --- MAP HELPERS (UNCHANGED) ---
243
- # create_empty_map, create_map_with_center, create_map_with_results
244
- # [identical to your original script]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
 
247
- # --- GRADIO UI (UNCHANGED) ---
248
 
249
  with gr.Blocks(theme=gr.themes.Soft(), title="Snow Finder") as demo:
250
  gr.Markdown("# ☃️ Snow Finder for Families")
 
2
  import pandas as pd
3
  import numpy as np
4
  import json
 
5
 
 
6
  from geopy import distance
7
  from geopy.geocoders import Nominatim
8
  import srtm
 
16
  # --- GLOBAL SETUP ---
17
 
18
  elevation_data = srtm.get_data()
19
+
20
  with open("weather_icons_custom.json", "r") as f:
21
  icons = json.load(f)
22
 
23
  cache_session = requests_cache.CachedSession(".cache", expire_after=3600)
24
  retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
25
  openmeteo = openmeteo_requests.Client(session=retry_session)
26
+
27
  geolocator = Nominatim(user_agent="snow_finder")
28
 
29
  OVERPASS_URL = "https://maps.mail.ru/osm/tools/overpass/api/interpreter"
 
68
  return None
69
 
70
 
71
+ # --- PEAK FETCHING (REFACTORED LOGIC) ---
72
+
73
  def get_peaks_from_overpass(lat, lon, dist_km):
74
  bbox = compute_bbox(lat, lon, dist_km)
75
 
 
170
  continue
171
 
172
  idx = 0
173
+
174
  snow_depth_cm = float(hourly.Variables(3).ValuesAsNumpy()[idx]) * 100
175
 
176
  if snow_depth_cm >= min_snow_cm:
 
216
  return df
217
 
218
 
219
+ def geocode_location(location_text):
220
+ try:
221
+ loc = geolocator.geocode(location_text, timeout=10)
222
+ if loc:
223
+ return loc.latitude, loc.longitude, f"Found: {loc.address}"
224
+ return None, None, f"Location '{location_text}' not found."
225
+ except Exception as e:
226
+ return None, None, f"Geocoding error: {e}"
227
+
228
+
229
  # --- CORE LOGIC ---
230
 
231
  def find_snowy_peaks(min_snow_cm, radius_km, lat, lon):
232
  if lat is None or lon is None:
233
+ fig = create_empty_map(DEFAULT_LAT, DEFAULT_LON)
234
  fig.update_layout(title_text="Enter valid coordinates.")
235
  return fig, "Please enter coordinates."
236
 
237
+ if not (-90 <= lat <= 90 and -180 <= lon <= 180):
238
+ fig = create_empty_map(DEFAULT_LAT, DEFAULT_LON)
239
+ fig.update_layout(title_text="Invalid coordinates.")
240
+ return fig, "Coordinates out of range."
241
+
242
  df_peaks = get_peaks_from_overpass(lat, lon, radius_km)
243
  if df_peaks.empty:
244
  fig = create_map_with_center(lat, lon)
 
257
  return fig, f"🎉 Showing {len(df_final)} snowy peaks with ≥ {min_snow_cm} cm of snow."
258
 
259
 
260
+ # --- MAP HELPERS ---
261
+
262
+ def create_empty_map(lat, lon):
263
+ fig = go.Figure()
264
+ fig.update_layout(
265
+ map=dict(style="open-street-map", center={"lat": lat, "lon": lon}, zoom=8),
266
+ margin={"r": 0, "t": 40, "l": 0, "b": 0},
267
+ height=1024,
268
+ width=1024,
269
+ )
270
+ return fig
271
+
272
+
273
+ def create_map_with_center(lat, lon):
274
+ fig = go.Figure(
275
+ go.Scattermap(
276
+ lat=[lat],
277
+ lon=[lon],
278
+ mode="markers",
279
+ marker=dict(size=24, color="white", opacity=0.8),
280
+ hoverinfo="skip",
281
+ )
282
+ )
283
+ fig.add_trace(
284
+ go.Scattermap(
285
+ lat=[lat],
286
+ lon=[lon],
287
+ mode="markers",
288
+ marker=dict(size=12, color="red"),
289
+ text=["Search Center"],
290
+ hoverinfo="text",
291
+ )
292
+ )
293
+ fig.update_layout(
294
+ map=dict(style="open-street-map", center={"lat": lat, "lon": lon}, zoom=8),
295
+ margin={"r": 0, "t": 40, "l": 0, "b": 0},
296
+ height=1024,
297
+ width=1024,
298
+ )
299
+ return fig
300
+
301
+
302
+ def create_map_with_results(lat, lon, df_final):
303
+ fig = go.Figure()
304
+
305
+ fig.add_trace(
306
+ go.Scattermap(
307
+ lat=df_final["latitude"],
308
+ lon=df_final["longitude"],
309
+ mode="markers",
310
+ marker=dict(size=24, color="white", opacity=0.8),
311
+ hoverinfo="skip",
312
+ )
313
+ )
314
+
315
+ fig.add_trace(
316
+ go.Scattermap(
317
+ lat=df_final["latitude"],
318
+ lon=df_final["longitude"],
319
+ mode="markers",
320
+ marker=dict(size=12, color="blue"),
321
+ customdata=df_final[
322
+ ["name", "altitude", "distance_km", "snow_depth_cm",
323
+ "weather_desc", "temp_c_str"]
324
+ ],
325
+ hovertemplate=(
326
+ "<b>%{customdata[0]}</b><br>"
327
+ "Altitude: %{customdata[1]} m<br>"
328
+ "Distance: %{customdata[2]} km<br>"
329
+ "<b>❄️ Snow: %{customdata[3]} cm</b><br>"
330
+ "Weather: %{customdata[4]}<br>"
331
+ "🌡 Temp: %{customdata[5]}<extra></extra>"
332
+ ),
333
+ )
334
+ )
335
+
336
+ fig.add_trace(
337
+ go.Scattermap(
338
+ lat=[lat],
339
+ lon=[lon],
340
+ mode="markers",
341
+ marker=dict(size=24, color="white", opacity=0.8),
342
+ hoverinfo="skip",
343
+ )
344
+ )
345
+ fig.add_trace(
346
+ go.Scattermap(
347
+ lat=[lat],
348
+ lon=[lon],
349
+ mode="markers",
350
+ marker=dict(size=12, color="red"),
351
+ text=["Search Center"],
352
+ hoverinfo="text",
353
+ )
354
+ )
355
+
356
+ fig.update_layout(
357
+ map=dict(style="open-street-map", center={"lat": lat, "lon": lon}, zoom=9),
358
+ margin={"r": 0, "t": 40, "l": 0, "b": 0},
359
+ height=1024,
360
+ width=1024,
361
+ showlegend=False,
362
+ )
363
+ return fig
364
 
365
 
366
+ # --- GRADIO UI ---
367
 
368
  with gr.Blocks(theme=gr.themes.Soft(), title="Snow Finder") as demo:
369
  gr.Markdown("# ☃️ Snow Finder for Families")