Skip to content
cmer81Public

About

UI for using the Open-Meteo Mapbox Layer using Maplibre GL JS

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1,335 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Modèles météo — fork Infoclimat

Fork de Open-Meteo Maps personnalisé pour Infoclimat.

Client SvelteKit qui rend des OMfiles via MapLibre GL — l'intégralité du rendu des tuiles météo s'exécute côté navigateur (pas de tile-server). Les fichiers sont récupérés directement depuis map-tiles.open-meteo.com ; les cumuls multi-heures transitent par un service Rust dédié (infoclimat-om-worker).

Aperçu

Spécificités du fork

  • Bandeau Infoclimat — logo + liens (site, forum, adhérer) intégrés en en-tête.
  • Échelle de cumul 0,1 → 500 mm — pour le cumul du run (precipitation_sum, et les precipitation_sum_Nh), calquée sur la légende ECMWF (26 paliers) ; la pluie par pas de temps garde l'échelle du package. Les valeurs de grille des précipitations s'affichent au dixième sous 10 mm, sans « 0 » en zone sèche (voir src/lib/color-scales/precipitation.ts).
  • Palette de températures « infoclimat-inspired » — échelle de couleurs adaptée aux conventions visuelles d'Infoclimat (voir src/lib/color-scales/).
  • Domaine par défaut : meteofrance_arome_france0025 (MF AROME France).
  • Sélecteur de domaine filtré — préset Infoclimat dans DOMAIN_ALLOWLIST (constants.ts) : AROME France HD/15min, AROME France, ARPEGE Europe, ECMWF IFS HRES/0.25°/AIFS, DWD ICON D2/EU. Les autres modèles restent accessibles via URL partagée.
  • Cumuls de précipitations — variables precipitation_sum_Nh (3 / 6 / 12 / 24 / 48 / 72 h) calculées par le worker sur la base des OMfiles horaires Open-Meteo.
  • Labels — affichage optionnel des valeurs numériques sur la carte (toggle en haut à droite).
  • Contours des départements — overlay GeoJSON bundlé (/static/departements.geojson) toggleable.
  • Wind overlay — surcouche de vent à 10/80/120/180 m, opacité indépendante de la couche principale.
  • Deuxième couche scalaire — superposition de deux variables (ex : température + précipitation) avec opacité réglable.
  • Diaporama / playback — animation pré-rendue avec FPS configurable (4–15 fps), capture côté canvas via preserveDrawingBuffer.
  • Cyclones IA (expérimental) — onglet « Cyclones IA » : superpositions du modèle IA WeatherNext Cyclones Mini (Google DeepMind) — cyclones, trajectoires, zones à surveiller et cônes d'incertitude 68 et 90 % (dès que le portail les publie pour le run en ligne) — activables sur n'importe quel fond, échéance alignée sur la frise principale, servies par l'API Weather AI du portail. Les champs continus (pression au niveau de la mer, probabilité d'existence cyclonique, température à 2 m) sont les variables du modèle « Weather AI (WeatherNext) » de l'onglet Données ; vent et précipitations à venir. Jamais une alerte officielle (voir ## Architecture).
  • UI 100 % française.

Dépendance forkée

