From e2c51f5125b39670eefa7a483cbf298b3664974f Mon Sep 17 00:00:00 2001 From: "2569718930@qq.com" <2569718930@qq.com> Date: Sun, 22 Mar 2026 22:43:06 +0800 Subject: [PATCH] Use METAR fallback for sparse official observation charts --- frontend/lib/dashboard-utils.ts | 48 +++++++++++++++++++++++++-------- web/analysis_service.py | 16 ++++------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/frontend/lib/dashboard-utils.ts b/frontend/lib/dashboard-utils.ts index 308ec730..dbf358a1 100644 --- a/frontend/lib/dashboard-utils.ts +++ b/frontend/lib/dashboard-utils.ts @@ -240,15 +240,34 @@ export function getTemperatureChartData( const observationCode = getObservationSourceCode(detail); const settlementSource = observationCode === "hko" || observationCode === "cwa"; + const officialObservationSource = + settlementSource + ? detail.settlement_today_obs?.length + ? detail.settlement_today_obs + : detail.current?.obs_time && detail.current?.temp != null + ? [{ time: detail.current.obs_time, temp: detail.current.temp }] + : [] + : []; + const metarObservationSource = detail.metar_today_obs?.length + ? detail.metar_today_obs + : detail.trend?.recent || []; + const shouldUseMetarFallback = + settlementSource && + officialObservationSource.length > 0 && + officialObservationSource.length < 3 && + metarObservationSource.length >= 3; const observationSource = settlementSource - ? detail.settlement_today_obs?.length - ? detail.settlement_today_obs - : detail.current?.obs_time && detail.current?.temp != null - ? [{ time: detail.current.obs_time, temp: detail.current.temp }] - : [] - : detail.metar_today_obs?.length - ? detail.metar_today_obs - : detail.trend?.recent || []; + ? shouldUseMetarFallback + ? metarObservationSource + : officialObservationSource + : metarObservationSource; + const metarFallbackTag = (() => { + const icao = String(detail.risk?.icao || "").trim().toUpperCase(); + if (!icao) return "METAR"; + return `${icao} METAR`; + })(); + const observationDisplayTag = + settlementSource && shouldUseMetarFallback ? metarFallbackTag : observationTag; const metarPoints = new Array(times.length).fill(null); observationSource.forEach((item) => { @@ -329,7 +348,14 @@ export function getTemperatureChartData( .reverse() .map((item) => `${item.temp}${detail.temp_symbol}@${item.time}`) .join(" -> "); - legendParts.push(`${observationTag}: ${recentText}`); + legendParts.push(`${observationDisplayTag}: ${recentText}`); + } + if (shouldUseMetarFallback) { + legendParts.push( + isEnglish(locale) + ? `Official ${observationTag} feed is sparse today, so the continuous observation line switches to ${metarFallbackTag}.` + : `今日官方 ${observationTag} 点位较稀疏,连续实测线改用 ${metarFallbackTag}。`, + ); } return { @@ -344,8 +370,8 @@ export function getTemperatureChartData( temps, }, observationLabel: isEnglish(locale) - ? `${observationTag} Observation` - : `${observationTag} 实况`, + ? `${observationDisplayTag} Observation` + : `${observationDisplayTag} 实况`, legendText: legendParts.join(" | "), max, min, diff --git a/web/analysis_service.py b/web/analysis_service.py index 3ad81f47..b4bea362 100644 --- a/web/analysis_service.py +++ b/web/analysis_service.py @@ -147,17 +147,11 @@ def _analyze(city: str, force_refresh: bool = False) -> Dict[str, Any]: ): settlement_today_obs.append({"time": str(max_temp_time), "temp": max_so_far}) - metar_today_obs_payload = ( - [] - if use_settlement_current - else [ - {"time": t, "temp": v} - for t, v in (metar.get("today_obs", []) if metar else []) - ] - ) - metar_recent_obs_payload = ( - [] if use_settlement_current else (metar.get("recent_obs", []) if metar else []) - ) + metar_today_obs_payload = [ + {"time": t, "temp": v} + for t, v in (metar.get("today_obs", []) if metar else []) + ] + metar_recent_obs_payload = metar.get("recent_obs", []) if metar else [] # ── 3. Local time parsing ── local_time_full = om.get("current", {}).get("local_time", "")