fix: use IMGW Hybrid for current weather
This commit is contained in:
10
lib/i18n.tsx
10
lib/i18n.tsx
@@ -61,6 +61,7 @@ const translations = {
|
||||
"weather.humidity": "Wilgotność",
|
||||
"weather.wind": "Wiatr",
|
||||
"weather.rainfall": "Suma opadu",
|
||||
"weather.rainfall10m": "Opad 10 min",
|
||||
"weather.pressure": "Ciśnienie",
|
||||
"weather.feelsLike": "Odczuwalna",
|
||||
"weather.measurement": "pomiar",
|
||||
@@ -68,6 +69,10 @@ const translations = {
|
||||
"weather.calm": "Spokojne warunki",
|
||||
"weather.humid": "Wilgotno",
|
||||
"weather.strongWind": "Silny wiatr",
|
||||
"weather.currentRain": "Opady deszczu",
|
||||
"weather.currentSnow": "Opady śniegu",
|
||||
"weather.thunderstorm": "Burza",
|
||||
"weather.hybridAnalysis": "analiza IMGW Hybrid",
|
||||
"weather.airTemperature": "Temperatura",
|
||||
"weather.windSpeed": "Prędkość wiatru",
|
||||
"weather.rainfallTotal": "Suma opadu",
|
||||
@@ -228,6 +233,7 @@ const translations = {
|
||||
"weather.humidity": "Humidity",
|
||||
"weather.wind": "Wind",
|
||||
"weather.rainfall": "Rainfall total",
|
||||
"weather.rainfall10m": "Rainfall 10 min",
|
||||
"weather.pressure": "Pressure",
|
||||
"weather.feelsLike": "Feels like",
|
||||
"weather.measurement": "measurement",
|
||||
@@ -235,6 +241,10 @@ const translations = {
|
||||
"weather.calm": "Calm conditions",
|
||||
"weather.humid": "Humid",
|
||||
"weather.strongWind": "Strong wind",
|
||||
"weather.currentRain": "Rain",
|
||||
"weather.currentSnow": "Snow",
|
||||
"weather.thunderstorm": "Thunderstorm",
|
||||
"weather.hybridAnalysis": "IMGW Hybrid analysis",
|
||||
"weather.airTemperature": "Temperature",
|
||||
"weather.windSpeed": "Wind speed",
|
||||
"weather.rainfallTotal": "Rainfall total",
|
||||
|
||||
77
lib/imgw-current-api.ts
Normal file
77
lib/imgw-current-api.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { toNumber } from "@/lib/weather-utils";
|
||||
import type { ImgwCurrentWeather, RawImgwHybridWeatherResponse, RawImgwHybridWeatherRow } from "@/types/imgw-current";
|
||||
|
||||
function toCelsius(value: unknown) {
|
||||
const temperature = toNumber(value);
|
||||
if (temperature === null) return null;
|
||||
return temperature > 150 ? temperature - 273.15 : temperature;
|
||||
}
|
||||
|
||||
function toHectopascals(value: unknown) {
|
||||
const pressure = toNumber(value);
|
||||
if (pressure === null) return null;
|
||||
return pressure > 2_000 ? pressure / 100 : pressure;
|
||||
}
|
||||
|
||||
function normalizeDate(value: unknown) {
|
||||
if (typeof value !== "string") return null;
|
||||
const date = new Date(value);
|
||||
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
||||
}
|
||||
|
||||
function getWeatherCode(iconCode: unknown) {
|
||||
if (typeof iconCode !== "string") return null;
|
||||
const match = iconCode.match(/z(\d{2})/i);
|
||||
return match ? Number(match[1]) : null;
|
||||
}
|
||||
|
||||
function getCondition(weatherCode: number | null, rainfall10m: number | null, snowfall10m: number | null) {
|
||||
if (weatherCode !== null && weatherCode >= 95) return "thunderstorm" as const;
|
||||
if ((snowfall10m ?? 0) > 0) return "snow" as const;
|
||||
if ((rainfall10m ?? 0) > 0) return "rain" as const;
|
||||
return null;
|
||||
}
|
||||
|
||||
export function normalizeImgwCurrentWeather(payload: RawImgwHybridWeatherResponse): ImgwCurrentWeather | null {
|
||||
if (!payload.data?.Valid || !Array.isArray(payload.data.Data)) return null;
|
||||
|
||||
const row = payload.data.Data
|
||||
.filter((candidate): candidate is RawImgwHybridWeatherRow => {
|
||||
if (!candidate || typeof candidate !== "object") return false;
|
||||
return candidate.Type === "Type_Ten_Minutes"
|
||||
&& typeof candidate.MODEL === "string"
|
||||
&& candidate.MODEL.includes("AROME")
|
||||
&& normalizeDate(candidate.Date) !== null;
|
||||
})
|
||||
.sort((left, right) => String(right.Date).localeCompare(String(left.Date)))[0];
|
||||
if (!row) return null;
|
||||
|
||||
const measuredAt = normalizeDate(row.Date);
|
||||
if (!measuredAt) return null;
|
||||
const rainfall10m = toNumber(row.Rain10m);
|
||||
const snowfall10m = toNumber(row.Snow10m);
|
||||
const weatherCode = getWeatherCode(row.Icon10);
|
||||
|
||||
return {
|
||||
measuredAt,
|
||||
temperature: toCelsius(row.Temperature),
|
||||
feelsLike: toCelsius(row.Chill),
|
||||
windSpeed: toNumber(row.Wind_Speed),
|
||||
windDirection: toNumber(row.Wind_Dir),
|
||||
humidity: toNumber(row.Humidity),
|
||||
pressure: toHectopascals(row.PressureMSL),
|
||||
precipitation10m: toNumber(row.Precipitation10m),
|
||||
rainfall10m,
|
||||
snowfall10m,
|
||||
cloudCover: toNumber(row.Cloud),
|
||||
weatherCode,
|
||||
condition: getCondition(weatherCode, rainfall10m, snowfall10m),
|
||||
};
|
||||
}
|
||||
|
||||
export async function fetchImgwCurrentWeather(latitude: number, longitude: number, signal?: AbortSignal) {
|
||||
const params = new URLSearchParams({ latitude: String(latitude), longitude: String(longitude) });
|
||||
const response = await fetch(`/api/imgw-current?${params}`, { signal });
|
||||
if (!response.ok) throw new Error("Nie udało się pobrać bieżącej analizy IMGW Hybrid.");
|
||||
return normalizeImgwCurrentWeather(await response.json() as RawImgwHybridWeatherResponse);
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
} from "@/types/imgw";
|
||||
import { translate, type Language } from "@/lib/i18n";
|
||||
import { getProvinceFromTeryt, normalizeProvinceName } from "@/lib/provinces";
|
||||
import type { CurrentWeatherCondition } from "@/types/imgw-current";
|
||||
|
||||
const locales: Record<Language, string> = { pl: "pl-PL", en: "en-GB" };
|
||||
|
||||
@@ -174,7 +175,10 @@ export function getWeatherMoodFromData(station: SynopStation, date = new Date())
|
||||
return "mild";
|
||||
}
|
||||
|
||||
export function getWeatherDescription(station: SynopStation, language: Language = "pl") {
|
||||
export function getWeatherDescription(station: SynopStation, language: Language = "pl", condition?: CurrentWeatherCondition) {
|
||||
if (condition === "thunderstorm") return translate(language, "weather.thunderstorm");
|
||||
if (condition === "snow") return translate(language, "weather.currentSnow");
|
||||
if (condition === "rain") return translate(language, "weather.currentRain");
|
||||
if ((station.windSpeed ?? 0) >= 8) return translate(language, "weather.strongWind");
|
||||
if ((station.humidity ?? 0) >= 90) return translate(language, "weather.humid");
|
||||
return translate(language, "weather.calm");
|
||||
|
||||
Reference in New Issue
Block a user