mirix commited on
Commit
d423a9d
·
verified ·
1 Parent(s): 8b9fd46

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -33
app.py CHANGED
@@ -1,4 +1,4 @@
1
- ### app_refactored_openmeteo_strings.py ###
2
 
3
  import gradio as gr
4
  import pandas as pd
@@ -37,10 +37,45 @@ DEFAULT_LAT, DEFAULT_LON = 49.6116, 6.1319
37
  # --- UTILS ---
38
 
39
  def compute_bbox(lat, lon, dist_km):
40
- origin = geopy.Point(lat, lon)
41
- dest_sw = distance.distance(kilometers=dist_km).destination(origin, bearing=225)
42
- dest_ne = distance.distance(kilometers=dist_km).destination(origin, bearing=45)
43
- return f"{dest_sw.latitude},{dest_sw.longitude},{dest_ne.latitude},{dest_ne.longitude}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
 
46
  def get_peaks_from_overpass(lat, lon, dist_km):
@@ -63,28 +98,56 @@ def get_peaks_from_overpass(lat, lon, dist_km):
63
  return pd.DataFrame()
64
 
65
  peaks = {"name": [], "latitude": [], "longitude": [], "altitude": []}
 
 
 
 
66
  for e in data.get("elements", []):
 
 
 
 
67
  lat_e, lon_e = e.get("lat"), e.get("lon")
 
 
 
 
 
 
68
  tags = e.get("tags", {})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  peaks["latitude"].append(lat_e)
70
  peaks["longitude"].append(lon_e)
71
  peaks["name"].append(tags.get("name", "Unnamed Peak/Hill"))
72
-
73
- ele = tags.get("ele")
74
- if ele and str(ele).replace(".", "").replace("-", "").isnumeric():
75
- peaks["altitude"].append(float(ele))
76
- else:
77
- try:
78
- alt = elevation_data.get_elevation(lat_e, lon_e)
79
- peaks["altitude"].append(alt if alt is not None else 0)
80
- except Exception:
81
- peaks["altitude"].append(0)
82
 
83
  if not peaks["latitude"]:
84
  return pd.DataFrame()
85
 
86
  df = pd.DataFrame(peaks)
87
  df["altitude"] = df["altitude"].round(0).astype(int)
 
88
  df["distance_m"] = df.apply(
89
  lambda r: distance.distance((r["latitude"], r["longitude"]), (lat, lon)).m, axis=1
90
  )
@@ -115,21 +178,15 @@ def get_weather_for_peaks_iteratively(df_peaks, min_snow_cm, max_results=20, max
115
  }
116
 
117
  try:
118
- # FIX: Get the list of responses and access the first one
119
  responses = openmeteo.weather_api(url, params=params)
120
- if not responses: # Check if the list is empty
121
  continue
122
- response = responses[0] # This is the critical fix
123
 
124
- # Now proceed with your existing processing
125
  hourly = response.Hourly()
126
  if hourly is None:
127
  continue
128
 
129
- #times = hourly.Time()
130
- #now_utc = datetime.now(timezone.utc)
131
- #times_utc = datetime.fromtimestamp(times, tz=timezone.utc)
132
- #idx = int(np.argmin([abs((t - now_utc).total_seconds()) for t in times_utc]))
133
  idx = 0
134
 
135
  temp_c = float(hourly.Variables(0).ValuesAsNumpy()[idx])
@@ -149,7 +206,7 @@ def get_weather_for_peaks_iteratively(df_peaks, min_snow_cm, max_results=20, max
149
  })
150
 
151
  except Exception as e:
152
- print(f"Error fetching weather for {row['name']}: {e}")
153
 
154
  requests_made += 1
155
 
@@ -166,9 +223,13 @@ def format_weather_data(df):
166
  code = str(int(row["weather_code"]))
167
  tod = "day" if row["is_day"] == 1 else "night"
168
  info = icons.get(code, {}).get(tod, {})
169
- return ICON_URL + info.get("icon", ""), info.get("description", "Unknown")
 
 
170
 
171
- df[["weather_icon", "weather_desc"]] = df.apply(icon_mapper, axis=1, result_type="expand")
 
 
172
  df["distance_km"] = (df["distance_m"] / 1000).round(1)
173
  df["temp_c_str"] = df["temp_c"].round(0).astype(int).astype(str) + "°C"
174
  return df
@@ -238,7 +299,7 @@ def create_map_with_center(lat, lon):
238
  lon=[lon],
239
  mode="markers",
240
  marker=dict(size=24, color="white", opacity=0.8),
241
- hoverinfo=None,
242
  )
243
  )
244
  fig.add_trace(
@@ -246,7 +307,7 @@ def create_map_with_center(lat, lon):
246
  lat=[lat],
247
  lon=[lon],
248
  mode="markers",
249
- marker=dict(size=12, color="white", symbol="landmark"),
250
  text=["Search Center"],
251
  hoverinfo="text",
252
  )
