Generalize NOAA settlement handling across dashboard and docs
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user