Taiwan Weather Command Terminal:用中央氣象署開放資料打造台灣氣象儀表板

2026年4月1日

Taiwan Weather Command Terminal

為什麼做這個專案

中央氣象署的開放資料非常豐富,但大多是一大包 JSON。想做的是一個像指揮中心螢幕一樣的儀表板:打開就能看到現在的天氣、未來一週的變化,以及最近的地震。

視覺上刻意做成「終端機」風格:深色底、等寬英文標籤,像 LIVE_OPS、SYSTEM_ONLINE、SEISMIC_REPORT,連錯誤訊息都叫 SYSTEM_LINKAGE_FAILED。


技術架構

項目使用技術
框架Next.js 16(App Router)+ React 19 + TypeScript
資料請求TanStack Query:天氣每 10 分鐘、地震每 5 分鐘自動更新
圖表ECharts
地圖Leaflet + OpenStreetMap
樣式Tailwind CSS 4,預設深色模式
資料中央氣象署開放資料 API
部署Vercel

三大模組

即時氣象監測

選擇縣市後,顯示氣溫、相對濕度、風速、降雨機率與舒適度,並在地圖上標出位置。氣溫、濕度、風速來自氣象站即時觀測,天氣描述與降雨機率來自縣市 36 小時預報。

一週天氣預報

各縣市未來 7 天的白天與夜晚天氣、最高最低溫與降雨機率。桌機是完整表格;手機則改成可以展開收合的縣市清單,預設只展開第一個。

地震活動監控

最近 10 筆顯著有感地震:規模、深度、最大震度、震央位置,以及氣象署的報告圖。後端會依照規模與震度計算 1~4 級的警示等級。


實作細節

API Key 只留在伺服器端

三個資料來源都透過 Next.js 的 Route Handler 代理,前端只呼叫自己的 /api/weather、/api/forecast、/api/quake。氣象署的授權碼只存在伺服器的環境變數裡,瀏覽器完全看不到。

一週預報:把資料對齊到「白天」和「夜晚」

氣象署的一週預報是每 12 小時一筆,但第一筆從幾點開始會隨查詢時間改變:有時從早上 6 點開始,有時從中午 12 點開始。如果直接用陣列順序配對,白天和夜晚就會整個錯開。

最後改成用日期分組,再依時段放進白天或夜晚:

const dateKey = time.slice(0, 10);
if (time.includes('T06:00')) {
  dayMap[dateKey] = t;
} else if (time.includes('T12:00')) {
  if (!dayMap[dateKey]) dayMap[dateKey] = t;
} else if (time.includes('T18:00')) {
  nightMap[dateKey] = t;
}

氣溫和降雨機率也改成用時間當作查找的 key,而不是靠陣列索引,資料就不會錯位。

地震的最大震度

台灣的震度分級不是純數字,有「5弱」、「5強」這種寫法。計算最大震度時,先定義好排序,再從各地的震度中找出最大值:

['0','1','2','3','4','5弱','5強','6弱','6強','7']

目前的限制

空氣品質、紫外線和能見度目前是示範用的固定值,還沒有串接真實資料;即時氣溫圖表的時間序列也是以目前氣溫推算的示意。這些會是下一步要補上的部分。


小結

開放資料最麻煩的往往不是「拿到資料」,而是資料的格式和你想像的不一樣:時段會漂移、震度不是數字。把這些整理乾淨,前端才能專心把資訊呈現得一目了然。

🌐 線上 Demo | 💻 GitHub