Web application that evaluates how reachable schools are by walking, biking, or driving within any city. It overlays isochrone analysis on population data to quantify coverage gaps.
Built on UrbanAccessAnalyzer, OpenStreetMap, and WorldPop.
- Python 3.12+
- Node.js 18+
- uv (Python package manager) — install from docs.astral.sh/uv
- osmium-tool — required for street network downloads
# Debian/Ubuntu
sudo apt-get install -y osmium-tool
# macOS
brew install osmium-tool
# Conda
conda install -c conda-forge osmium-tooluv venv
uv pip install fastapi "uvicorn[standard]"
uv pip install "UrbanAccessAnalyzer[osm,plot,h3] @ git+https://github.com/CityScope/UrbanAccessAnalyzer.git@v1.0.0"cd frontend
npm install
cd ..Start both servers (each in its own terminal):
Backend (from the project root):
.venv/bin/uvicorn backend.main:app --reload --port 8000Frontend (from frontend/):
cd frontend
npm run devThen open http://localhost:5173 in your browser.
The Vite dev server proxies all /api requests to the backend on port 8000.
- On the landing page, type a city name in the search bar (e.g. "Needham, MA, USA").
- Select a suggestion — the city boundary appears on the map.
- Adjust the distance thresholds for Walk, Bike, and Bus/Car using the sliders.
- Click Run Analysis — the backend fetches schools, builds the street graph, computes isochrones, downloads population data, and returns the results.
- The map displays color-coded H3 hexagons (green = walk, blue = bike, amber = bus/car) with school markers. The sidebar shows population coverage statistics.
├── backend/
│ ├── main.py # FastAPI app with API endpoints
│ └── analysis.py # Analysis pipeline (extracted from notebook)
├── frontend/
│ ├── src/
│ │ ├── App.tsx
│ │ ├── api.ts # API client functions
│ │ ├── types.ts # TypeScript interfaces
│ │ └── components/
│ │ ├── LandingPage.tsx # Video + city search
│ │ ├── AnalysisPage.tsx # Map + controls + results
│ │ ├── CityMap.tsx # Leaflet map component
│ │ ├── DistanceControls.tsx # Walk/bike/car sliders
│ │ └── StatsPanel.tsx # Population stats display
│ └── ...
├── rural_schools.ipynb # Original notebook
└── output/ # Generated analysis results (per city)
| Method | Path | Description |
|---|---|---|
| GET | /api/suggestions?q= |
City name autocomplete via Nominatim |
| POST | /api/city-geometry |
Returns city boundary as GeoJSON |
| POST | /api/analyze |
Starts analysis job, returns job_id |
| GET | /api/job/{job_id} |
Poll job status and retrieve results |