This project builds a public-transport & last-mile accessibility dashboard for Bengaluru.
It aggregates BMTC bus stops, metro stations, and BBMP zones, then computes planning KPIs like access coverage, FLGI (first/last-mile gap index), bus stop density, and nearest-metro distance.
This dashboard helps city planners pinpoint where public transport access is weak, prioritize high-impact investments (new bus stops, feeder routes, sidewalks, cycle links), and track shifts in mode share over time. By making it easier to use buses and metro—and improving first/last-mile connectivity—it shifts trips away from private vehicles, cutting congestion, air pollution, and CO₂ emissions across the city.
The final deliverable is a Streamlit app that lets planners:
- Compare zones on supply and access.
- Explore gaps (where to add stops/feeder/footpaths).
- Inspect bus stop ↔ metro station distances and download the filtered data.
- Track citywide mode share KPIs (PT / NMT / Private) over time.
This Project was created as a contribution at the Bengaluru Climate Hackathon, hosted by WRI India, BBMP, OpenCity, BCAP and partners.
- KPIs & Trend
Citywide PT/NMT/Private shares by year, YoY deltas, and trend lines. (Data from your CSV.) - Supply & Access (by Zone)
Zone selector → grid heatmap of Access, FLGI, Bus stop density, Nearest metro, Stations ≤800 m, plus histogram/ECDF/rank charts and Bottom-10 table. - Stop ↔ Station Distance Explorer
Shows nearest metro station for every BMTC stop; filter by distance slider and download CSV. - Auto cache-busting & Refresh
Caches keyed to file modification time; sidebar button to clear cache. - Downloadables
Filtered stop–station pairs as CSV; zone tables exportable from the UI.
- Fetch Bengaluru boundary via OSM (Nominatim through OSMnx).
- Save:
processed/bengaluru_boundary.geojson
- Metro stations from Overpass (OSM); filter by metro keywords.
- BMTC stops from community GTFS-derived GeoJSON.
- Save:
processed/stations_overpass.geojson
processed/bmtc_stops.geojson
- For each BMTC stop, compute Haversine distance to all stations; keep the minimum.
- Save:
processed/stop_station_nearest.csv
(one row per stop)processed/station_nearby_stops.json
(station → stops within a radius)
- Build a square grid (e.g., 2 × 2 km) clipped to the city.
- Access coverage: % of each cell within 500 m of any bus stop (union of buffers).
- FLGI proxy:
1 − Access
. - Also compute bus stop count/density, nearest metro (m) from cell centroid, stations ≤800 m.
- Download BBMP zones/wards (OpenCity), normalize to
zone_id
, save:processed/zones.geojson
- Attach
zone_id
to grid cells via centroid-in-polygon.
- Create
processed/modal_share_city.csv
with columns:
year, pt_share_pct, nmt_share_pct, private_share_pct
- (Optional)
meta/targets.yaml
for PT/NMT targets shown in the header.
- App file:
notebooks/app_all_in_one.py
- Tabs: KPIs & Trend • Supply & Access (by Zone) • Distance Explorer
- Sidebar: grid size, Refresh data (clear cache).
most of the work is already done in this (if you want to start it from scratch, follow this steps)
python -m venv .venv
# macOS/Linux
source .venv/bin/activate
# Windows
# .venv\Scripts\activate
python -m pip install --upgrade pip
pip install streamlit pandas numpy altair pydeck geopandas shapely pyogrio requests fastkml osmnx networkx geopy
# Metro stations (OSM) + BMTC stops + nearest-station pairs
node scripts/build_bmtc_lastmile.js
# Optional: change “nearby stops” radius for station_nearby_stops.json
LASTMILE_RADIUS=1000 node scripts/build_bmtc_lastmile.js
python scripts/make_zones_file.py
# writes processed/zones.geojson with zone_id
year,pt_share_pct,nmt_share_pct,private_share_pct
2019,41.0,18.5,40.5
2020,41.2,18.6,40.2
...
2025,48.0,18.5,33.5
.venv/bin/streamlit run notebooks/app_all_in_one.py
- Access (coverage): share of a grid cell within 500 m of any bus stop (union of buffers).
- FLGI (proxy): 1 − Access → fraction not covered (higher = worse last-mile).
- Bus stop density: stops per km² in the cell.
- Nearest metro (m): straight-line distance from cell centroid to closest station.
- Stations ≤800 m: number of stations within 800 m of centroid.
- YoY (pp): current year % − previous year % (percentage points).
- OpenStreetMap / Overpass API — metro stations & fallback bus stops https://www.openstreetmap.org • https://overpass-api.de
- BMTC GTFS-derived GeoJSON (community) — bus stops https://github.com/Vonter/bmtc-gtfs (uses geojson/stops.geojson)
- Bengaluru boundary (Nominatim via OSMnx) https://nominatim.openstreetmap.org • https://github.com/gboeing/osmnx
- BBMP Zones/Wards (OpenCity) https://data.opencity.in/ (KML downloads; converted to GeoJSON by our script) © OpenStreetMap contributors (ODbL). Check OpenCity pages for dataset licenses.
- Advik R Holalu
- Akshath S Bhandiwad
- Joselyn Riana Manoj
- K Jaidev Shankar Reddy
- Sanjan Dileep