@@ -262,23 +323,28 @@ def create_map_with_center(lat, lon):
262
 
263
  def create_map_with_results(lat, lon, df_final):
264
  fig = go.Figure()
 
 
265
  fig.add_trace(
266
  go.Scattermap(
267
  lat=df_final["latitude"],
268
  lon=df_final["longitude"],
269
  mode="markers",
270
  marker=dict(size=24, color="white", opacity=0.8),
271
- hoverinfo=None,
272
  )
273
  )
 
 
274
  fig.add_trace(
275
  go.Scattermap(
276
  lat=df_final["latitude"],
277
  lon=df_final["longitude"],
278
  mode="markers",
279
- marker=dict(size=12, color="white", symbol="mountain"),
280
  customdata=df_final[
281
- ["name", "altitude", "distance_km", "snow_depth_cm", "weather_desc", "temp_c_str"]
 
282
  ],
283
  hovertemplate=(
284
  "<b>%{customdata[0]}</b><br>"
@@ -290,13 +356,15 @@ def create_map_with_results(lat, lon, df_final):
290
  ),
291
  )
292
  )
 
 
293
  fig.add_trace(
294
  go.Scattermap(
295
  lat=[lat],
296
  lon=[lon],
297
  mode="markers",
298
  marker=dict(size=24, color="white", opacity=0.8),
299
- hoverinfo=None,
300
  )
301
  )
302
  fig.add_trace(
@@ -304,11 +372,12 @@ def create_map_with_results(lat, lon, df_final):
304
  lat=[lat],
305
  lon=[lon],
306
  mode="markers",
307
- marker=dict(size=12, color="white", symbol="landmark"),
308
  text=["Search Center"],
309
  hoverinfo="text",
310
  )
311
  )
 
312
  fig.update_layout(
313
  map=dict(style="open-street-map", center={"lat": lat, "lon": lon}, zoom=9),
314
  margin={"r": 0, "t": 40, "l": 0, "b": 0},
 
1
+ ### app_fixed.py ###
2
 
3
  import gradio as gr
4
  import pandas as pd
 
37
  # --- UTILS ---
38
 
39
  def compute_bbox(lat, lon, dist_km):
40
+ """Compute bounding box more reliably for any location."""
41
+ # Convert km to degrees (rough approximation)
42
+ # At equator: 1 degree ≈ 111 km
43
+ lat_delta = dist_km / 111.0
44
+ lon_delta = dist_km / (111.0 * np.cos(np.radians(lat)))
45
+
46
+ south = lat - lat_delta
47
+ north = lat + lat_delta
48
+ west = lon - lon_delta
49
+ east = lon + lon_delta
50
+
51
+ # Ensure longitude wraps properly
52
+ if west < -180:
53
+ west += 360
54
+ if east > 180:
55
+ east -= 360
56
+
57
+ # Ensure latitude stays in valid range
58
+ south = max(south, -90)
59
+ north = min(north, 90)
60
+
61
+ return f"{south},{west},{north},{east}"
62
+
63
+
64
+ def get_elevation_from_srtm(lat, lon):
65
+ """Get elevation from SRTM if within coverage area."""
66
+ if lat is None or lon is None:
67
+ return None
68
+
69
+ # SRTM coverage: 60°N to 56°S
70
+ if -56 <= lat <= 60:
71
+ try:
72
+ alt = elevation_data.get_elevation(lat, lon)
73
+ if alt is not None and alt > 0:
74
+ return alt
75
+ except Exception as ex:
76
+ print(f"SRTM error for {lat},{lon}: {ex}")
77
+
78
+ return None
79
 
80
 
81
  def get_peaks_from_overpass(lat, lon, dist_km):
 
98
  return pd.DataFrame()
99
 
100
  peaks = {"name": [], "latitude": [], "longitude": [], "altitude": []}
101
+ skipped = 0
102
+ processed = 0
103
+ max_peaks = 100 # Limit processing to avoid slowdowns
104
+
105
  for e in data.get("elements", []):
106
+ # Stop if we've processed enough peaks
107
+ if processed >= max_peaks:
108
+ break
109
+
110
  lat_e, lon_e = e.get("lat"), e.get("lon")
111
+
112
+ # Skip elements without valid coordinates
113
+ if lat_e is None or lon_e is None:
114
+ skipped += 1
115
+ continue
116
+
117
  tags = e.get("tags", {})
118
+ alt = None
119
+
120
+ # Strategy 1: Try to get elevation from OSM tag first
121
+ ele = tags.get("ele")
122
+ if ele and str(ele).replace(".", "").replace("-", "").isnumeric():
123
+ alt = float(ele)
124
+
125
+ # Strategy 2: If no OSM elevation, try SRTM as fallback
126
+ if alt is None or alt <= 10:
127
+ alt = get_elevation_from_srtm(lat_e, lon_e)
128
+
129
+ # Skip peaks if both strategies failed to produce valid elevation
130
+ if alt is None or alt <= 10:
131
+ skipped += 1
132
+ continue
133
+
134
  peaks["latitude"].append(lat_e)
135
  peaks["longitude"].append(lon_e)
136
  peaks["name"].append(tags.get("name", "Unnamed Peak/Hill"))
137
+ peaks["altitude"].append(alt)
138
+ processed += 1
139
+
140
+ if skipped > 0:
141
+ print(f"Skipped {skipped} peaks without complete data (coordinates or elevation)")
142
+ if processed >= max_peaks:
143
+ print(f"Reached limit of {max_peaks} peaks processed")
 
 
 
144
 
145
  if not peaks["latitude"]:
146
  return pd.DataFrame()
147
 
148
  df = pd.DataFrame(peaks)
149
  df["altitude"] = df["altitude"].round(0).astype(int)
150
+
151
  df["distance_m"] = df.apply(
152
  lambda r: distance.distance((r["latitude"], r["longitude"]), (lat, lon)).m, axis=1
153
  )
 
178
  }
