The problem
The Parking Reform Network is a transportation advocacy nonprofit that works to change public policy around parking mandates in cities. Their reform case rests on a simple visual: how much of a downtown is given over to parking. Hand-mapping that for every city is slow, manual, and the kind of work that doesn't scale to the size of the policy fight.
What I built
A full-stack app that takes a city name, resolves its downtown boundary from public GIS data, fetches satellite imagery for the area, and runs a custom-trained computer vision model to detect parking lots. Humans then refine the output and publish the result back to OpenStreetMap and the PRN website.
- Boundary resolution. Downtown polygons come from municipal GIS data where available, falling back to OSM or hand-drawn outlines.
- Tile fetching. Google Maps tiles for the bounded area, batched to avoid rate limits.
- Detection. A custom-trained CV model identifies parking lots tile by tile. Results are stitched back into the source coordinate system.
- Human-in-the-loop refinement. A React UI lets reviewers approve, reject, edit polygon boundaries, and add metadata. Realtime updates push to the UI via RabbitMQ streams.
- Publication. Approved detections feed back to OpenStreetMap and PRN's database.
Architecture
Python backend with PostGIS for spatial data, React frontend, RabbitMQ for both work queueing (backend nodes hand work to worker nodes) and realtime streaming (workers push status to the UI). CI/CD auto-deploys to a DigitalOcean droplet. Built with Claude Code as a pair-programming partner — a useful experiment in how much velocity an AI-assisted workflow buys for a solo project.
What I'm thinking about
The interesting design question wasn't model accuracy. The CV model is good but never perfect — the question is what to do with the messy 20% that comes out wrong. Building the refinement UI taught me more about progressive disclosure, undo affordances, and trust-building in AI-augmented workflows than any of the model training did.