Documentation Index
Fetch the complete documentation index at: https://mintlify.com/originalankur/maptoposter/llms.txt
Use this file to discover all available pages before exploring further.
System Architecture
MapToPoster is a Python-based command-line tool that generates minimalist map posters by fetching OpenStreetMap data and rendering it with matplotlib. The architecture follows a modular pipeline design.High-Level Data Flow
CLI Argument Parsing
The entry point (
create_map_poster.py:860-1051) uses argparse to collect user inputs:- Required: City and country names
- Optional: Theme, distance, dimensions, coordinates override, custom fonts
- Validation: Maximum dimensions (20 inches), theme availability checks
Coordinate Resolution
The
get_coordinates() function (create_map_poster.py:319-370) converts city/country to lat/lon:- Uses Nominatim geocoding service via geopy
- Implements rate limiting (1 second delay) to respect API policies
- Caches results locally to avoid redundant requests
- Falls back to manual coordinate override via
--latitude/--longitudeflags
OSM Data Fetching
Three parallel data fetch operations using OSMnx:Street Network (
fetch_graph() at line 409-441):- Fetches all road types within specified radius
- Uses
network_type='all'to include all drivable roads - Applies distance compensation for viewport cropping
- Cached via pickle for performance
fetch_features() at line 444-479):- Tags:
{"natural": ["water", "bay", "strait"], "waterway": "riverbank"} - Returns GeoDataFrame of water polygons
- Rate-limited with 0.3s delay between requests
- Tags:
{"leisure": "park", "landuse": "grass"} - Returns GeoDataFrame of park polygons
Map Rendering
The
create_poster() function (create_map_poster.py:482-772) orchestrates the rendering:- Creates matplotlib figure with theme background color
- Projects all geographic data to metric CRS for accurate scaling
- Renders layers in correct z-order
- Applies gradient fades and typography
- Exports to PNG (300 DPI), SVG, or PDF
Rendering Pipeline
Layer Composition
MapToPoster renders map elements in a specific z-order (bottom to top) to ensure proper visual hierarchy:Layer 0-1: Background & Water Features
Layer 0-1: Background & Water Features
Background (
create_map_poster.py:564-566):- Solid color fill using
THEME['bg'] - Applied to both figure and axes for seamless borders
create_map_poster.py:574-582):- Filters to only
PolygonandMultiPolygongeometries (excludes point features) - Projects to graph CRS for proper alignment
- Rendered with
THEME['water']color atzorder=0.5 - No edge color for clean appearance
Layer 2: Parks & Green Spaces
Layer 2: Parks & Green Spaces
Parks Rendering (
create_map_poster.py:584-593):- Same polygon filtering as water features
- Projected to match graph coordinate system
- Uses
THEME['parks']color atzorder=0.8 - Sits above water but below roads
Layer 3: Road Network
Layer 3: Road Network
Road Hierarchy (
create_map_poster.py:595-612):- Roads styled by OSM
highwaytag usingget_edge_colors_by_type()andget_edge_widths_by_type() - Rendered at
zorder=2(matplotlib default forox.plot_graph) - Aspect ratio maintained via
get_crop_limits()to prevent distortion - Node size set to 0 for clean minimalist aesthetic
Layer 10-11: Overlays & Typography
Layer 10-11: Overlays & Typography
Gradient Fades (
create_gradient_fade() at line 214-252):- Top and bottom 25% of canvas get alpha-gradient overlay
- Creates depth and focuses attention on center
- Uses
THEME['gradient_color'](usually matches background) - Implemented via
ax.imshow()with custom colormap
create_map_poster.py:683-753):- All text uses
transform=ax.transAxes(0-1 normalized coordinates) - Font sizes scale dynamically based on poster dimensions
- Latin script detection applies letter spacing for aesthetics
- Coordinate formatting adjusts for hemisphere (N/S, E/W)
Core Functions Reference
Geocoding & Data Fetching
All fetching functions implement automatic caching using pickle serialization. Cache files are stored in
cache/ directory with sanitized filenames based on parameters.Road Styling & Hierarchy
| OSM Highway Tag | Theme Color | Line Width | Road Type |
|---|---|---|---|
motorway, motorway_link | road_motorway | 1.2 | Highways/freeways |
trunk, primary, *_link | road_primary | 1.0 | Major arterials |
secondary, secondary_link | road_secondary | 0.8 | Secondary roads |
tertiary, tertiary_link | road_tertiary | 0.6 | Tertiary roads |
residential, living_street | road_residential | 0.4 | Local streets |
| Other types | road_default | 0.4 | Fallback styling |
Rendering & Visual Effects
Typography & Internationalization
create_map_poster.py:114
- Latin scripts (English, French, Spanish, etc.): Text is uppercased and letter-spaced (“P A R I S”)
- Non-Latin scripts (Japanese, Arabic, Thai, Korean, Chinese): Natural spacing preserved (“東京”)
create_map_poster.py:654-660:
Theme System
Theme Structure
Themes are JSON files stored inthemes/ directory. Each theme defines a complete color palette:
themes/terracotta.json
Theme Loading
Theload_theme() function (create_map_poster.py:177-207):
- Reads JSON from
themes/{theme_name}.json - Falls back to embedded terracotta theme if file not found
- Returns dictionary accessible via global
THEMEvariable - Prints theme name and description on load
Adding Custom Themes
Define color palette
All colors must be hex codes. Required keys:
bg,text,gradient_colorwater,parksroad_motorway,road_primary,road_secondary,road_tertiary,road_residential,road_default
Font Management
Thefont_management.py module handles typography with support for Google Fonts and local font files.
Font Loading Pipeline
font_management.py:137
Local Font Loading (Default)
Local Font Loading (Default)
When no
--font-family is specified, loads Roboto from fonts/ directory:Roboto-Bold.ttf→fonts['bold']Roboto-Regular.ttf→fonts['regular']Roboto-Light.ttf→fonts['light']
font_management.py:158-168).Google Fonts Integration
Google Fonts Integration
The
download_google_font() function (font_management.py:17-134):Download Process:- Queries Google Fonts API for font family with weights 300, 400, 700
- Parses CSS response to extract
.woff2or.ttfURLs - Downloads font files to
fonts/cache/directory - Maps weights to keys: 300→light, 400→regular, 700→bold
- Downloaded fonts cached in
fonts/cache/{font_name_safe}_{weight}.woff2 - Subsequent runs use cached files
- Fallback to closest available weight if exact weight not found
Typography Positioning
All text usestransform=ax.transAxes with normalized coordinates (0-1 range):
create_map_poster.py:618-681):
- Base sizes defined at 12” reference width
- Scales by
min(height, width) / 12.0for proper landscape/portrait support - City name font reduces for long names (>10 characters) to prevent truncation
- Coordinate labels adjust format based on latitude/longitude signs
Caching System
Cache Implementation
MapToPoster uses pickle-based caching to avoid redundant OSM API calls:Cached Data Types
| Cache Key Format | Data Type | Example |
|---|---|---|
coords_{city}_{country} | (lat, lon) tuple | Geocoding results |
graph_{lat}_{lon}_{dist} | MultiDiGraph | Street network |
{name}_{lat}_{lon}_{dist}_{tags} | GeoDataFrame | Water/parks features |
Cache directory location can be customized via
CACHE_DIR environment variable. Defaults to cache/ in project root.Cache Invalidation
Cache files persist indefinitely unless manually deleted. To refresh data:Performance Considerations
Optimal Distance Values
Optimal Distance Values
Large distance values can significantly impact performance:
- < 20km: Fast downloads, reasonable memory usage
- 20-30km: Slower, higher memory consumption
- > 30km: Very slow, may hit API limits or memory issues
Network Type Optimization
Network Type Optimization
The default Other options:
network_type='all' includes all road types. For faster renders:'bike', 'walk' (see OSMnx documentation).Preview Renders
Preview Renders
Reduce DPI for quick previews:Cuts file size and render time by ~75%.
API Rate Limiting
API Rate Limiting
Implemented delays to respect service policies:
- Nominatim geocoding: 1.0s delay (
create_map_poster.py:334) - OSMnx graph fetch: 0.5s delay (
create_map_poster.py:433) - OSMnx features fetch: 0.3s delay (
create_map_poster.py:471)
Extension Points
Adding New Map Layers
To add a new layer (e.g., railways, buildings):- Add
"railway": "#FF0000"to all theme JSON files - Add fallback color in
load_theme()default dict
Useful OSMnx Tag Patterns
Custom Theme Properties
To add a new color property (e.g., for railways):Dependencies
Core Python packages used:| Package | Purpose | Key Usage |
|---|---|---|
osmnx | OpenStreetMap data fetching | Graph and feature downloads |
matplotlib | Rendering and plotting | Figure creation, layer composition |
geopandas | Geographic data handling | Feature dataframes, CRS projection |
geopy | Geocoding | City/country → coordinates |
shapely | Geometric operations | Point creation, geometry filtering |
networkx | Graph data structures | Street network storage |
numpy | Numerical operations | Gradient generation, array math |
requests | HTTP requests | Google Fonts downloading |
tqdm | Progress bars | User feedback during data fetching |
pyproject.toml and requirements.txt.