179
 
180
  try:
 
181
  responses = openmeteo.weather_api(url, params=params)
182
+ if not responses:
183
  continue
184
+ response = responses[0]
185
 
 
186
  hourly = response.Hourly()
187
  if hourly is None:
188
  continue
189
 
 
 
 
 
190
  idx = 0
191
 
192
  temp_c = float(hourly.Variables(0).ValuesAsNumpy()[idx])
 
206
  })
207
 
208
  except Exception as e:
209
+ print(f"Error fetching weather for {row['name']} at {row['latitude']},{row['longitude']}: {e}")
210
 
211
  requests_made += 1
212
 
 
223
  code = str(int(row["weather_code"]))
224
  tod = "day" if row["is_day"] == 1 else "night"
225
  info = icons.get(code, {}).get(tod, {})
226
+ icon_filename = info.get("icon", "")
227
+ description = info.get("description", "Unknown")
228
+ return ICON_URL + icon_filename, description, icon_filename
229
 
230
+ df[["weather_icon_url", "weather_desc", "weather_icon_name"]] = df.apply(
231
+ icon_mapper, axis=1, result_type="expand"
232
+ )
233
  df["distance_km"] = (df["distance_m"] / 1000).round(1)
234
  df["temp_c_str"] = df["temp_c"].round(0).astype(int).astype(str) + "°C"
235
  return df
 
299
  lon=[lon],
300
  mode="markers",
301
  marker=dict(size=24, color="white", opacity=0.8),
302
+ hoverinfo="skip",
303
  )
304
  )
305
  fig.add_trace(
 
307
  lat=[lat],
308
  lon=[lon],
309
  mode="markers",
310
+ marker=dict(size=12, color="red"),
311
  text=["Search Center"],
312
  hoverinfo="text",
313
  )
 
323
 
324
  def create_map_with_results(lat, lon, df_final):
325
  fig = go.Figure()
326
+
327
+ # Add white halos for peaks
328
  fig.add_trace(
329
  go.Scattermap(
330
  lat=df_final["latitude"],
331
  lon=df_final["longitude"],
332
  mode="markers",
333
  marker=dict(size=24, color="white", opacity=0.8),
334
+ hoverinfo="skip",
335
  )
336
  )
337
+
338
+ # Add peak markers with weather info in hover (no HTML icons)
339
  fig.add_trace(
340
  go.Scattermap(
341
  lat=df_final["latitude"],
342
  lon=df_final["longitude"],
343
  mode="markers",
344
+ marker=dict(size=12, color="blue"),
345
  customdata=df_final[
346
+ ["name", "altitude", "distance_km", "snow_depth_cm", "weather_desc",
347
+ "temp_c_str"]
348
  ],
349
  hovertemplate=(
350
  "<b>%{customdata[0]}</b><br>"
 
356
  ),
357
  )
358
  )
359
+
360
+ # Add search center with halo
361
  fig.add_trace(
362
  go.Scattermap(
363
  lat=[lat],
364
  lon=[lon],
365
  mode="markers",
366
  marker=dict(size=24, color="white", opacity=0.8),
367
+ hoverinfo="skip",
368
  )
369
  )
370
  fig.add_trace(
 
372
  lat=[lat],
373
  lon=[lon],
374
  mode="markers",
375
+ marker=dict(size=12, color="red"),
376
  text=["Search Center"],
377
  hoverinfo="text",
378
  )
379
  )
380
+
381
  fig.update_layout(
382
  map=dict(style="open-street-map", center={"lat": lat, "lon": lon}, zoom=9),
383
  margin={"r": 0, "t": 40, "l": 0, "b": 0},