Map Poster Service (cbmaps)¶
Status: Active Port: 32213 URL: https://maps.nominate.ai
Overview¶
cbmaps is a FastAPI service that wraps the maptoposter CLI tool for generating minimalist city map posters. Uses OpenStreetMap data to create high-quality cartographic art.
Quick Start¶
# Install dependencies
pip install -e ".[dev]"
# Start development server
./startit.sh
# Or: python -m uvicorn src.main:app --port 32213 --reload
# Run tests
pytest
API Endpoints¶
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check |
| GET | /api/v1/posters/themes |
List available themes |
| POST | /api/v1/posters/generate |
Generate a map poster |
| GET | /api/v1/posters |
List generated posters |
| GET | /api/v1/posters/{filename} |
Download a poster |
Generate Poster¶
curl -X POST http://localhost:32213/api/v1/posters/generate \
-H "Content-Type: application/json" \
-d '{"city": "Paris", "country": "France", "theme": "noir", "distance": 10000}'
Parameters:
| Parameter | Required | Default | Description |
|---|---|---|---|
city |
Yes | - | City name |
country |
Yes | - | Country name |
theme |
No | feature_based | Theme name |
distance |
No | 29000 | Map radius in meters (4000-50000) |
Distance Guide: - 4000-6000m: Small/dense cities - 8000-12000m: Medium cities - 15000-20000m: Large metros
Architecture¶
POST /api/v1/posters/generate
↓
poster_service.generate_poster() [async]
↓
asyncio.to_thread(_generate_poster_sync)
↓
maptoposter: geocode → fetch OSM data → render → save PNG
↓
Return PosterResponse with download_url
Project Structure¶
cbmaps/
├── src/
│ ├── main.py # FastAPI app, lifespan, CORS
│ ├── config.py # Settings (pydantic-settings)
│ ├── models/schemas.py # Request/Response models
│ ├── routes/posters.py # Poster endpoints
│ └── services/poster_service.py # maptoposter wrapper
├── extern/maptoposter/ # Original CLI tool
└── posters/ # Generated output
Configuration¶
Environment variables (.env):
| Variable | Default | Description |
|---|---|---|
API_HOST |
0.0.0.0 | Server host |
API_PORT |
32213 | Server port |
MAX_DISTANCE |
50000 | Max allowed distance |
MIN_DISTANCE |
4000 | Min allowed distance |
GENERATION_TIMEOUT |
300 | Timeout in seconds |
Performance Notes¶
- Generation takes 10-60 seconds depending on distance and city complexity
- Large distances (>20km) are slow and memory-heavy
- OSM API has rate limiting built into maptoposter (1-3s delays)
- Runs synchronous work in thread pool to avoid blocking event loop
Dependencies¶
- FastAPI, uvicorn, pydantic-settings for API
- osmnx, geopandas, matplotlib, geopy for map generation
- Uses maptoposter code from
extern/maptoposter/