Spaces:
Running
Running
# usgs_service.py | |
import requests | |
import pandas as pd | |
from datetime import datetime, timedelta, timezone | |
# ✨ CORRECTED IMPORT | |
from config.settings import USGS_API_BASE_URL, CURRENT_YEAR | |
def _iso(dt: datetime) -> str: | |
"""將 datetime 物件格式化為 USGS API 需要的 ISO 8601 字串。""" | |
return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S") | |
def fetch_global_last24h_text(min_mag: float = 5.0, limit: int = 10) -> str: | |
"""從 USGS 擷取過去 24 小時的全球顯著地震。""" | |
now_utc = datetime.now(timezone.utc) | |
since = now_utc - timedelta(hours=24) | |
params = { | |
"format": "geojson", | |
"starttime": _iso(since), | |
"endtime": _iso(now_utc), | |
"minmagnitude": float(min_mag), | |
"limit": int(limit), | |
"orderby": "time", | |
} | |
try: | |
r = requests.get(USGS_API_BASE_URL, params=params, timeout=15) | |
r.raise_for_status() | |
features = r.json().get("features", []) | |
if not features: | |
return f"✅ 過去 24 小時內,全球無規模 {min_mag} 以上的顯著地震。" | |
lines = [f"🚨 近 24 小時全球顯著地震 (M≥{min_mag}):", "-" * 20] | |
for f in features: | |
p = f["properties"] | |
t_utc = datetime.fromtimestamp(p["time"] / 1000, tz=timezone.utc) | |
lines.append( | |
# [修改] 將 "震級" 改為 "規模" | |
f"規模: {p['mag']:.1f} | 日期時間: {t_utc.strftime('%Y-%m-%d %H:%M')} (UTC)\n" | |
f"地點: {p.get('place', 'N/A')}\n" | |
f"報告連結: {p.get('url', '無')}" | |
) | |
return "\n\n".join(lines) | |
except Exception as e: | |
return f"❌ 查詢失敗:{e}" | |
def fetch_taiwan_df_this_year(min_mag: float = 5.0) -> pd.DataFrame | str: | |
"""從USGS擷取今年以來台灣區域的顯著地震。""" | |
now_utc = datetime.now(timezone.utc) | |
start_of_year_utc = datetime(now_utc.year, 1, 1, tzinfo=timezone.utc) | |
params = { | |
"format": "geojson", "starttime": _iso(start_of_year_utc), "endtime": _iso(now_utc), | |
"minmagnitude": float(min_mag), | |
"minlatitude": 21, "maxlatitude": 26, | |
"minlongitude": 119, "maxlongitude": 123, | |
"limit": 250, | |
"orderby": "time", | |
} | |
try: | |
r = requests.get(USGS_API_BASE_URL, params=params, timeout=20) | |
r.raise_for_status() | |
features = r.json().get("features", []) | |
if not features: | |
return f"✅ 今年 ({CURRENT_YEAR} 年) 以來,台灣區域無 M≥{min_mag:.1f} 的顯著地震。" | |
rows = [] | |
for f in features: | |
p = f["properties"] | |
lon, lat, *_ = f["geometry"]["coordinates"] | |
rows.append({ | |
"latitude": lat, | |
"longitude": lon, | |
"magnitude": p["mag"], | |
"place": p.get("place", ""), | |
"time_utc": datetime.fromtimestamp(p["time"]/1000, tz=timezone.utc), | |
"url": p.get("url", "") | |
}) | |
return pd.DataFrame(rows) | |
except Exception as e: | |
return f"❌ 查詢失敗: {e}" | |
# --- ✨ 以下是新增的函式 --- | |
def fetch_usgs_earthquakes_by_date(start_time_str: str, end_time_str: str, min_mag: float, limit: int = 20) -> str: | |
"""根據指定的日期範圍和最小規模,從 USGS API 查詢全球地震。""" | |
params = { | |
"format": "geojson", | |
"starttime": start_time_str, | |
"endtime": end_time_str, | |
"minmagnitude": float(min_mag), | |
"limit": int(limit), | |
"orderby": "time-asc", # 按時間正序排列 | |
} | |
try: | |
r = requests.get(USGS_API_BASE_URL, params=params, timeout=20) | |
r.raise_for_status() | |
features = r.json().get("features", []) | |
if not features: | |
return f"✅ 在 {start_time_str} 至 {end_time_str} 期間,全球無規模 {min_mag} 以上的地震紀錄。" | |
lines = [f"🔎 {start_time_str} 至 {end_time_str} 全球地震 (M≥{min_mag}):", "-" * 20] | |
for f in features: | |
p = f["properties"] | |
t_utc = datetime.fromtimestamp(p["time"] / 1000, tz=timezone.utc) | |
lines.append( | |
f"規模: {p['mag']:.1f} | 時間: {t_utc.strftime('%Y-%m-%d %H:%M')} (UTC)\n" | |
f"地點: {p.get('place', 'N/A')}\n" | |
f"報告: {p.get('url', '無')}" | |
) | |
if len(features) >= limit: | |
lines.append(f"\n(注意:結果已達上限 {limit} 筆,可能還有更多地震未顯示)") | |
return "\n\n".join(lines) | |
except Exception as e: | |
return f"❌ 查詢失敗:{e}" | |