Skip to content

Latest commit

 

History

History
122 lines (96 loc) · 5.49 KB

File metadata and controls

122 lines (96 loc) · 5.49 KB

Developer Guide: MapToPoster Setup & Architecture

Welcome to the MapToPoster developer guide! This document explains how to set up the development environment, configure the codebase, and understand the application's core architecture.

MapToPoster consists of a Python command-line map renderer, a FastAPI REST API (with an asynchronous sequential job queue), and a Next.js single-page web app.


🛠️ Prerequisites

Ensure you have the following tools installed on your local machine:

  1. Node.js (v18.0.0 or higher) and npm
  2. Python (v3.11 or higher)
  3. uv (v0.1.0 or higher) — Astrals' ultra-fast Python package installer
    • Install on macOS/Linux via Homebrew: brew install uv
    • Install via curl: curl -LsSf https://astral.sh/uv/install.sh | sh

🚀 Getting Started (Quick Setup)

We have provided a custom setup script that configures virtual environments, installs Python and Node dependencies, and creates template configuration .env files automatically.

  1. Clone & Navigate to the repository.
  2. Run the setup script:
    ./setup_dev.sh
  3. Start the developer services:
    ./start_dev.sh

start_dev.sh spins up both:

Press Ctrl+C in the terminal to gracefully shut down both services.


⚙️ Environment Variables

FastAPI Backend (web/backend/.env)

Variable Description Default
ALLOWED_ORIGINS CORS allowed origins (comma-separated) http://localhost:3000
CACHE_DIR Directory for geocoding & map features caching ../../cache

Next.js Frontend (web/frontend/.env.local)

Variable Description Default
BACKEND_URL Endpoint of the FastAPI backend server http://localhost:8000
NEXT_PUBLIC_SITE_URL Canonical URL of the frontend website http://localhost:3000

📁 Repository Structure

MapToPoster/
├── create_map_poster.py    # Core map rendering engine (matplotlib + OSMnx)
├── font_management.py      # Google Fonts loader and downloader
├── setup_dev.sh            # One-click environment setup script
├── start_dev.sh            # Concurrent developer services runner
├── DEVELOPMENT.md          # This developer guide
├── EXAMPLES.md             # API integration code samples
├── pyproject.toml          # uv/python project metadata & requirements
├── themes/                 # Curated theme JSON files
├── fonts/                  # Custom fonts directory (Roboto + caches)
├── posters/                # Outputs directory for generated map posters
└── web/
    ├── backend/
    │   ├── main.py         # FastAPI REST application & Sequential Worker Queue
    │   └── requirements.txt
    └── frontend/
        ├── package.json
        ├── next.config.ts
        └── src/
            ├── app/        # Next.js Pages & Proxying (/api/[...proxy]/route.ts)
            └── components/ # UI Elements (Header, Footer, ScrollReveal)

🏗️ Architecture & Core Components

┌────────────────────────┐
│     Next.js Web UI     │ (localhost:3000)
└────────────────────────┘
            │
            ▼ (Next.js API route proxying)
┌────────────────────────┐
│     FastAPI Server     │ (localhost:8000)
└────────────────────────┘
            │
            ▼ (Job Submission)
┌────────────────────────┐
│ Sequential Worker Queue│ (Thread-safe background worker loop)
└────────────────────────┘
            │
            ▼ (Calls)
┌────────────────────────┐
│  create_map_poster.py  │ (Generates maps with Nominatim + OSMnx)
└────────────────────────┘

1. The Rendering Engine (create_map_poster.py)

Fetches spatial features (streets, water bodies, park polygons) using the OSMnx library from OpenStreetMap APIs, scales road widths and highlights coordinates using geopandas, and draws high-resolution posters with custom typography through matplotlib.

2. FastAPI Async Queue Backend (web/backend/main.py)

Matplotlib and geocoding resources contain global variables that are not thread-safe. To handle concurrent API requests safely, the backend:

  1. Receives requests via /api/generate and assigns a UUID (job_id).
  2. Appends the job request into an in-memory sequential queue (_job_queue).
  3. A background worker loop processes jobs one-by-one to avoid state corruption.
  4. Clients poll /api/jobs/{job_id} until status is done, returning the poster image encoded in base64.

3. Next.js App Proxy (web/frontend/src/app/api/[...proxy]/route.ts)

To prevent CORS preflight requests in production, Next.js uses an catch-all proxy route. Any requests to /api/* on port 3000 are automatically forwarded to BACKEND_URL/api/* on the server-side.