Inspiration
Current air quality applications show city-wide averages, offering the exact same generic advice to a healthy adult and a child with severe asthma. We built AirWatch—a personalized, zero-cost, and decentralized air intelligence platform to help citizens schedule safe outdoor commutes using clinical health factors and meteorological forecasting.
How it works
- Clinical Risk Scaling: The app adjusts the raw AQI score into a personalized \( AQI_{effective} \) based on user age and health conditions.
- Smart Scheduling: A daily planner evaluates the 24-hour forecast and marks 5 daily activities (Morning Walk, School Commute, Errands, Exercise, Evening Walk) as Go, Caution, or Avoid based on the user's safety limits.
- Map-Click Geocoding: Users can tap anywhere on the map to instantly reverse-geocode coordinates, fetch real-time air data, and update the entire dashboard dynamically.
How We Built It
We developed AirWatch as a 100% client-side React 19 & Vite Single Page Application:
- Leaflet.js & CARTO Maps: Interactive maps that dynamically toggle between Dark Matter and Positron tile layers based on the active theme.
- Chart.js: Visualizes 24-hour pollutant curves.
- Open-Meteo & OpenStreetMap APIs: Direct CORS-friendly browser fetches for zero server cost and maximum user data privacy.
Mathematical Models & Formulations
1. Clinical Risk Index Scaling
We scale the raw index using clinical multipliers:
$$AQI_{effective} = AQI_{raw} \times M_{age} \times M_{condition}$$
- Age Multiplier (\( M_{age} \)): Child (\( 1.8 \)), Senior (\( 1.7 \)), Adult (\( 1.0 \)).
- Condition Multiplier (\( M_{condition} \)): Asthma (\( 2.5 \)), Lung Disease (\( 2.8 \)), Heart Condition (\( 2.2 \)), Pregnancy (\( 2.0 \)), None (\( 1.0 \)).
2. Atmospheric Stagnation Heuristics
We forecast short-term pollution accumulation based on weather factors:
$$\text{Trend Score } (T) = S_{wind} + S_{humidity} + S_{temp}$$
- Wind Speed (\( S_{wind} \)): Stagnant air traps smog (\( +2 \)), strong wind disperses it (\( -2 \)).
- Humidity (\( S_{humidity} \)): Damp air holds PM2.5 in suspension (\( +2 \)), dry air reduces it (\( 0 \)).
- Temperature (\( S_{temp} \)): Cold triggers thermal inversion (\( +2 \)), keeping pollutants close to the ground.
Challenges We Faced
- CORS Blocks: Nominatim geocoding blocked browser requests. We bypassed this by switching to the Open-Meteo Geocoding API.
- Leaflet DOM Re-renders: React crashed when re-mounting map containers. We resolved this by cleaning up old instances using
map.remove()inside React's lifecycle hook. - Stale Map Closures: Leaflet click listeners captured stale React states. We solved this by implementing a
useRefreference wrapper for callbacks.
What We Learned
- Serverless Computations: How to run heavy algorithms (clinical adjustments and meteorological trends) completely client-side in the browser, protecting user privacy.
- Dynamic Map Searches: Mastered binding map clicks directly to coordinates and reverse-geocoding, letting users query any spot on the globe by simply clicking.
Built With
- avascript
- chart.js
- css3
- geolocation-api
- html5
- leaflet.js
- localstorage
- open-meteo-api
- openstreetmap-api
- react
- vercel
- vite
- web-speech-api
Log in or sign up for Devpost to join the conversation.