# originalankur/maptoposter architecture

> Architecture diagram of the GitHub repository originalankur/maptoposter, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-13). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/originalankur/maptoposter
- Repository: https://github.com/originalankur/maptoposter

## Overview

1. **What this repo is**
   - A single-purpose Python command-line tool that generates static city map posters as PNGs.
   - The repository is centered around one main executable script, not a server or library API.

2. **Primary execution path**
   - The user invokes `create_map_poster.py` with city/country and optional styling parameters.
   - The script resolves the city to coordinates, fetches map data, renders a poster, and writes the image into `posters/`.

3. **Input boundary: CLI + configuration**
   - The CLI accepts geography inputs, optional coordinate overrides, poster size, map radius, theme selection, and multilingual display names.
   - These inputs determine both the map extent and the final typography/styling, so they are the main control surface of the system.

4. **Geocoding subsystem**
   - City and country names are converted to latitude/longitude using Nominatim.
   - This is the first external dependency in the pipeline and establishes the map center unless manually overridden.

5. **Map data acquisition subsystem**
   - The project uses OSMnx to pull OpenStreetMap graph and feature data around the chosen point.
   - The fetched data includes roads and other geographic layers such as water and parks, which become separate visual layers in the final poster.

6. **Rendering subsystem**
   - Matplotlib is the rendering engine and is responsible for composing the poster image.
   - The visual stack is layered: background, water, parks, roads, gradient fades, then text and attribution on top.
   - Road styling is derived from OpenStreetMap highway classes, with width and color mapped by road importance.

7. **Theme system**
   - Theme files in `themes/*.json` define color palettes and visual behavior.
   - Themes control the poster’s look-and-feel without changing rendering code, making them a clean configuration boundary.
   - The `--all-themes` and `--list-themes` options indicate themes are treated as first-class runtime inputs.

8. **Font and multilingual support**
   - `font_management.py` handles font loading and Google Fonts integration.
   - Default fonts live in `fonts/`, while downloaded Google Fonts are cached locally in `fonts/cache/`.
   - Script detection changes typography behavior: Latin scripts get spaced letter treatment, while non-Latin scripts retain natural spacing.

9. **Output boundary**
   - Rendered posters are saved as timestamped PNG files in `posters/`.
   - The output is a generated artifact, not a persistent application state; the repo also includes example poster images for documentation and regression reference.

10. **Project layout and responsibilities**
   - `create_map_poster.py`: end-to-end orchestration of CLI, geocoding, fetching, styling, rendering, and file output.
   - `font_management.py`: font discovery, caching, and Google Fonts handling.
   - `themes/`: visual configuration data.
   - `fonts/`: bundled font assets and cache.
   - `posters/`: generated results and sample outputs.

11. **Tooling and delivery**
   - The repo supports both `uv` and `pip + venv` workflows, with locked dependency management via `uv.lock`.
   - `pyproject.toml`, `requirements.txt`, and `.flake8` suggest linting and reproducible Python packaging are important, but the project remains a script-first tool.
   - GitHub Actions workflows are present for PR checks and conflict automation, indicating basic CI around code quality rather than runtime infrastructure.

12. **Testing and contributor workflow**
   - `test/all_variations.sh` implies manual or scripted generation checks across themes/variations.
   - The README frames validation around visually inspecting before/after poster outputs, which makes output rendering quality a key correctness criterion.

