142 lines
10 KiB
Markdown
142 lines
10 KiB
Markdown
# wtr.
|
|
|
|
**Pogoda z danych IMGW. Prosto. Pięknie. Aktualnie.**
|
|
|
|
`wtr.` to nowoczesna pogodowa PWA dla Polski oparta o publiczne dane IMGW i jawnie oznaczoną prognozę modelową łączącą IMGW ALARO z Open-Meteo. Aplikacja prezentuje bieżącą analizę pogody IMGW Hybrid, odczyty synoptyczne, prognozę godzinową i 7-dniową, stacje hydrologiczne oraz ostrzeżenia w spokojnym, mobilnym interfejsie z gradientami, kartami glassmorphism i subtelnymi animacjami. Dashboard pokazuje rozszerzony desktopowy podgląd godzin z podsumowaniem najbliższej doby, a także wykresy temperatury i opadu dla bieżącego dnia. Każdy dzień prognozy można także otworzyć w animowanym widoku szczegółowym z przebiegiem godzinowym oraz wykresami.
|
|
|
|
Interfejs jest dostępny po polsku i angielsku. Wybrany język jest zapisywany lokalnie w przeglądarce. Oryginalne treści ostrzeżeń oraz nazwy stacji pochodzą bezpośrednio z API IMGW i nie są automatycznie tłumaczone.
|
|
|
|
Wyszukiwarka na stronie głównej obsługuje miejscowości w całej Polsce. Nazwa miejscowości jest rozpoznawana przez Open-Meteo Geocoding API oparte o GeoNames. Bieżące warunki są analizowane lokalnie przez IMGW Hybrid, a najbliższa rzeczywista stacja IMGW jest pokazywana jako kontekst i fallback. Interfejs jawnie pokazuje nazwę tej stacji oraz przybliżoną odległość.
|
|
|
|
Użytkownik może opcjonalnie udostępnić położenie GPS. Pozycja jest zaokrąglana do trzech miejsc po przecinku, czyli około 100 metrów, a nazwa miejscowości jest ustalana przez Nominatim / OpenStreetMap. Po zgodzie aplikacja wybiera lokalizację, najbliższą stację IMGW i prognozę. Geolocation API wymaga bezpiecznego kontekstu HTTPS. Wyjątkiem jest `localhost`; wejście z iPhone przez lokalny adres typu `http://192.168.x.x:3000` nie uruchomi systemowego pytania Safari.
|
|
|
|
Widok ostrzeżeń priorytetyzuje komunikaty dla województwa wynikającego z miejscowości lub stacji wybranej w pogodzie. W każdej grupie ostrzeżenia meteorologiczne, np. o burzach lub silnym wietrze, są wyświetlane przed hydrologicznymi. Ostrzeżenia meteorologiczne IMGW przypisuje do regionów na podstawie kodów TERYT, a hydrologiczne na podstawie jawnych pól województwa z API. Pozostałe aktywne komunikaty są wyświetlane niżej.
|
|
|
|
## Stack
|
|
|
|
- Next.js z App Router i TypeScript
|
|
- Tailwind CSS oraz komponenty w stylu shadcn/ui
|
|
- Framer Motion
|
|
- Recharts
|
|
- Lucide React
|
|
- TanStack Query
|
|
- Zustand z trwałym stanem `localStorage`
|
|
- własny service worker, manifest i offline fallback
|
|
|
|
## Uruchomienie
|
|
|
|
Wymagany jest Node.js 20.9 lub nowszy.
|
|
|
|
```bash
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
Aplikacja będzie dostępna pod adresem `http://localhost:3000`.
|
|
|
|
Sprawdzenie jakości i build produkcyjny:
|
|
|
|
```bash
|
|
npm run lint
|
|
npm run build
|
|
npm run start
|
|
```
|
|
|
|
## Źródła danych
|
|
|
|
Bieżące pomiary i komunikaty pochodzą z rzeczywistych publicznych danych IMGW:
|
|
|
|
- bieżąca analiza IMGW Hybrid używana przez oficjalny portal: `https://meteo.imgw.pl/api/v1/forecast/fcapi`
|
|
- prognoza godzinowa IMGW ALARO używana przez oficjalny portal: `https://meteo.imgw.pl/api/v1/forecast/fcapi?m=alaro`
|
|
- dane synoptyczne: `https://danepubliczne.imgw.pl/api/data/synop`
|
|
- pojedyncza stacja synoptyczna: `https://danepubliczne.imgw.pl/api/data/synop/id/{id}`
|
|
- dane hydrologiczne: `https://danepubliczne.imgw.pl/api/data/hydro/`
|
|
- ostrzeżenia meteorologiczne: `https://danepubliczne.imgw.pl/api/data/warningsmeteo`
|
|
- ostrzeżenia hydrologiczne: `https://danepubliczne.imgw.pl/api/data/warningshydro`
|
|
- dane meteorologiczne: `https://danepubliczne.imgw.pl/api/data/meteo/`
|
|
- lista produktów: `https://danepubliczne.imgw.pl/api/data/product`
|
|
|
|
Prognoza modelowa łączy dwa źródła. IMGW ALARO dostarcza dostępne godziny prognozy, zwykle około 72 godzin od cyklu modelu. Open-Meteo Forecast API (`https://api.open-meteo.com/v1/forecast`) dostarcza prawdopodobieństwo opadu dla całego zakresu, uzupełnia dalszy horyzont do pełnych 7 dni i pozostaje fallbackiem, jeśli ALARO chwilowo nie odpowiada. Interfejs pokazuje oba źródła i ich role.
|
|
|
|
Do wyszukiwania nazw miejscowości używany jest endpoint `https://geocoding-api.open-meteo.com/v1/search`. Przed wdrożeniem komercyjnym należy sprawdzić aktualne warunki korzystania z Open-Meteo lub zastąpić usługę własnym dostawcą.
|
|
|
|
Opcjonalny reverse geocoding dla GPS korzysta z publicznego endpointu Nominatim: `https://nominatim.openstreetmap.org/reverse`. Wywołanie następuje wyłącznie po zgodzie użytkownika. Interfejs pokazuje atrybucję OpenStreetMap. Przed wdrożeniem o większym ruchu należy sprawdzić aktualną politykę użycia publicznej instancji Nominatim lub zastąpić ją własną usługą.
|
|
|
|
Przeglądarka pobiera dane przez route handlery Next.js. Proxy IMGW w `app/api/imgw/[...path]/route.ts` pozwala ujednolicić cache, błędy API i bezpiecznie obsłużyć hydro bez mixed content. Bieżącą analizę pogody obsługuje `app/api/imgw-current/route.ts`, prognozę `app/api/forecast/route.ts`, a reverse geocoding GPS `app/api/locations/reverse/route.ts`.
|
|
|
|
## Ograniczenia API
|
|
|
|
Dashboard korzysta z publicznego endpointu IMGW Hybrid używanego przez oficjalny portal `meteo.imgw.pl`. Bieżące warunki są wybierane z lokalnego rekordu aktualnej godziny dla współrzędnych miejscowości, zgodnie z zachowaniem portalu IMGW, i mogą dodatkowo pokazać rzeczywisty opad z ostatnich 10 minut. Interfejs oddzielnie opisuje lokalną analizę Hybrid oraz najbliższą stację pomiarową IMGW. Pokrycie Hybrid może być częściowe: jeśli IMGW publikuje lokalny opad MERGE bez pełnego rekordu parametrów, hero zachowuje lokalny opad, a temperaturę, wiatr, wilgotność i ciśnienie jawnie uzupełnia fallbackiem ze stacji. Jeśli usługa Hybrid nie odpowiada, hero zachowuje cały pomiar `synop` jako oznaczony fallback. Gdy fallback pochodzi ze stacji oddalonej od miejscowości o co najmniej 30 km, interfejs ostrzega o możliwej różnicy warunków lokalnych. Endpoint Hybrid jest częścią publicznego frontendu IMGW, ale nie jest opisany w stabilnej dokumentacji `danepubliczne.imgw.pl`, więc integrację należy monitorować przy zmianach portalu.
|
|
|
|
Publiczny endpoint synoptyczny IMGW udostępnia najnowszy pomiar, a nie historię odczytów. Prognoza modelowa jest wyraźnie oddzielona od pomiarów IMGW oraz bieżącej analizy Hybrid. Parametry ALARO mają pierwszeństwo w godzinach objętych tym modelem, natomiast prawdopodobieństwo opadu i dalszy horyzont pochodzą z Open-Meteo, ponieważ ALARO nie publikuje prawdopodobieństwa opadu i nie obejmuje pełnych 7 dni. `wtr.` nie generuje fikcyjnych prognoz. Widok stacji prezentuje aktualne parametry i jawnie opisany snapshot pomiarowy. Brakujące wartości są oznaczane jako `Brak danych`.
|
|
|
|
Pole `suma_opadu` z endpointu synoptycznego jest prezentowane jako akumulowana suma opadu. Nie służy do wnioskowania, że w danej chwili pada, ani do uruchamiania animacji deszczu.
|
|
|
|
Czas aktualizacji parametrów hydrologicznych może się różnić. Interfejs pokazuje czas pomiaru, aby starsze odczyty nie wyglądały na bieżące.
|
|
|
|
## Stany pogody i efekty wizualne
|
|
|
|
Prognoza godzinowa i dzienna rozpoznaje następujące stany warunków pogodowych:
|
|
|
|
| Stan | Opis w interfejsie |
|
|
| --- | --- |
|
|
| `clear` | Bezchmurnie |
|
|
| `partlyCloudy` | Częściowe zachmurzenie |
|
|
| `cloudy` | Pochmurno |
|
|
| `fog` | Mgła |
|
|
| `drizzle` | Mżawka |
|
|
| `rain` | Opady deszczu |
|
|
| `snow` | Opady śniegu |
|
|
| `thunderstorm` | Burza |
|
|
| `unknown` | Brak opisu |
|
|
|
|
Bieżąca analiza IMGW Hybrid rozpoznaje bezpośrednio opad deszczu, śnieg i burzę. Gdy żadne z tych zjawisk nie występuje, hero może pokazać pomocniczy opis: `Silny wiatr`, `Wilgotne warunki` albo `Spokojne warunki`.
|
|
|
|
Gradient hero i część animacji korzystają z uproszczonego nastroju wizualnego:
|
|
|
|
| Mood | Obecna reguła |
|
|
| --- | --- |
|
|
| `night` | godzina przed `06:00` lub od `21:00` |
|
|
| `wind` | wiatr od `8 m/s` |
|
|
| `cold` | temperatura do `3°C` |
|
|
| `cloudy` | wilgotność od `80%` |
|
|
| `warm` | temperatura od `20°C` |
|
|
| `mild` | pozostałe przypadki |
|
|
|
|
Warstwa efektów wizualnych dodaje miękkie chmury dla `cloudy`, poświatę dla `warm`, gwiazdy nocą, smugi przy silnym wietrze, krople przy lokalnym opadzie, błyski przy burzy oraz chłodną poświatę dla `cold`. Mood hero jest obecnie heurystyką opartą o porę dnia, temperaturę, wilgotność i wiatr. Nie jest jeszcze pełną klasyfikacją sterowaną kodem warunków IMGW Hybrid.
|
|
|
|
## Struktura projektu
|
|
|
|
```text
|
|
app/ routing, layout, proxy danych, offline fallback
|
|
components/forecast/ prognoza godzinowa i dzienna IMGW ALARO + Open-Meteo
|
|
components/charts/ wykresy odczytów i szczegółów prognozy
|
|
components/dashboard dashboard aplikacji
|
|
components/weather/ hero, stacje, metryki i szczegóły
|
|
components/warnings/ alerty meteo i hydro
|
|
components/hydro/ lista stacji hydrologicznych
|
|
components/ui/ bazowe komponenty interfejsu
|
|
components/states/ loading, empty i error states
|
|
hooks/ zapytania TanStack Query
|
|
lib/ API, normalizacja, helpery i stan
|
|
types/ typy danych IMGW
|
|
public/ manifest, ikony i service worker
|
|
```
|
|
|
|
## PWA i offline
|
|
|
|
Manifest znajduje się w `public/manifest.json`, a service worker w `public/sw.js`. Rejestracja service workera działa w buildzie produkcyjnym. Powłoka aplikacji ma podstawowy offline fallback. Odpowiedzi API mogą być dostępne z pamięci urządzenia przy braku sieci, ale UI nadal prezentuje czas pomiaru i status świeżości.
|
|
|
|
## Wdrożenie na Vercel
|
|
|
|
1. Umieść repozytorium w serwisie Git.
|
|
2. Importuj projekt do Vercel jako aplikację Next.js.
|
|
3. Nie dodawaj kluczy API: publiczne endpointy IMGW ich nie wymagają.
|
|
4. Wdróż standardowym poleceniem builda `npm run build`.
|
|
|
|
Proxy IMGW działa jako route handler Next.js i jest zgodne z hostingiem Vercel.
|
|
|
|
## Bezpieczeństwo zależności
|
|
|
|
Projekt używa stabilnego Next.js `16.2.6`. `npm audit --omit=dev` raportuje obecnie umiarkowane zgłoszenie `GHSA-qx2v-qp2m-jg93` dla PostCSS `8.4.31` bundlowanego bezpośrednio przez najnowszy Next.js. Główna konfiguracja projektu korzysta z poprawionego PostCSS `8.5.x`, ale wewnętrznej kopii Next.js nie należy ręcznie podmieniać. Po publikacji poprawki upstream należy zaktualizować Next.js i ponownie uruchomić audyt.
|