Un seul paquet @openmeteo/* est consommé depuis un fork maison (voir package.json) :

  • @openmeteo/weather-map-layer → npm:@cm3r/weather-map-layer@0.3.0 (fork publié npm, source : cmer81/weather-map-layer, base upstream v0.3.0). Le fork est rebasé sur l'upstream et ne porte plus que ce qui est impossible à faire côté consommateur :

    • globalIndex — les points de la source-layer grid portent un id global stable (globalIndex = rangée_globale·nx + colonne_globale) au lieu de l'index local de la sous-grille rognée aux tuiles. Sans ça, un même nœud change d'id selon les tuiles chargées (nx du clip variable) → l'index de symboles inter-tuiles de MapLibre ne l'apparie plus (étiquettes qui se replacent au pan) et tout décodage (i, j) côté client produit des bandes horizontales sur les domaines monde. Le fork découple l'id (global, pour MapLibre) de l'index local (qui sert encore à lire la valeur). C'est ce qui permet la couche « valeurs aux points de grille » figée (voir ## Architecture) — cf. src/lib/layers.ts, buildGridDecimationFilter.
    • readRawVariable — lecture d'une variable telle que stockée, sans règle de dérivation ; le sondage a besoin des composantes wind_u/v_component_* brutes, que readVariable remplace par vitesse + direction (irrécupérables : interpoler une direction est faux à la couture 0°/360°).
    • réexports defaultResolveRequest + types BreakpointColorScale / ColorScale / RGBA, nécessaires pour surcharger resolveRequest et typer nos color scales.

    Objectif : faire merger globalIndex en amont, puis repasser sur @openmeteo/weather-map-layer officiel (le reste du patch est mince et upstreamable).

Plus de fork @openmeteo/file-reader — il existait pour mémoïser le HEAD par URL (le reader officiel le refaisait à chaque fichier). Depuis file-reader@0.0.18, l'upstream couvre le besoin avec OmHttpBackendPool + withReader, que weather-map-layer utilise en interne : on consomme donc @openmeteo/file-reader officiel. (La PR typescript-omfiles#93 a été fermée sans merge, l'upstream ayant implémenté sa propre variante.)

Faire évoluer un fork (modification non triviale de la lib)

Quand un correctif/feature ne peut pas se faire côté maps et exige de toucher la lib, on modifie le fork puis on monte la version npm — ne jamais consommer une lib forkée autrement que par une version npm publiée et épinglée (sinon CI et autres devs ne sont pas reproductibles).

  1. Dans le repo du fork (cmer81/weather-map-layer, branche main) : coder la modif (patch petit et isolé pour garder un futur rebase upstream gérable), npm run build && npx vitest run.
  2. npm version patch (→ tag git) puis npm publish (public, OTP si 2FA) et git push origin main --tags.
  3. Dans maps : npm install -D @openmeteo/weather-map-layer@npm:@cm3r/weather-map-layer@<nouvelle-version>, puis npm run check && npm run test && npm run build, commit.

Pour itérer avant de publier, on peut pointer temporairement maps sur un tarball local (npm pack dans le fork) ou github:cmer81/weather-map-layer#<sha> ; on ne publie sur npm + bump le pin qu'une fois stable.

Avant d'ajouter un patch au fork, vérifier qu'il ne peut pas se faire côté maps : les color scales upper-air AROME-France vivaient dans le fork alors que om-protocol-settings.ts les surcharge déjà par clé exacte — elles ont été retirées lors du rebase.

Démarrage

npm install
npm run dev

L'app tourne par défaut sur http://localhost:5173.

Activer les cumuls (worker local)

Les variables *_sum_Nh ne s'affichent dans le sélecteur que si le worker est joignable. Démarrer le worker dans un terminal séparé :

cd ../infoclimat-om-worker && cargo run

Puis configurer maps/.env.local :

VITE_OM_WORKER_URL=http://localhost:8080

Build

npm run build    # static export → ./build
npm run preview  # servir la build localement

Image Docker (déploiement self-hosted)

Le Dockerfile produit une image nginx qui template VITE_OM_WORKER_URL au runtime via docker-entrypoint.d/ (pas besoin de rebuilder pour changer la cible du worker). Headers COOP/COEP/CORP appliqués pour activer SharedArrayBuffer : @openmeteo/file-reader lit alors les OMfiles en mémoire partagée avec les workers (zéro copie). Sans isolation cross-origin (ex. WebView Android, où COOP/COEP sont sans effet), useSAB retombe sur des ArrayBuffer copiés vers les workers — plus lent mais fonctionnel (src/lib/shared-array-buffer.ts).

Une image est publiée automatiquement sur GHCR via .github/workflows/.

Qualité

npm run check     # typecheck (svelte-check)
npm run lint      # prettier + eslint
npm run format    # prettier --write
npm run test      # vitest
npm run coverage  # vitest --coverage (v8)

Tests dans src/lib/tests/** (logique pure : temps, URLs, stores playback…).

Architecture

Voir .claude/CLAUDE.md et les règles ciblées dans .claude/rules/ pour les détails internes :

  • protocole MapLibre om:// et résolution d'URL (src/lib/url.ts)
  • routing des cumuls vers le worker (getOMUrl() + om-protocol-settings.ts)
  • système de slots double-buffered pour les transitions de tuiles (slot-manager.ts)
  • cache persistant des blocs OMfile par générations du Cache API, éviction à coût constant (generational-block-cache.ts, remplace BrowserBlockCache)
  • pipeline playback / pré-rendu (playback-renderer.ts)
  • synchronisation URL ↔ stores Svelte 5
  • sondages verticaux client-side (Skew-T + hodographe + indices convectifs) calculés depuis les OMfiles AROME niveaux de pression au point cliqué (src/lib/sounding/)
  • couches expérimentales Weather AI (cyclones) : produits découverts depuis le catalogue de l'API du portail, run chargé hors écran puis bascule atomique, rendu MapLibre dédié hors om:// (src/lib/weather-ai/, onglet « Cyclones IA »). L'API est appelée en direct (le portail renvoie l'en-tête CORS) ; VITE_WEATHER_AI_API_URL=/api/weather-ai passe optionnellement par le proxy Vite en local ; VITE_WEATHER_AI_CONES=on|off|fixture pilote les cônes publics (on par défaut : affichés quand le champ cones du catalogue les annonce pour le run affiché ; off les retire ; ?weather_ai_cones=fixture : démonstration hors API sur le run de référence archivé)
  • compositions de cartes (fond + superpositions d'isolignes/flèches, compositions toutes faites et enregistrées ; portage des « Combined charts » d'open-meteo/maps #361) : composition.ts, overlay-stack.ts, stores/composition.ts, paramètre d'URL overlays
  • modèle IA expérimental Weather AI (WeatherNext) (weather_ai_wnc_mini, weather-ai-domain.ts) : champs continus globaux 1° (pression, probabilité d'existence cyclonique, température à 2 m, vent à 10 m et précipitations en taux moyen sur 6 h — ces deux derniers absents des anciens runs) exportés en .om par le producteur weather-ai sur un bucket dédié (VITE_WEATHER_AI_OM_BUCKET_URL / WEATHER_AI_OM_BUCKET_URL) ; absent du sélecteur sans cette variable

Le chrome s'organise autour d'un header fin pleine largeur (marque Infoclimat, onglet « Carte », bouton « Réglages » ouvrant le panneau Avancé) et, sur desktop, d'une sidebar gauche à rail d'onglets — Données (modèle, recherche et liste des variables, niveaux en puces), Compositions (superpositions), Carte (calque météo, fond de carte, interaction), Cyclones IA (couches expérimentales Weather AI) — dont le panneau se replie sur le rail ; sur mobile, un bottom-sheet reprend les mêmes quatre onglets. La timeline et la légende se décalent de la largeur de la sidebar ; les contrôles MapLibre natifs sont ancrés en bas-droite au-dessus de la timeline.

Crédits & licence

  • Upstream : open-meteo/maps — voir LICENSE.
  • Layer : open-meteo/weather-map-layer.
  • Données :
    • OMfiles météo : Open-Meteo (et indirectement Météo-France, ECMWF, DWD, NOAA…).
    • Weather AI : WeatherNext Cyclones Mini (Google DeepMind), ECMWF open data (CC BY 4.0, modifiées), OSTIA (Met Office), E.U. Copernicus Marine Service ; attribution dans la notice « i » de la carte quand la couche est affichée, mentions complètes derrière son lien « Sources et licence » (weather-ai-sources-dialog.svelte).
    • Contours administratifs FR : gregoiredavid/france-geojson (licence ODbL).

Licence Highcharts

Le meteogram utilise Highcharts, gratuit pour un usage non commercial (licence CC BY-NC 3.0) — ce qui couvre Infoclimat (association à but non lucratif, produit non monétisé). Tout déploiement commercial d'un fork de ce dépôt nécessite une licence Highcharts propre. Les icônes météo (static/weather-symbols/) proviennent de nrkno/yr-weather-symbols (MIT).

Pour les contributions liées au layer ou au protocole om:// lui-même, ouvrir un ticket sur open-meteo/weather-map-layer plutôt qu'ici.

About

UI for using the Open-Meteo Mapbox Layer using Maplibre GL JS

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages