Restore observed temperatures on map and trend charts

This commit is contained in:
2569718930@qq.com
2026-04-16 15:29:26 +08:00
parent 767f7ed6bf
commit 25424700ce
3 changed files with 191 additions and 11 deletions
+23 -3
View File
@@ -52,6 +52,26 @@ function getMarkerDisplayOffset(cityName: string) {
};
}
function pickMarkerTemperature(
snapshot?: Pick<CityDetail, "current" | "temp_symbol"> | CitySummary,
) {
if (!snapshot) return null;
const detail = snapshot as Partial<CityDetail>;
const candidates = [
snapshot.current?.temp,
detail.airport_primary?.temp,
detail.airport_current?.temp,
detail.center_station_candidate?.temp,
detail.official_nearby?.[0]?.temp,
detail.mgm_nearby?.[0]?.temp,
];
for (const value of candidates) {
const numeric = Number(value);
if (Number.isFinite(numeric)) return numeric;
}
return null;
}
function createMarkerIcon(
city: CityListItem,
snapshot?: Pick<CityDetail, "current" | "temp_symbol"> | CitySummary,
@@ -60,8 +80,8 @@ function createMarkerIcon(
const label = city.display_name;
const unit = city.temp_unit === "fahrenheit" ? "°F" : "°C";
const shortName = label.length > 10 ? `${label.substring(0, 8)}...` : label;
const tempText =
snapshot?.current?.temp != null ? `${snapshot.current.temp}${unit}` : "--";
const markerTemp = pickMarkerTemperature(snapshot);
const tempText = markerTemp != null ? `${markerTemp}${unit}` : "--";
const offset = getMarkerDisplayOffset(city.name);
const styleAttr =
offset.x || offset.y
@@ -91,7 +111,7 @@ function getMarkerSignature(
city.temp_unit,
city.lat,
city.lon,
snapshot?.current?.temp ?? "",
pickMarkerTemperature(snapshot) ?? "",
].join("|");
}
+86 -2
View File
@@ -323,6 +323,78 @@ function sortObservationItemsByTime<T extends { time?: string | null }>(items: T
});
}
function normalizeObservationTimeForChart(
value: unknown,
detail: CityDetail,
) {
const raw = String(value || "").trim();
if (raw && !raw.includes("T")) {
return normalizeHm(raw) || raw;
}
return normalizeHm(detail.local_time) || normalizeHm(raw) || raw;
}
function buildCurrentObservationFallback(
detail: CityDetail,
): Array<{ time?: string; temp?: number | null; sourceLabel?: string | null }> {
const candidates: Array<{
sourceLabel?: string | null;
temp?: number | null;
time?: string | null;
}> = [
{
sourceLabel: detail.current?.settlement_source_label,
temp: detail.current?.temp,
time: detail.current?.obs_time || detail.current?.report_time,
},
{
sourceLabel: detail.airport_primary?.source_label || "METAR",
temp: detail.airport_primary?.temp,
time: detail.airport_primary?.obs_time || detail.airport_primary?.report_time,
},
{
sourceLabel: detail.airport_current?.source_label || "METAR",
temp: detail.airport_current?.temp,
time: detail.airport_current?.obs_time || detail.airport_current?.report_time,
},
{
sourceLabel:
detail.center_station_candidate?.source_label ||
detail.center_station_candidate?.source_code,
temp: detail.center_station_candidate?.temp,
time: String((detail.center_station_candidate as Record<string, unknown> | null | undefined)?.obs_time || ""),
},
{
sourceLabel:
detail.official_nearby?.[0]?.source_label ||
detail.official_nearby?.[0]?.source_code,
temp: detail.official_nearby?.[0]?.temp,
time: String((detail.official_nearby?.[0] as Record<string, unknown> | null | undefined)?.obs_time || ""),
},
{
sourceLabel:
detail.mgm_nearby?.[0]?.source_label ||
detail.mgm_nearby?.[0]?.source_code,
temp: detail.mgm_nearby?.[0]?.temp,
time: String((detail.mgm_nearby?.[0] as Record<string, unknown> | null | undefined)?.obs_time || ""),
},
];
const first = candidates.find((item) => {
const numeric = Number(item.temp);
return Number.isFinite(numeric);
});
if (!first) return [];
return [
{
sourceLabel: first.sourceLabel,
temp: Number(first.temp),
time: normalizeObservationTimeForChart(first.time, detail),
},
];
}
function interpolateSeriesAtMinutes(
times: string[],
values: Array<number | null | undefined>,
@@ -623,9 +695,19 @@ export function getTemperatureChartData(
? [{ time: detail.current.obs_time, temp: detail.current.temp }]
: []
: [];
const currentObservationFallback = buildCurrentObservationFallback(detail);
const metarObservationSource = detail.metar_today_obs?.length
? detail.metar_today_obs
: detail.trend?.recent || [];
: detail.trend?.recent?.length
? detail.trend.recent
: currentObservationFallback;
const usingCurrentObservationFallback =
!detail.metar_today_obs?.length &&
!detail.trend?.recent?.length &&
currentObservationFallback.length > 0;
const currentFallbackTag =
currentObservationFallback[0]?.sourceLabel ||
getObservationSourceTag(detail);
const allowMetarFallback = settlementSource && observationCode !== "hko";
const shouldUseMetarFallback =
allowMetarFallback &&
@@ -644,7 +726,9 @@ export function getTemperatureChartData(
return `${icao} METAR`;
})();
const observationDisplayTag =
observationCode === "wunderground"
usingCurrentObservationFallback
? String(currentFallbackTag).toUpperCase()
: observationCode === "wunderground"
? metarFallbackTag
: useSettlementObservationSource && shouldUseMetarFallback
? metarFallbackTag