A web application for detecting and editing parking lot polygons from satellite imagery using AI.
- AI-Powered Detection: Uses a SegFormer model (UTEL-UIUC/SegFormer-large-parking) to detect parking lots from Google Maps satellite imagery
- Worker Queue: Inference jobs run in a dedicated RabbitMQ-backed worker container, keeping the API responsive
- Live Progress: SSE-based progress streaming so the browser shows real-time inference status
- Interactive Map Editor: Edit, add, delete, and split parking lot polygons on a Leaflet map
- City Boundary Search: Look up official downtown/city boundaries by name (via ArcGIS Hub) to use as project bounds
- Multi-User Support: Role-based access control (Admin, Reviewer)
- Project Management: Create projects for different areas, track status through a review workflow
- Backend: FastAPI (Python 3.11+)
- Worker: Same backend image, runs RabbitMQ consumer for inference jobs
- Frontend: React + TypeScript, served via nginx
- Database: PostgreSQL 15 + PostGIS
- Message Queue: RabbitMQ 3.13
- Maps: Google Maps satellite tiles (proxied + cached by backend)
- Auth: JWT-based authentication
- Docker and Docker Compose
- A Google Maps API key (set in
.env)
-
Clone the repository and set up your environment:
cp .env.example .env # Edit .env and set GOOGLE_MAPS_API_KEY and SECRET_KEY -
Start all services:
docker compose up -d
-
Create an admin user:
docker compose exec backend python scripts/create_admin.py admin@example.com yourpassword -
Access the application:
- Frontend: http://localhost:5173
- Backend API: http://localhost:8000
- API Docs: http://localhost:8000/docs
- RabbitMQ Management: http://localhost:15672 (user:
parking/parking)
Backend (.env):
DATABASE_URL=postgresql://postgres:postgres@db:5432/parking_lots
SECRET_KEY=your-secret-key
GOOGLE_MAPS_API_KEY=your-google-maps-key
CORS_ORIGINS=["http://localhost:5173"]
RABBITMQ_URL=amqp://parking:parking@rabbitmq:5672/
- Create a Project: Click "New Project" on the dashboard, then either draw a boundary on the map or search for a city/downtown boundary by name
- Run Detection: Click "Run Detection" — the job is queued and progress streams to the UI in real time
- Edit Results: Use the map tools to edit, add, delete, or split polygons
- Submit for Review: When editing is complete, submit for admin review
- Approve: Admins can approve the final results
- Draw: Add new polygons
- Edit: Modify existing polygon vertices
- Delete: Remove polygons
- Split: Click on a polygon, then draw a line to split it
- Admin: Full access — can approve projects and manage users
- Reviewer: Can create projects, run detection, and edit polygons
parking-lot-app/
├── backend/
│ ├── app/
│ │ ├── api/ # FastAPI routes (auth, projects, polygons, inference, cities, maps)
│ │ ├── core/ # Security & permissions
│ │ ├── models/ # SQLAlchemy models
│ │ ├── schemas/ # Pydantic schemas
│ │ ├── services/ # Business logic (inference, city_resolver, queue, sse, tiles, osm)
│ │ └── worker_main.py # RabbitMQ inference worker entry point
│ ├── alembic/ # Database migrations (001–004)
│ └── scripts/ # Utility scripts
├── frontend/
│ └── src/
│ ├── components/ # React components
│ ├── pages/ # Page components
│ ├── services/ # API client
│ └── store/ # State management (zustand)
├── model/ # Custom model checkpoint (volume-mounted, not committed)
└── docker-compose.yml
The app uses UTEL-UIUC/SegFormer-large-parking from HuggingFace, downloaded automatically on first run and cached in a Docker volume.
To use a custom-trained checkpoint:
- Place your model file in the
model/directory - Set
MODEL_PATHin your environment configuration
If you use this tool or its outputs in research, please cite the model it is built on:
@inproceedings{qiam2025pipeline,
title={A Pipeline and NIR-Enhanced Dataset for Parking Lot Segmentation},
author={Qiam, Shirin and Devunuri, Saipraneeth and Lehe, Lewis J},
booktitle={2025 IEEE/CVF Winter Conference on Applications of Computer Vision (WACV)},
pages={1227--1236},
year={2025},
organization={IEEE}
}- Frontend changes require a rebuild:
docker compose build frontend && docker compose up -d frontend - Backend changes must be copied in (source is not volume-mounted):
docker compose cp <file> backend:/app/<path> - Migrations must also be copied before running:
docker compose cp backend/alembic/versions/XXX.py backend:/app/alembic/versions/ - The worker container shares the backend image — restart it after backend changes:
docker compose restart worker
Once the backend is running, visit:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
MIT