A modern, interactive web application for real-time air quality monitoring across African cities, built with Svelte 5 and SvelteKit.
about data:
duckdb -c "SUMMARIZE TABLE 'static/data/african_cities_air_quality_2024_2026.parquet';"
ββββββββββββββββββ¬ββββββββββββββ¬ββββββββββββββββββββββ¬ββββ¬βββββββββββββββββββββββ¬ββββββββ¬ββββββββββββββββββ
β column_name β column_type β min β β¦ β q75 β count β null_percentage β
β varchar β varchar β varchar β β varchar β int64 β decimal(9,2) β
ββββββββββββββββββΌββββββββββββββΌββββββββββββββββββββββΌββββΌβββββββββββββββββββββββΌββββββββΌββββββββββββββββββ€
β station_id β VARCHAR β AA001 β β¦ β NULL β 16440 β 0.00 β
β datetime β TIMESTAMP β 2024-01-01 01:52:43 β β¦ β 2026-04-01 23:53:4β¦ β 16440 β 0.00 β
β city β VARCHAR β addis_ababa β β¦ β NULL β 16440 β 0.00 β
β station_name β VARCHAR β Bole Station β β¦ β NULL β 16440 β 0.00 β
β latitude β DOUBLE β -24.6589 β β¦ β 0.33754575929203545 β 16440 β 0.00 β
β longitude β DOUBLE β 25.8541 β β¦ β 36.836366123893804 β 16440 β 0.00 β
β pm2_5 β BIGINT β 5 β β¦ β 30 β 16440 β 0.00 β
β pm10 β BIGINT β 10 β β¦ β 52 β 16440 β 0.00 β
β o3 β BIGINT β 10 β β¦ β 49 β 16440 β 0.00 β
β no2 β BIGINT β 5 β β¦ β 25 β 16440 β 0.00 β
β so2 β BIGINT β 3 β β¦ β 20 β 16440 β 0.00 β
β co β BIGINT β 1 β β¦ β 2 β 16440 β 0.00 β
β pm2_5_aqi β DOUBLE β 20.8 β β¦ β 88.66394207562348 β 16440 β 0.00 β
β pm10_aqi β DOUBLE β 9.3 β β¦ β 48.072887323943654 β 16440 β 0.00 β
β o3_aqi β DOUBLE β 9.3 β β¦ β 45.39075837347373 β 16440 β 0.00 β
β no2_aqi β DOUBLE β 4.7 β β¦ β 23.46635412420165 β 16440 β 0.00 β
β so2_aqi β DOUBLE β 4.3 β β¦ β 28.6 β 16440 β 0.00 β
β co_aqi β DOUBLE β 11.4 β β¦ β 22.7 β 16440 β 0.00 β
β overall_aqi β DOUBLE β 20.8 β β¦ β 88.71476326057154 β 16440 β 0.00 β
β overall_rating β VARCHAR β good β β¦ β NULL β 16440 β 0.00 β
β pm2_5_rating β VARCHAR β good β β¦ β NULL β 16440 β 0.00 β
β pm10_rating β VARCHAR β good β β¦ β NULL β 16440 β 0.00 β
β o3_rating β VARCHAR β good β β¦ β NULL β 16440 β 0.00 β
β no2_rating β VARCHAR β good β β¦ β NULL β 16440 β 0.00 β
β so2_rating β VARCHAR β good β β¦ β NULL β 16440 β 0.00 β
β co_rating β VARCHAR β good β β¦ β NULL β 16440 β 0.00 β
ββββββββββββββββββ΄ββββββββββββββ΄ββββββββββββββββββββββ΄ββββ΄βββββββββββββββββββββββ΄ββββββββ΄ββββββββββββββββββ€
β 26 rows 12 columns (6 shown) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
AAQIS (Africa Air Quality Information System) is a comprehensive platform designed to provide real-time air quality monitoring and analysis for major African cities. The system serves multiple stakeholders including:
- π₯ General Public: Health advice and daily air quality updates
- π’ Government Officials: Policy-making insights and regulatory data
- π¬ Researchers: Historical trends and data analysis tools
- π Environmental Organizations: Monitoring and reporting capabilities
- Live air quality data from multiple monitoring stations
- AQI (Air Quality Index) calculations for all major pollutants
- Color-coded severity levels following international standards
- Interactive station selection with detailed breakdowns
- MapLibre GL powered interactive maps
- Custom station markers with real-time status indicators
- Beautiful popup overlays with comprehensive data
- Smooth pan and zoom functionality with city-specific views
- ECharts-powered calendar heatmap (GitHub contribution style)
- Historical trends with daily, weekly, and monthly aggregation
- Time series analysis with Chart.js integration
- Professional legends and tooltips
Currently monitoring air quality in:
- πͺπΉ Addis Ababa - Ethiopia's capital and largest city
- πΊπ¬ Kampala - Uganda's vibrant capital
- π°πͺ Nairobi - Kenya's bustling metropolis
- π·πΌ Kigali - Rwanda's clean and green capital
- π§πΌ Gaborone - Botswana's administrative center
- PMβ.β - Fine particulate matter (most health-critical)
- PMββ - Coarse particulate matter
- Oβ - Ground-level ozone
- NOβ - Nitrogen dioxide
- SOβ - Sulfur dioxide
- CO - Carbon monoxide
- β‘ Svelte 5 - Latest reactive framework with runes
- ποΈ SvelteKit - Full-stack framework with SSR/SPA capabilities
- π TypeScript - Type-safe development
- π¨ Tailwind CSS 4 - Modern utility-first styling
- π ECharts - Professional data visualization library
- πΊοΈ MapLibre GL - High-performance mapping engine
- ποΈ Apache Arrow - Efficient columnar data processing
- π¦ Parquet-WASM - Client-side parquet file parsing
- β‘ WebAssembly - High-performance data operations
- π Date-fns - Robust date/time manipulation
- π Bun - Fast JavaScript runtime and package manager
- β‘ Vite - Lightning-fast build tool
- π Svelte Check - TypeScript integration for Svelte
- π ESLint & Prettier - Code quality and formatting
- Bun >= 1.0.0 (recommended package manager)
- Node.js >= 18.0.0 (fallback)
# Clone the repository
git clone https://github.com/cartologic/aaqis-app.git
cd aaqis-app
# Install dependencies using Bun (recommended)
bun install
# Start development server
bun run dev
# Alternative: Using npm/yarn
npm install && npm run dev
# Production build
bun run build
# Preview production build
bun run preview
# Type checking
bun run check
# Continuous type checking
bun run check:watch
The application will be available at http://localhost:5173
src/
βββ app.html # HTML template
βββ app.css # Global styles
βββ lib/ # Shared library code
β βββ components/ # Reusable Svelte components
β β βββ AQIGauge.svelte # Circular AQI indicator
β β βββ AirQualityHeatmap.svelte # ECharts calendar heatmap
β β βββ FilterBar.svelte # Advanced filtering controls
β β βββ LineChart.svelte # Time series charts
β β βββ MapComponent.svelte # Interactive map with popups
β β βββ DataDebugger.svelte # Development debugging tool
β βββ dataUtils.ts # Data processing and aggregation
β βββ locationService.ts # Geolocation and station finding
β βββ messages.ts # Stakeholder-specific messaging
β βββ types.ts # TypeScript type definitions
βββ routes/ # SvelteKit file-based routing
β βββ +layout.svelte # App-wide layout
β βββ +page.svelte # Main dashboard page
static/
βββ data/ # Static data files
β βββ *.parquet # Air quality datasets
βββ favicon.png # App icon
The application uses a carefully curated color system based on international AQI standards:
- π’ Good (0-50):
#00e400
- Vibrant green indicating healthy air - π‘ Moderate (51-100):
#ffff00
- Yellow for acceptable conditions - π Unhealthy for Sensitive (101-150):
#ff7e00
- Orange warning - π΄ Unhealthy (151-200):
#ff0000
- Red alert level - π£ Very Unhealthy (201-300):
#8f3f97
- Purple danger zone - β« Hazardous (300+):
#7e0023
- Maroon critical level
- Primary Font: Ubuntu (Google Fonts)
- UI Font Stack: Inter, SF Pro, system fonts
- Monospace: SF Mono, Consolas, Monaco
- π₯ Data Ingestion: Parquet files containing historical and real-time measurements
- π Processing: Apache Arrow for efficient columnar operations
- π Aggregation: Daily, weekly, monthly summaries with statistical analysis
- π― Filtering: Station-specific, city-wide, and temporal filtering
- π‘ Real-time Updates: Simulated live data feed for demonstration
- Comprehensive data validation and error handling
- Missing data interpolation and flagging
- Quality assurance metrics and reporting
- Temporal consistency checks
- Simple, intuitive AQI readings with health advice
- Location-based recommendations
- Easy-to-understand visual indicators
- Mobile-responsive design
- Policy-relevant data aggregations
- Regulatory compliance monitoring
- Trend analysis for decision-making
- Export capabilities for reporting
- Historical data access and analysis
- Statistical trend identification
- Data export in multiple formats
- API access for programmatic use
# Development
VITE_API_BASE_URL=https://api.aaqis.org
VITE_MAP_STYLE=your-mapbox-style-url
# Analytics (optional)
VITE_ANALYTICS_ID=your-analytics-id
Update src/lib/types.ts
to add new cities:
export const CITY_INFO: Record<string, CityInfo> = {
your_city: {
name: 'your_city',
displayName: 'Your City',
country: 'your_country',
emoji: 'ποΈ',
center: [longitude, latitude],
zoom: 11,
stations: []
}
};
bun run build
# Deploy the `build/` directory to any static host
- Vercel:
@sveltejs/adapter-vercel
- Netlify:
@sveltejs/adapter-netlify
- Cloudflare:
@sveltejs/adapter-cloudflare
- Node.js:
@sveltejs/adapter-node
- β‘ Code Splitting: Automatic route-based code splitting
- ποΈ Asset Optimization: Vite's built-in minification and tree-shaking
- π Lazy Loading: Charts and maps load on demand
- πΎ Efficient Data Structures: Columnar data processing with Apache Arrow
- π― Smart Caching: Browser and CDN caching strategies
# Type checking
bun run check
# Linting (when configured)
bun run lint
# Testing (when configured)
bun run test
We welcome contributions to improve AAQIS! Please see our contributing guidelines:
- π΄ Fork the repository
- πΏ Create a feature branch (
git checkout -b feature/amazing-feature
) - πΎ Commit your changes (
git commit -m 'Add amazing feature'
) - π€ Push to the branch (
git push origin feature/amazing-feature
) - π Open a Pull Request
- Follow TypeScript best practices
- Use Svelte 5 runes for reactivity
- Maintain consistent code formatting
- Add proper documentation for new features
- Ensure mobile responsiveness
This project is licensed under the MIT License - see the LICENSE file for details.
- π Environmental Data Providers for crucial air quality measurements
- ποΈ African Governments for supporting environmental monitoring
- π¨βπ» Open Source Community for the amazing tools and libraries
- π¨ Design Inspiration from modern environmental dashboards
- π Website: https://aaqis.org
- π§ Email: support@cartologic.com
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
π Built with β€οΈ for a cleaner, healthier Africa
Empowering communities with actionable air quality information