From fd210ac73007efe9b0e7f4bbcfb42b4965fbbc4a Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Wed, 25 Mar 2026 17:14:25 +0800 Subject: [PATCH] Show Wunderground settlement sources in the dashboard --- .../dashboard/FutureForecastModal.tsx | 11 ++++- frontend/lib/dashboard-utils.ts | 43 ++++++++++++++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/frontend/components/dashboard/FutureForecastModal.tsx b/frontend/components/dashboard/FutureForecastModal.tsx index 218cc6b0..508064fe 100644 --- a/frontend/components/dashboard/FutureForecastModal.tsx +++ b/frontend/components/dashboard/FutureForecastModal.tsx @@ -730,7 +730,10 @@ export function FutureForecastModal() { detail.current?.settlement_source || "", ).toLowerCase(); const isOfficialSettlementSource = - settlementSourceCode === "hko" || settlementSourceCode === "cwa"; + settlementSourceCode === "hko" || + settlementSourceCode === "cwa" || + settlementSourceCode === "noaa" || + settlementSourceCode === "wunderground"; const settlementProfileLabel = isOfficialSettlementSource ? locale === "en-US" ? "Settlement source" @@ -745,10 +748,14 @@ export function FutureForecastModal() { ? locale === "en-US" ? "NOAA RCTP (Taiwan Taoyuan International Airport)" : "NOAA RCTP(台湾桃园国际机场)" - : settlementSourceCode === "cwa" + : settlementSourceCode === "cwa" ? locale === "en-US" ? "Central Weather Administration (CWA)" : "交通部中央气象署 (CWA)" + : settlementSourceCode === "wunderground" + ? locale === "en-US" + ? `${detail.current?.settlement_source_label || risk.airport || "Wunderground"}` + : `${detail.current?.settlement_source_label || risk.airport || "Wunderground"}` : risk.airport ? `${risk.airport}${risk.icao ? ` (${risk.icao})` : ""}` : "--"; diff --git a/frontend/lib/dashboard-utils.ts b/frontend/lib/dashboard-utils.ts index e6dfb5fa..c5c8dbfa 100644 --- a/frontend/lib/dashboard-utils.ts +++ b/frontend/lib/dashboard-utils.ts @@ -67,6 +67,7 @@ function getObservationSourceTag(detail: CityDetail): string { if (code === "hko") return "HKO"; if (code === "cwa") return "CWA"; if (code === "noaa") return "NOAA"; + if (code === "wunderground") return "WUNDERGROUND"; if (code === "mgm") return "MGM"; return "METAR"; } @@ -254,7 +255,10 @@ export function getTemperatureChartData( const observationTag = getObservationSourceTag(detail); const observationCode = getObservationSourceCode(detail); const settlementSource = - observationCode === "hko" || observationCode === "cwa" || observationCode === "noaa"; + observationCode === "hko" || + observationCode === "cwa" || + observationCode === "noaa" || + observationCode === "wunderground"; const officialObservationSource = settlementSource ? detail.settlement_today_obs?.length @@ -267,7 +271,9 @@ export function getTemperatureChartData( ? detail.metar_today_obs : detail.trend?.recent || []; const allowMetarFallback = - settlementSource && observationCode !== "hko"; + settlementSource && + observationCode !== "hko" && + observationCode !== "wunderground"; const shouldUseMetarFallback = allowMetarFallback && officialObservationSource.length > 0 && @@ -288,6 +294,8 @@ export function getTemperatureChartData( ? metarFallbackTag : observationCode === "noaa" ? "NOAA RCTP" + : observationCode === "wunderground" + ? "Wunderground" : observationTag; const metarPoints = new Array(times.length).fill(null); @@ -424,6 +432,12 @@ export function getTemperatureChartData( ? "Taipei settles on NOAA RCTP using the finalized highest rounded whole-degree Celsius reading; the plotted line is a settlement reference." : "台北按 NOAA RCTP 最终完成质控后的最高整度摄氏值结算;图中曲线仅作为结算参考线。", ); + } else if (observationCode === "wunderground") { + legendParts.push( + isEnglish(locale) + ? "This city settles on the configured Wunderground station; the plotted observation points follow that settlement source." + : "该城市按配置的 Wunderground 站点结算;图中实测点位按该结算源展示。", + ); } if (tafMarkers.length) { const tafText = tafMarkers @@ -450,7 +464,8 @@ export function getTemperatureChartData( temps, }, observationLabel: - observationCode === "noaa" && !shouldUseMetarFallback + (observationCode === "noaa" || observationCode === "wunderground") && + !shouldUseMetarFallback ? isEnglish(locale) ? `${observationDisplayTag} Settlement Reference` : `${observationDisplayTag} 结算参考` @@ -2064,7 +2079,11 @@ export function getCityProfileStats(detail: CityDetail, locale: Locale = "zh-CN" const current = detail.current || {}; const nearbyCount = Array.isArray(detail.mgm_nearby) ? detail.mgm_nearby.length : 0; const sourceCode = getObservationSourceCode(detail); - const isOfficialSource = sourceCode === "hko" || sourceCode === "cwa" || sourceCode === "noaa"; + const isOfficialSource = + sourceCode === "hko" || + sourceCode === "cwa" || + sourceCode === "noaa" || + sourceCode === "wunderground"; const sourceDisplay = (() => { if (sourceCode === "hko") { @@ -2082,6 +2101,16 @@ export function getCityProfileStats(detail: CityDetail, locale: Locale = "zh-CN" ? "NOAA RCTP (Taiwan Taoyuan)" : "NOAA RCTP(台湾桃园国际机场)"; } + if (sourceCode === "wunderground") { + const stationName = String( + detail.current?.settlement_source_label || + detail.risk?.airport || + "Wunderground", + ).trim(); + return isEnglish(locale) + ? `${stationName} (Wunderground)` + : `${stationName}(Wunderground)`; + } const tag = getObservationSourceTag(detail); if (sourceCode === "mgm") { return isEnglish(locale) ? `MGM (${tag})` : `MGM (${tag})`; @@ -2144,7 +2173,11 @@ export function getSettlementRiskNarrative( ) { const risk = detail.risk || {}; const sourceCode = getObservationSourceCode(detail); - const stationTerm = sourceCode === "hko" || sourceCode === "cwa" || sourceCode === "noaa" + const stationTerm = + sourceCode === "hko" || + sourceCode === "cwa" || + sourceCode === "noaa" || + sourceCode === "wunderground" ? isEnglish(locale) ? "settlement reference station" : "结算参考站"