Skip to content

雷達風向疊圖、選單點了不關,震度 0 不再被 S 波染色、重播圖例可收合 - #574

Open
PiscesXD wants to merge 4 commits into
mainfrom
feat-map-layers
Open

雷達風向疊圖、選單點了不關,震度 0 不再被 S 波染色、重播圖例可收合#574
PiscesXD wants to merge 4 commits into
mainfrom
feat-map-layers

Conversation

@PiscesXD

@PiscesXD PiscesXD commented Sep 12, 2026

Copy link
Copy Markdown
Member

這個 PR 做了什麼

五件事,四件在地圖上:雷達回波多了一個「顯示風向」疊圖(畫同一幀時間的測站風向風速,和顯示閃電互斥);所有圖層的選項選單改成點一列不會自動關閉;強震監視器與報告重播在速報期間,震度 0 的鄉鎮不再被 S 波圓盤染色;報告重播的震度圖例可以收起來。第五件在測試裡:雷達疊圖那幾組不再靠猜事件圈數等非同步工作 —— 那是滿載時 lightning overlay 會偶爾紅的真正原因。

相關 issue

怎麼驗

1/5 雷達風向(feat(map))

  1. 地圖 → 雷達回波 → 右上角選項選單,「資料圖層」那段多一列「顯示風向」,預設關。
  2. 打開後島上出現測站箭頭:箭頭指向風吹去的方向(氣象的「風從哪來」+180°),顏色是風速分段,右下圖例會多一段帶 m/s 的鍵。
  3. 「顯示閃電」和「顯示風向」最多只有一個開著 —— 打開一個會自動關掉另一個。兩列都還是可以點,不會變灰。
  4. 拖時間軸往回,箭頭跟著換成那個時刻在吹的風,不是現在的風。
  5. 關掉再打開、切到別的圖層再回來、切深色模式(會重烘箭頭圖),都要乾淨重建,不殘留上一次的箭頭。
  6. 和單獨的「風向」圖層同時用不會互相干擾 —— 兩邊各自掛在自己的 source/layer id 上(radar-wind-* vs wind-arrow-*)。

時間對齊這段最值得看,因為兩邊的刻度差很多:

來源 端點 間隔
雷達回波 /api/v2/tiles/radar/list 10 分鐘
閃電 /api/v5/meteor/lightning/list 5 分鐘
測站觀測 /api/v5/meteor/weather/list 1 小時

觀測是整點一筆(差量全是 3600,連 latesttime 都落在整點)。所以風向不是照閃電那樣取「最近一筆 ±10 分」—— 那樣一小時六張影格裡只有三張對得上,拖時間軸時箭頭會一直閃掉。改成取該影格時刻當下生效的那筆(時間 ≤ 影格時間、且最新),一筆整點觀測覆蓋它之後的六張影格。

跟著這個規則要確認兩件事:

  • 往回拖不會看到未來的風。 16:40 的影格最近的一筆是 17:00(差 20 分),但那是這張回波拍完之後才量到的,不畫。
  • 斷更或超出範圍會停在「掛著但不畫」,不會拿舊資料充當現況。 最後一筆超過一小時、或時間軸拖到觀測歷史之外(回波存 7 天、觀測只有 3 天)都算。這是 ARCHITECTURE.md 那條「stale 的資料不得呈現為現況」,所以 showEmpty() 保留圖層本身,讓「開著但沒資料」和「關掉」在畫面上是兩件事。

2/5 選項選單不再自動關閉(fix(map))

  1. 任何圖層右上角的篩選器,點一列不會關選單 —— 可以連續改好幾列、邊看底下的地圖邊調。
  2. 再點篩選器本身、或點選單外的空白處,才會關。
  3. 例外:GSI 那列「詳細」會開 bottom sheet,仍然會關 —— 它不是用 MapMenuToggleRow 做的,維持原本行為。
  4. 受影響的選單:雷達、颱風、衛星雲圖、災害、雨量(含颱風暴風圈、衛星樣式、雨量級距這些單選列,一併改成一致)。

3/5 震度 0 不再被 S 波染色(fix(map))

現象:強震監視器有速報時,震度 0 的鄉鎮會被 EEW 的 S 波圓盤染上一層紅。

成因要從 c8fb4372 fix(map): keep the OSM ground visible under the township wash 說起 —— 那次把震度洗(town 圖層)在震度 0 的 match fallback 從灰色改成 rgba(0, 0, 0, 0),好讓 OSM 詳細底圖透出來,但沒動到旁邊那行:速報期間 county 圖層被設成 fillOpacity: 0。疊圖順序是

bg → land → county → [OSM 地面] → town(震度洗) → [OSM 道路] → 界線 → 標籤

而 S 波圓盤(fillOpacity: 0.16)是刻意掛在 belowLayerId: landLayerId,讓它只染開闊海面。於是速報一來、某個鄉鎮估到 0:洗是透明的、county 被藏起來,台灣上面沒有任何不透明的圖層,下面那圈 S 波就透上來了。

改法不是把 fallback 改回灰色(那會把 c8fb4372 修的 OSM 問題再弄回來),而是county 在有無速報時都維持原本的灰色,寫在分支前面:

  1. 強震監視器,等一個有速報的時刻(或用 demo/replay 重現)。
  2. 震度 0 的鄉鎮 + OSM 詳細底圖關 → 看到原本的灰色島,S 波不會透上來
  3. 震度 0 的鄉鎮 + OSM 詳細底圖開 → OSM 地面仍在 county 之上、洗之下,照樣看得到 —— c8fb4372 修的東西沒有退回去。
  4. 有震度的鄉鎮 → 洗蓋在最上面,顏色與級距不變。
  5. 海上的 S 波圓盤照樣要看得到 —— 它本來就只該染海。

report_replay_page.dart_updateAreaFillrts_layer.dart 是逐字複製的同一段,同一個 bug,一起改;map_style.dart 上兩段已經過期的註解(還在講「洗可以直接把 county 藏掉」)也一併更新。

4/5 重播圖例可以收合(feat(eew))

報告重播是自己一頁全螢幕地圖、沒走 MapScaffold,所以漏掉了 CollapsibleMapLegend —— 雷達、衛星、雨量那些圖例本來就是預設收合成一顆「圖例」鈕、點開才展開。這次補上,沒有新字串(圖例收合圖例 12 個 locale 都已經有了)。

  1. 進重播頁,左上角返回鈕下面是一顆「圖例」鈕,不是攤開的尺標 —— 十一格的連續震度尺標攤著會壓在島的西北角一整段重播。
  2. 點開展開,右上角有收合鈕,再點收回去。
  3. 重播中途來速報:尺標從連續儀器震度(−37)換成分級震度(17),但圖例不會被關掉 —— 收合狀態包在 mode 切換的外層,換的是「哪個尺標」,不是「你要不要看」。

5/5 雷達疊圖測試不再靠猜事件圈數(test(map))

滿載跑全套時 radar_layer_test.dartlightning overlay 那組會偶爾掛(先是
draws the snapshot nearest the frame,後來換成 draws nothing when no snapshot is near the frame),斷言看到的是 source 還沒掛上。不是疊圖本身的 bug,是測試等的方式:

shown()await pumpEventQueue() 等疊圖工作落地,而 pumpEventQueue() 預設只給
20 圈事件圈。疊圖掛載時要烘八顆圖示,每顆走 Picture.toImage + toByteData(png)
—— 那是 engine 的回覆,不是 microtask,16 次各自佔一圈。實測把圈數壓到 16 就穩定
失敗、20 才會過,也就是說單單烘圖就把預算吃光,後面的 history 抓取、addSource
addSymbolLayer、第一次 setGeoJsonSource 全都在借剩下那三四圈 —— 機器閒著時有些回覆
會併在同一圈所以塞得進去,滿載時就塞不進去。

