cwadayi commited on
Commit
f4202e1
·
verified ·
1 Parent(s): 9286501

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -0
app.py ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import gradio as gr
3
+ from datetime import datetime, timedelta
4
+
5
+ # USGS API 的基礎 URL
6
+ USGS_API_BASE_URL = "https://earthquake.usgs.gov/fdsnws/event/1/query"
7
+
8
+ def format_earthquake_info_markdown(data):
9
+ """
10
+ 將從 API 獲取的地震資料格式化為 Markdown 字串。
11
+ """
12
+ if not data or 'features' not in data or not data['features']:
13
+ return "在指定的條件下,找不到任何地震資料。"
14
+
15
+ count = data['metadata']['count']
16
+ title = data['metadata']['title']
17
+
18
+ # 建立 Markdown 表格的標頭
19
+ md_output = f"## {title}\n\n"
20
+ md_output += f"**查詢成功,共找到 {count} 筆地震資料。**\n\n"
21
+ md_output += "| 時間 (UTC) | 地點 | 芮氏規模 | 深度 (公里) | 經緯度 |\n"
22
+ md_output += "|---|---|---|---|---|\n"
23
+
24
+ # 填入每一筆地震資料
25
+ for feature in data['features']:
26
+ properties = feature['properties']
27
+ geometry = feature['geometry']
28
+
29
+ event_time_utc = datetime.fromtimestamp(properties['time'] / 1000)
30
+ time_str = event_time_utc.strftime('%Y-%m-%d %H:%M:%S')
31
+
32
+ magnitude = properties['mag']
33
+ place = properties['place'].replace('|', '\|') # 避免 Markdown 表格語法衝突
34
+ longitude, latitude, depth = geometry['coordinates']
35
+
36
+ md_output += f"| {time_str} | {place} | {magnitude:.2f} | {depth:.2f} | ({latitude:.4f}, {longitude:.4f}) |\n"
37
+
38
+ return md_output
39
+
40
+ def query_earthquakes(
41
+ starttime_str: str,
42
+ endtime_str: str,
43
+ min_magnitude: float,
44
+ use_geo: bool,
45
+ min_lat: float, max_lat: float,
46
+ min_lon: float, max_lon: float
47
+ ):
48
+ """
49
+ 接收來自 Gradio UI 的輸入,查詢並回傳格式化的地震資料。
50
+ """
51
+ params = {
52
+ "format": "geojson",
53
+ "starttime": starttime_str,
54
+ "endtime": endtime_str,
55
+ "minmagnitude": min_magnitude,
56
+ "limit": 500, # 限制回傳數量,避免 UI 過於壅塞
57
+ "orderby": "time"
58
+ }
59
+
60
+ # 如果使用者勾選了 "指定地理範圍"
61
+ if use_geo:
62
+ # 簡單的驗證
63
+ if not all([min_lat, max_lat, min_lon, max_lon]):
64
+ return "錯誤:若要指定地理範圍,則經緯度四個欄位皆須填寫。"
65
+ if min_lat >= max_lat or min_lon >= max_lon:
66
+ return "錯誤:最小經緯度必須小於最大經緯度。"
67
+
68
+ params.update({
69
+ "minlatitude": min_lat,
70
+ "maxlatitude": max_lat,
71
+ "minlongitude": min_lon,
72
+ "maxlongitude": max_lon
73
+ })
74
+
75
+ try:
76
+ response = requests.get(USGS_API_BASE_URL, params=params, timeout=20)
77
+ response.raise_for_status()
78
+ data = response.json()
79
+ return format_earthquake_info_markdown(data)
80
+ except requests.exceptions.RequestException as e:
81
+ return f"錯誤:網路請求失敗: {e}"
82
+ except Exception as e:
83
+ return f"發生未知錯誤: {e}"
84
+
85
+ # --- Gradio 介面設計 ---
86
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
87
+ gr.Markdown("# 🌎 USGS 地震資料查詢工具")
88
+ gr.Markdown("透過此工具,您可以查詢美國地質調查局 (USGS) 的全球地震紀錄。")
89
+
90
+ with gr.Row():
91
+ with gr.Column(scale=1):
92
+ gr.Markdown("### 1. 設定查詢條件")
93
+ # 預設查詢時間為過去 7 天
94
+ today = datetime.now()
95
+ seven_days_ago = today - timedelta(days=7)
96
+
97
+ starttime_input = gr.Textbox(label="查詢開始日期", value=seven_days_ago.strftime('%Y-%m-%d'))
98
+ endtime_input = gr.Textbox(label="查詢結束日期", value=today.strftime('%Y-%m-%d'))
99
+
100
+ magnitude_slider = gr.Slider(
101
+ minimum=0, maximum=10, step=0.1,
102
+ label="最小芮氏規模",
103
+ value=4.5
104
+ )
105
+
106
+ gr.Markdown("### 2. (可選) 指定地理範圍")
107
+ use_geo_checkbox = gr.Checkbox(label="啟用地理範圍篩選", value=False)
108
+
109
+ with gr.Row():
110
+ min_lat_input = gr.Number(label="最小緯度 (南)", value=21.5)
111
+ max_lat_input = gr.Number(label="最大緯度 (北)", value=25.5)
112
+ with gr.Row():
113
+ min_lon_input = gr.Number(label="最小經度 (西)", value=120.0)
114
+ max_lon_input = gr.Number(label="最大經度 (東)", value=122.5)
115
+
116
+ submit_btn = gr.Button("開始查詢", variant="primary")
117
+
118
+ with gr.Column(scale=3):
119
+ gr.Markdown("### 查詢結果")
120
+ output_markdown = gr.Markdown("點擊「開始查詢」後,結果將會顯示於此。")
121
+
122
+ # 綁定按鈕點擊事件
123
+ submit_btn.click(
124
+ fn=query_earthquakes,
125
+ inputs=[
126
+ starttime_input,
127
+ endtime_input,
128
+ magnitude_slider,
129
+ use_geo_checkbox,
130
+ min_lat_input, max_lat_input,
131
+ min_lon_input, max_lon_input
132
+ ],
133
+ outputs=output_markdown
134
+ )
135
+
136
+ gr.Examples(
137
+ examples=[
138
+ [seven_days_ago.strftime('%Y-%m-%d'), today.strftime('%Y-%m-%d'), 6.0, False, 0, 0, 0, 0],
139
+ ["2024-04-02", "2024-04-04", 5.5, True, 23.0, 25.0, 121.0, 122.5],
140
+ ["2024-01-01", "2024-01-02", 7.0, True, 35.0, 38.0, 136.0, 140.0],
141
+ ],
142
+ inputs=[
143
+ starttime_input,
144
+ endtime_input,
145
+ magnitude_slider,
146
+ use_geo_checkbox,
147
+ min_lat_input, max_lat_input,
148
+ min_lon_input, max_lon_input
149
+ ],
150
+ outputs=output_markdown,
151
+ fn=query_earthquakes,
152
+ cache_examples=True # 讓範例結果快取,加速載入
153
+ )
154
+
155
+ if __name__ == "__main__":
156
+ demo.launch()