-
Notifications
You must be signed in to change notification settings - Fork 0
Weather Integration
FlightMeet uses Open-Meteo (no API key required) for geocoding and forecasts. Wind data is first-class because the audience is paraglider pilots.
app/Libraries/OpenMeteo.php is a thin wrapper shared by the Weather controller and the meets weather endpoint:
-
geocode(string $name)calls the geocoding API (v1/search, first match, English) and returns{ name, country, latitude, longitude }ornullwhen the place is unresolvable or the service fails. Failures are logged, never thrown. -
forecast(float $lat, float $lon)fetches current conditions plus the daily forecast, returningnullon failure.
Forecast variables include, for the current conditions: wind_speed_10m, wind_gusts_10m, wind_direction_10m; daily: wind_speed_10m_max, wind_gusts_10m_max, wind_direction_10m_dominant, alongside temperature and weather codes (rendered via a WMO code map on the frontend).
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /api/weather?city=... |
public | current + 7-day forecast for a searched city |
| GET | /api/weather/reports |
public | every cached forecast report |
| POST | /api/weather/reports/{id}/refresh |
public | re-fetch a cached report from Open-Meteo |
| GET | /api/meets/{id}/weather |
public | forecast for a meet's stored coordinates |
GET /api/weather?city=... → 200 { "status": "ok", "location": { name, country, latitude, longitude }, "forecast": {...} }. Unknown city → 404; weather service down → 502 (both as { "status": "error", "message": "..." }).
When a city search resolves and the forecast succeeds, a weather_reports row is upserted, keyed by (latitude, longitude):
-
Staleness: a report is flagged
staleafter 6 hours; the UI offers a refresh. - Purging: rows older than 4 days are deleted whenever the table is touched.
-
Refresh:
POST /api/weather/reports/{id}/refreshre-fetches from Open-Meteo, updatespayloadandfetched_at, and returns200 { "report": WeatherReport }(404unknown id,502service down).
These cached reports double as pilot-submitted weather reports: every successful city search leaves a pin, and the Weather page renders them on a Leaflet map with marker clustering.
-
Create: when a meet is created without coordinates, the backend geocodes the
spot, falling back to theregion. An unresolvable spot leaveslatitude/longitudenull; this is deliberate and never blocks meet creation. - Edit: explicit coordinates win; empty coordinates keep the stored values when spot and region are unchanged, otherwise the spot is re-geocoded.
-
Per-meet forecast:
GET /api/meets/{id}/weatheruses the stored coordinates; when they are null it returns409 { "error": "This meet has no coordinates." }, and the frontend'sMeetWeatherPanelshows a friendly "no forecast" note instead of an error. - On the create/edit form, users can also pick the spot directly on an interactive map (
LocationPickerMap), which supplies explicit coordinates and skips geocoding.
-
pages/WeatherPage.tsx: city search, current conditions, forecast, and the clustered report map. -
pages/weather/:ForecastStrip(7-day strip),ReportDetail,WindArrow(direction visualization),wmo.ts(WMO weather-code → label/icon map),wind.tsandformat.tshelpers. -
pages/meets/MeetWeatherPanel.tsx: the per-meet forecast panel on the detail page. -
components/map/:BaseMap,MarkerClusterLayer, andmarkers.tsshared between weather and meet location picking.
FlightMeet
Code
Reference