Generalize NOAA settlement handling across dashboard and docs

This commit is contained in:
2569718930@qq.com
2026-03-27 20:58:38 +08:00
parent 15a452dd49
commit 7237278f5a
13 changed files with 374 additions and 51 deletions
@@ -75,6 +75,23 @@ const CITY_SPECIFIC_SOURCES: Record<string, OfficialSourceLink[]> = {
kind: "metar",
},
],
"lau fau shan": [
{
label: "香港天文台",
href: "https://www.hko.gov.hk/en/index.html",
kind: "agency",
},
{
label: "HKO 区域天气数据",
href: "https://data.weather.gov.hk/weatherAPI/hko_data/regional-weather/latest_1min_temperature.csv",
kind: "agency",
},
{
label: "HKO 实时读数页",
href: "https://www.hko.gov.hk/textonly/v2/forecast/text_readings_e.htm",
kind: "agency",
},
],
taipei: [
{
label: "NOAA RCTP Timeseries",
@@ -92,6 +109,23 @@ const CITY_SPECIFIC_SOURCES: Record<string, OfficialSourceLink[]> = {
kind: "metar",
},
],
istanbul: [
{
label: "NOAA LTFM Timeseries",
href: "https://www.weather.gov/wrh/timeseries?site=LTFM",
kind: "agency",
},
{
label: "Istanbul Airport",
href: "https://www.istairport.com/en",
kind: "airport",
},
{
label: "LTFM METAR",
href: "https://aviationweather.gov/data/metar/?id=LTFM&decoded=1&taf=1",
kind: "metar",
},
],
london: [
{
label: "Met Office",
+2
View File
@@ -50,6 +50,8 @@ export interface CurrentConditions {
wu_settlement: number | null;
settlement_source?: string | null;
settlement_source_label?: string | null;
station_code?: string | null;
station_name?: string | null;
obs_time: string | null;
obs_age_min: number | null;
wind_speed_kt: number | null;
+31 -8
View File
@@ -53,7 +53,13 @@ function getObservationSourceCode(detail: CityDetail): string {
const city = String(detail.name || detail.display_name || "")
.trim()
.toLowerCase();
if (city === "hong kong") return "hko";
if (
city === "hong kong" ||
city === "shek kong" ||
city === "lau fau shan"
) {
return "hko";
}
if (city === "taipei") return "noaa";
return "metar";
}
@@ -72,6 +78,20 @@ function getObservationSourceTag(detail: CityDetail): string {
return "METAR";
}
function getNoaaStationCode(detail: CityDetail): string {
return String(detail.current?.station_code || detail.risk?.icao || "NOAA")
.trim()
.toUpperCase();
}
function getNoaaStationName(detail: CityDetail): string {
return (
String(detail.current?.station_name || "").trim() ||
String(detail.risk?.airport || "").trim() ||
getNoaaStationCode(detail)
);
}
function normalizeCloudSummary(
cloudDesc: string | null | undefined,
locale: Locale,
@@ -297,7 +317,7 @@ export function getTemperatureChartData(
settlementSource && shouldUseMetarFallback
? metarFallbackTag
: observationCode === "noaa"
? "NOAA RCTP"
? `NOAA ${getNoaaStationCode(detail)}`
: observationCode === "wunderground"
? "Wunderground"
: observationTag;
@@ -574,14 +594,15 @@ export function getTemperatureChartData(
} else if (observationCode === "hko") {
legendParts.push(
isEnglish(locale)
? "Hong Kong uses HKO official readings. The chart keeps official HKO points instead of switching to airport METAR."
: "香港按 HKO 官方读数展示;图中保留 HKO 官方点位,不切换到机场 METAR 连续线。",
? "This city uses HKO official readings. The chart keeps official HKO points instead of switching to airport METAR."
: "该城市按 HKO 官方读数展示;图中保留 HKO 官方点位,不切换到机场 METAR 连续线。",
);
} else if (observationCode === "noaa") {
const noaaCode = getNoaaStationCode(detail);
legendParts.push(
isEnglish(locale)
? "Taipei settles on NOAA RCTP using the finalized highest rounded whole-degree Celsius reading; the plotted line is a settlement reference."
: "台北按 NOAA RCTP 最终完成质控后的最高整度摄氏结算;图中曲线仅作为结算参考线。",
? `This city settles on NOAA ${noaaCode} using the finalized highest rounded whole-degree Celsius Temp reading; the plotted line is a settlement reference.`
: `该城市按 NOAA ${noaaCode} 最终完成质控后的最高整度摄氏 Temp 读数结算;图中曲线仅作为结算参考线。`,
);
} else if (observationCode === "wunderground") {
legendParts.push(
@@ -2275,9 +2296,11 @@ export function getCityProfileStats(detail: CityDetail, locale: Locale = "zh-CN"
: "交通部中央气象署 (CWA)";
}
if (sourceCode === "noaa") {
const noaaCode = getNoaaStationCode(detail);
const noaaName = getNoaaStationName(detail);
return isEnglish(locale)
? "NOAA RCTP (Taiwan Taoyuan)"
: "NOAA RCTP(台湾桃园国际机场)";
? `NOAA ${noaaCode} (${noaaName})`
: `NOAA ${noaaCode}${noaaName}`;
}
if (sourceCode === "wunderground") {
const stationName = String(
+2 -2
View File
@@ -54,7 +54,7 @@ const MESSAGES: Record<Locale, Record<string, string>> = {
"guide.title": "📎 PolyWeather 系统技术说明",
"guide.closeAria": "关闭技术说明",
"guide.footer":
"数据源以 METAR、香港天文台(HKO)、NOAA RCTP、Turkish MGM、Open-Meteo、weather.gov 为主。",
"数据源以 METAR、香港天文台(HKO)、NOAA 指定站点、Turkish MGM、Open-Meteo、weather.gov 为主。",
"history.title": "📊 历史准确率对账 - {city}",
"history.closeAria": "关闭历史对账",
@@ -218,7 +218,7 @@ const MESSAGES: Record<Locale, Record<string, string>> = {
"guide.title": "📎 PolyWeather Technical Overview",
"guide.closeAria": "Close technical overview",
"guide.footer":
"Primary data sources are METAR, Hong Kong Observatory (HKO), NOAA RCTP, Turkish MGM, Open-Meteo, and weather.gov.",
"Primary data sources are METAR, Hong Kong Observatory (HKO), designated NOAA stations, Turkish MGM, Open-Meteo, and weather.gov.",
"history.title": "📊 Historical Reconciliation - {city}",
"history.closeAria": "Close history reconciliation",