Main entry points: [`create_map_poster.py`](https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py) (Map Poster CLI), [`themes/autumn.json`](https://github.com/originalankur/maptoposter/blob/main/themes/autumn.json) (Theme Config), [`font_management.py`](https://github.com/originalankur/maptoposter/blob/main/font_management.py) (Font Manager), [`pyproject.toml`](https://github.com/originalankur/maptoposter/blob/main/pyproject.toml) (Python Setup)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Runtime Pipeline"]
  node_cli["Map Poster CLI<br/>script orchestration"]
  node_geo(("Geocoding<br/>nominatim lookup"))
  node_mapdata[("Map Fetching<br/>osmnx data pull")]
  node_render["Poster Rendering<br/>matplotlib composition"]
  node_roadstyle{{"Road Styling<br/>highway classification"}}
  node_layers["Map Layers<br/>visual layers"]
  node_text["Typography<br/>script-aware text"]
  node_fonts["Font Manager<br/>font loading<br/>[font_management.py]"]
end

subgraph group_assets["Assets & Config"]
  node_theme["Theme Config<br/>json themes<br/>[autumn.json]"]
  node_fontdir[("Fonts<br/>bundled assets")]
  node_posterout["Poster Output<br/>generated PNGs"]
  node_themesdir["Themes<br/>theme set"]
end

subgraph group_tooling["Tooling & Delivery"]
  node_checks["CI Checks<br/>github actions<br/>[pr-checks.yml]"]
  node_conflicts["Conflict Bot<br/>workflow automation<br/>[conflicts.yml]"]
  node_deps["Python Setup<br/>packaging<br/>[pyproject.toml]"]
  node_lock["Lockfile<br/>dependency lock<br/>[uv.lock]"]
  node_reqs["Requirements<br/>pip deps<br/>[requirements.txt]"]
  node_tests["Variations Test<br/>generation script<br/>[all_variations.sh]"]
  node_docs["Project Docs<br/>readme/changelog<br/>[README.md]"]
end

node_cli -->|"resolve location"| node_geo
node_cli -->|"select theme"| node_theme
node_cli -->|"load fonts"| node_fonts
node_geo -->|"center map"| node_mapdata
node_mapdata -->|"road graph"| node_roadstyle
node_mapdata -->|"feature layers"| node_layers
node_roadstyle -->|"style roads"| node_render
node_layers -->|"compose scene"| node_render
node_theme -->|"colors and behavior"| node_render
node_fonts -->|"provide typefaces"| node_text
node_text -->|"overlay text"| node_render
node_render -->|"write PNG"| node_posterout
node_fontdir -->|"bundled fonts"| node_fonts
node_themesdir -->|"theme files"| node_theme
node_deps -->|"pin deps"| node_lock
node_deps -->|"alternate install"| node_reqs
node_checks -->|"validate code"| node_cli
node_tests -->|"exercise outputs"| node_cli
node_docs -.->|"describe usage"| node_cli
node_docs -.->|"list presets"| node_theme

click node_cli "https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py"
click node_geo "https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py"
click node_mapdata "https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py"
click node_render "https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py"
click node_roadstyle "https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py"
click node_layers "https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py"
click node_text "https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py"
click node_fonts "https://github.com/originalankur/maptoposter/blob/main/font_management.py"
click node_theme "https://github.com/originalankur/maptoposter/blob/main/themes/autumn.json"
click node_fontdir "https://github.com/originalankur/maptoposter/tree/main/fonts"
click node_posterout "https://github.com/originalankur/maptoposter/tree/main/posters"
click node_themesdir "https://github.com/originalankur/maptoposter/tree/main/themes"
click node_checks "https://github.com/originalankur/maptoposter/blob/main/.github/workflows/pr-checks.yml"
click node_conflicts "https://github.com/originalankur/maptoposter/blob/main/.github/workflows/conflicts.yml"
click node_deps "https://github.com/originalankur/maptoposter/blob/main/pyproject.toml"
click node_lock "https://github.com/originalankur/maptoposter/blob/main/uv.lock"
click node_reqs "https://github.com/originalankur/maptoposter/blob/main/requirements.txt"
click node_tests "https://github.com/originalankur/maptoposter/blob/main/test/all_variations.sh"
click node_docs "https://github.com/originalankur/maptoposter/blob/main/README.md"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_geo,node_mapdata,node_render,node_roadstyle,node_layers,node_text,node_fonts toneBlue
class node_theme,node_fontdir,node_posterout,node_themesdir toneAmber
class node_checks,node_conflicts,node_deps,node_lock,node_reqs,node_tests,node_docs toneMint
```

## Components

### Runtime Pipeline

Main poster generation flow from inputs to PNG output.

- [Map Poster CLI](https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py): script orchestration · End-to-end command-line entry point that coordinates the full poster build. · `create_map_poster.py`
- [Geocoding](https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py): nominatim lookup · Resolves city and country names into coordinates used as the map center. · `create_map_poster.py`
- [Map Fetching](https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py): osmnx data pull · Pulls OpenStreetMap graph and feature layers around the chosen location. · `create_map_poster.py`
- [Poster Rendering](https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py): matplotlib composition · Composes the layered poster image, including roads, land features, fades, text, and attribution. · `create_map_poster.py`
- [Road Styling](https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py): highway classification · Maps OpenStreetMap highway classes to line width and color for visual hierarchy. · `create_map_poster.py`
- [Map Layers](https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py): visual layers · Background, water, parks, roads, and gradient overlays that build the final scene. · `create_map_poster.py`
- [Typography](https://github.com/originalankur/maptoposter/blob/main/create_map_poster.py): script-aware text · Handles titles, multilingual names, spacing behavior, and placement of labels. · `create_map_poster.py`
- [Font Manager](https://github.com/originalankur/maptoposter/blob/main/font_management.py): font loading · Discovers bundled fonts, loads Google Fonts, and manages local font cache. · `font_management.py`

### Assets & Config

Bundled visual resources that shape poster appearance.

- [Theme Config](https://github.com/originalankur/maptoposter/blob/main/themes/autumn.json): json themes · Defines palettes and visual behavior that control poster styling without code changes. · `themes/autumn.json`
- [Fonts](https://github.com/originalankur/maptoposter/tree/main/fonts): bundled assets · Repository font files used as defaults and cache targets for downloaded fonts. · `fonts`
- [Poster Output](https://github.com/originalankur/maptoposter/tree/main/posters): generated PNGs · Timestamped poster images written to disk, plus sample outputs in the repo. · `posters`
- [Themes](https://github.com/originalankur/maptoposter/tree/main/themes): theme set · Collection of poster style presets such as contrast, monochrome, and neon variants. · `themes`

### Tooling & Delivery

Dependency management, CI, and validation workflows.

- [CI Checks](https://github.com/originalankur/maptoposter/blob/main/.github/workflows/pr-checks.yml): github actions · Pull request validation and repository automation workflows. · `.github/workflows/pr-checks.yml`
- [Conflict Bot](https://github.com/originalankur/maptoposter/blob/main/.github/workflows/conflicts.yml): workflow automation · GitHub workflow for conflict management and related maintenance automation. · `.github/workflows/conflicts.yml`
- [Python Setup](https://github.com/originalankur/maptoposter/blob/main/pyproject.toml): packaging · Dependency and environment definitions for uv, pip, and linting workflows. · `pyproject.toml`
- [Lockfile](https://github.com/originalankur/maptoposter/blob/main/uv.lock): dependency lock · Pinned dependency resolution for reproducible installs with uv. · `uv.lock`
- [Requirements](https://github.com/originalankur/maptoposter/blob/main/requirements.txt): pip deps · Alternate dependency manifest for pip-based environments. · `requirements.txt`
- [Variations Test](https://github.com/originalankur/maptoposter/blob/main/test/all_variations.sh): generation script · Scripted poster generation checks across theme and styling variations. · `test/all_variations.sh`
- [Project Docs](https://github.com/originalankur/maptoposter/blob/main/README.md): readme/changelog · Human-facing description of usage, workflow, and release history. · `README.md`

## Connections

- Map Poster CLI → Geocoding: resolve location · CLI inputs are converted into map-center coordinates.
- Map Poster CLI → Theme Config: select theme · Runtime theme selection changes the poster palette and styling.
- Map Poster CLI → Font Manager: load fonts · The script requests fonts for title and label rendering.
- Geocoding → Map Fetching: center map · Resolved coordinates determine where map data is fetched.
- Map Fetching → Road Styling: road graph · Road network data is classified into visual importance levels.
- Map Fetching → Map Layers: feature layers · Water, parks, and other geographic features become poster layers.
- Road Styling → Poster Rendering: style roads · Road widths and colors feed the rendering stack.
- Map Layers → Poster Rendering: compose scene · The rendering engine draws the layered map composition.
- Theme Config → Poster Rendering: colors and behavior · Theme values drive palette choices and visual effects.
- Font Manager → Typography: provide typefaces · Loaded fonts are used to render titles and multilingual names.
- Typography → Poster Rendering: overlay text · Typography is placed on top of the rendered map layers.
- Poster Rendering → Poster Output: write PNG · The final poster is saved as a generated image artifact.
- Fonts → Font Manager: bundled fonts · Local font assets are discovered and loaded by the font manager.
- Themes → Theme Config: theme files · JSON presets define poster appearance options.
- Python Setup → Lockfile: pin deps · Project packaging and dependency resolution are kept reproducible.
- Python Setup → Requirements: alternate install · Pip-based installation is supported alongside uv.
- CI Checks → Map Poster CLI: validate code · CI runs repository checks against the main poster script.
- Variations Test → Map Poster CLI: exercise outputs · The variation script generates posters to inspect visual correctness.
- Project Docs → Map Poster CLI: describe usage · Documentation explains invocation, options, and workflow.
- Project Docs → Theme Config: list presets · README and changelog help surface available themes and behavior.