改法是不要猜:RadarMapLayer 開一個 @visibleForTestingoverlaySettled,直接回
那條序列化疊圖工作的 chain,測試 await 它。閃電、風向、兩者互斥三組共 11 處 await pumpEventQueue() 換成 await layer.overlaySettled,等待條件從「圈數夠不夠」變成「工作
做完了沒有」,和機器負載無關。

測試

  • test/features/map/radar_layer_test.dart 63 個(風向疊圖新增一組 group,含三條時間對齊的邊界;閃電/風向/互斥三組的等待方式一併換掉)
  • test/features/map/radar_overlay_menu_test.dart 12 個(三方互斥、以及「點一列選單留著/點篩選器才關」)
  • test/features/map/presentation/layers/rts_layer_demo_test.dart 新增一條:放一個震央上的鄉鎮和一個 250 km 外的鄉鎮,斷言洗的 fallback 還是透明而且 countyfill-opacity 是 1
  • test/features/earthquake/presentation/widgets/intensity_legend_chip_test.dart 新增 2 條:預設收合/點開/收回,以及「速報換尺標不會關掉已展開的圖例」

全套 tool/dev/test.sh 1832 passed / 5 skipped(連兩次綠)。tool/dev/analyze.sh 乾淨,tool/check/commits.sh origin/main..HEAD 5 則全過。

先前這裡寫著「lightning overlay 那條是既有 flake、重跑就好」—— 那個判斷是錯的,同一組裡第二條也掛之後回去查,成因就是上面第 5 則講的等待方式。已經修掉,不用重跑。

檢查清單

  • tool/check/commits.sh origin/main..HEAD 通過
    —— commit 訊息就是更新日誌,格式見 commit.md
  • 一個 commit 一件事
    —— 五件事拆成五則;radar_overlay_menu_test.dart 一個檔同時含前兩件事,
    所以先把只含「點一列選單留著」的中間版本進第一則、確認那棵樹是綠的,再還原最終版進第二則
  • mise exec -- flutter analyzemise exec -- flutter test 通過
    —— 走 tool/dev/analyze.shtool/dev/test.sh
  • 新的使用者可見字串都走 AppLocalizations,沒有寫死
    —— 「顯示風向」12 個 locale 都補齊了;圖例收合沿用既有的 mapLegendExpand
    mapLegendCollapse,沒有新增字串
  • 有 UI 變更的話:用的是 AppSpacing / AppRadius / AppMotion,
    深色模式看過,文字對比度可接受
    —— 風向是既有雷達選單裡多一列,沿用同一個 row 樣式;箭頭圖例沿用
    SymbolLegendItem,箭頭本身是預先烘好的 PNG 且跟著色覺輔助設定重烘;
    圖例收合直接沿用 CollapsibleMapLegend,和其他圖層同一個外觀與動畫

Fix(zh-Hant): 圖層選項選單改成點選項目後不再自動關閉,只有點篩選器或空白處才會關閉
Fix(en-US): Keep the layer options menu open when a row is tapped; only the chip or a tap outside closes it
New(zh-Hant): 雷達回波圖新增「顯示風向」圖層,畫出同一時刻的測站風向風速,和顯示閃電兩者只能擇一
New(en-US): Add a wind overlay to the radar echo drawing the same frame's station wind, exclusive with the lightning overlay
@PiscesXD PiscesXD changed the title Feat map layers 雷達回波疊同一幀的測站風向,圖層選項選單改成點了不關 Sep 12, 2026
Fix(zh-Hant): 震度速報期間,震度 0 的鄉鎮不再被 S 波圓盤染上顏色
Fix(en-US): Stop the EEW S-wave disc showing through townships the estimate puts at 0
New(zh-Hant): 報告重播的震度圖例可以收起來了,預設收合成一顆「圖例」按鈕
New(en-US): The report replay's intensity legend now collapses, and starts collapsed as a legend chip
@lowrt lowrt added this to the v26.3 milestone Sep 12, 2026
@PiscesXD PiscesXD changed the title 雷達回波疊同一幀的測站風向,圖層選項選單改成點了不關 雷達風向疊圖、選單點了不關,震度 0 不再被 S 波染色、重播圖例可收合 Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants