DEV Community

WonderLab
WonderLab

Posted on

Open Source Project of the Day (Part 15): MapToPoster - Converting City Maps into Beautiful Poster Designs with Code

Introduction

"Every city has a unique road texture, as distinctive as a fingerprint."

This is Part 15 of the "Open Source Project of the Day" series. Today we explore MapToPoster (GitHub).

Have you ever thought about converting a city you love into a beautiful poster? MapToPoster makes this idea a reality. It uses OpenStreetMap's open-source map data and Python code to convert city road networks into minimalist-style beautiful poster designs. Whether it's Paris's romantic streets, Tokyo's dense road networks, or New York's grid layout β€” all can be transformed into unique works of art.

Why this project?

  • πŸ—ΊοΈ Real map data: Based on OpenStreetMap, data is accurate and free
  • 🎨 17 beautiful themes: From minimalist black-and-white to neon cyberpunk, satisfying all aesthetics
  • 🐍 Pure Python implementation: Clean code, easy to understand and customize
  • 🎯 Minimalist design: Focused on road textures to reveal each city's unique beauty
  • πŸ“ Flexible configuration: Supports custom distance, coordinates, fonts, themes, and more
  • 🌍 Global city support: Supports road networks for any city in the world

What You'll Learn

  • MapToPoster's core principles and architectural design
  • How to use OSMnx to get and process map data
  • The design philosophy and use cases for 17 themes
  • How to customize themes and styles
  • Font management and Google Fonts integration
  • Layer structure and optimization tips for map rendering
  • Best practices and parameter tuning in real usage

Prerequisites

  • Basic Python syntax and command-line usage
  • Basic understanding of maps and geographic data
  • Familiarity with JSON configuration file format
  • Basic concepts of data visualization (optional, helps understand rendering principles)

Project Background

Project Introduction

MapToPoster is a Python tool for converting city maps into beautiful posters with code. It uses OpenStreetMap's open-source map data and the OSMnx library to retrieve city road networks, then renders them into minimalist-style poster designs using matplotlib. You can choose different themes, adjust the distance range, customize fonts, and generate unique city map posters.

Core problems the project solves:

  • Lack of simple and easy-to-use map poster generation tools
  • Commercial map service APIs are expensive and restricted
  • Need a programmable, customizable map visualization solution
  • Desire to convert city maps into works of art
  • Need to batch generate map posters for different cities and themes

Target user groups:

  • Designers and artistic creators
  • Geographic data visualization enthusiasts
  • Python developers
  • Urban planning and architecture professionals
  • Users who want to create personalized city posters

Author/Team Introduction

Author: originalankur

  • Background: Open-source contributor focused on data visualization and design tools
  • Project creation date: 2024 (based on GitHub activity, an actively maintained project)
  • Philosophy: Create beauty with code, turn map data into art
  • Tech stack: Python, OSMnx, matplotlib, OpenStreetMap

Project Stats

  • ⭐ GitHub Stars: 9.8k+ (rapidly and continuously growing)
  • 🍴 Forks: 872+
  • πŸ“¦ Version: Continuously updated (50+ commits)
  • πŸ“„ License: MIT (fully open source, free to use)
  • 🌐 Project: GitHub
  • πŸ’¬ Community: Active GitHub Issues, 9 open Issues, 16 Pull Requests
  • πŸ‘₯ Contributors: 15 contributors, active community participation

Project development history:

  • 2024: Project created, core features implemented
  • Mid-2024: Added multi-theme support
  • Late 2024: Improved font management and Google Fonts integration
  • 2025: Optimized rendering performance, added more themes
  • Ongoing maintenance: Project remains active with continuous community contributions

Main Features

Core Purpose

MapToPoster's core purpose is to convert city map data into beautiful poster designs, with main features including:

  1. Map data acquisition: Uses OSMnx to retrieve city road network data from OpenStreetMap
  2. Multi-theme rendering: Supports 17 carefully designed themes, from minimal to cyberpunk
  3. Flexible configuration: Supports custom distance range, center coordinates, fonts, themes, and more
  4. High-quality output: Generates high-resolution PNG images suitable for printing and display
  5. Font management: Supports local fonts and automatic Google Fonts download
  6. Script detection: Automatically detects text script (Latin/non-Latin) and applies appropriate typography

15-01-barcelona_warm_beige

15-02-dubai_midnight_blue

15-03-san_francisco_sunset

15-04-singapore_neon_cyberpunk

Use Cases

MapToPoster is suitable for multiple scenarios:

  1. Personal collection and decoration

    • Create city map posters of places you've lived or love
    • Use as room decoration or give as gifts to friends
    • Document your travel footprint with a city series of posters
  2. Design and artistic creation

    • Designers obtaining city map materials
    • Map elements for art projects
    • Geographic elements in brand design
  3. Education and display

    • Visualization tool for geography teaching
    • Urban planning presentations
    • Data visualization projects
  4. Batch generation

    • Generate consistent-style posters for multiple cities
    • Test different theme effects
    • Create city comparison series

Quick Start

Installation

MapToPoster installation is very simple:

# 1. Clone the project
git clone https://github.com/originalankur/maptoposter.git
cd maptoposter

# 2. Install dependencies
pip install -r requirements.txt

# Or use pyproject.toml
pip install -e .
Enter fullscreen mode Exit fullscreen mode

Main dependencies:

  • osmnx: Get OpenStreetMap data
  • matplotlib: Map rendering
  • geopy: Geocoding (via Nominatim)
  • requests: Google Fonts API calls

Simplest Usage Example

Generate a minimalist black-and-white style poster of Paris:

python create_map_poster.py -c "Paris" -C "France" -t noir -d 10000
Enter fullscreen mode Exit fullscreen mode

This command will:

  • Find Paris's coordinates (via Nominatim geocoding)
  • Retrieve the road network within a 10km radius
  • Use the noir theme (pure black background, white roads)
  • Generate the poster and save it to the posters/ directory

Output filename format: Paris_noir_20260208_143022.png

Common Command Examples

# Generate posters with different themes
python create_map_poster.py -c "Tokyo" -C "Japan" -t neon_cyberpunk -d 15000
python create_map_poster.py -c "London" -C "UK" -t noir -d 15000
python create_map_poster.py -c "New York" -C "USA" -t blueprint -d 12000

# Use custom coordinates
python create_map_poster.py --city "Shanghai" --country "China" \
  -lat 31.2304 -long 121.4737 -t sunset -d 10000

# View all available themes
python create_map_poster.py --list-themes

# Generate all themes for the same city
python create_map_poster.py -c "Paris" -C "France" --all-themes -d 10000
Enter fullscreen mode Exit fullscreen mode

Core Features

MapToPoster's core features include:

  1. 17 beautiful themes

    • From minimalist black-and-white (noir) to neon cyberpunk (neon_cyberpunk)
    • Each theme has a unique color scheme and design philosophy
    • Supports custom theme JSON files
  2. Intelligent road classification

    • Automatically classifies based on OSM's highway tag
    • Different road grades use different colors and widths
    • Presents a clear road hierarchy
  3. Flexible distance control

    • Supports distance ranges from 4000m to 20000m+
    • Recommends appropriate distances based on city scale
    • Balances detail and overall effect
  4. Font management

    • Uses Roboto font by default
    • Supports automatic Google Fonts download
    • Automatically detects text script, applies appropriate typography
  5. High-quality rendering

    • Default 300 DPI, suitable for printing
    • Supports custom DPI settings
    • Optimized rendering performance
  6. Geocoding integration

    • Automatically finds city coordinates via Nominatim
    • Supports city name + country name combination
    • Supports directly specifying latitude/longitude coordinates

Project Advantages

Compared to other map visualization tools:

Comparison MapToPoster Google Maps API Mapbox Other Open Source
Cost Completely free Pay per use Pay per use Free but limited
Data source OpenStreetMap (open) Google proprietary Mapbox proprietary Various sources
Customizability Highly customizable Limited Moderate Usually low
Theme support 17 beautiful themes Limited styles Requires design Usually none
Code control Fully programmable API calls API calls Partially programmable
Output quality High-res PNG Requires processing Requires processing Usually low
Offline use Supported (needs caching) Not supported Not supported Partial support

Why choose MapToPoster?

  • βœ… Completely free: Based on open-source data, no API fees
  • βœ… Highly customizable: Open-source code, can modify any detail
  • βœ… Beautiful themes: 17 professionally designed themes, ready to use
  • βœ… Simple to use: A single command generates a poster
  • βœ… High-quality output: High-resolution images suitable for printing and display
  • βœ… Active community: 9.8k+ Stars, continuously updated and maintained

Detailed Project Analysis

Architecture Design

MapToPoster's overall architecture is very clear, consisting of the following modules:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   CLI Parser    │────▢│  Geocoding   │────▢│  Data Fetching  β”‚
β”‚   (argparse)    β”‚     β”‚  (Nominatim) β”‚     β”‚    (OSMnx)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                     β”‚
                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β–Ό
                        β”‚    Output    β”‚β—€β”€β”€β”€β”€β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                        β”‚  (PNG File)  β”‚     β”‚   Rendering     β”‚
                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚  (matplotlib)   β”‚
                                             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Enter fullscreen mode Exit fullscreen mode

Core process:

  1. Command-line parsing: Uses argparse to parse user input (city, theme, distance, etc.)
  2. Geocoding: Converts city names to lat/lon coordinates via Nominatim API
  3. Data fetching: Uses OSMnx to get road network data from OpenStreetMap
  4. Theme loading: Loads theme configuration from JSON files
  5. Map rendering: Uses matplotlib to render the map according to theme configuration
  6. File saving: Saves the rendered result as a PNG file

Core Module Analysis

1. Geocoding Module

MapToPoster uses Nominatim (OpenStreetMap's geocoding service) to find city coordinates:

# Core function: get_coordinates()
# Input: city name, country name
# Output: lat/lon coordinates

# Example call
coordinates = get_coordinates("Paris", "France")
# Returns: (48.8566, 2.3522)
Enter fullscreen mode Exit fullscreen mode

Characteristics:

  • Free to use, no API key required
  • Supports city name + country name combination for improved accuracy
  • Supports directly specifying lat/lon to skip geocoding

2. Data Fetching Module (OSMnx)

OSMnx is MapToPoster's core dependency for getting OpenStreetMap data:

# Core function: Get road network
import osmnx as ox

# Get road network from point coordinates
G = ox.graph_from_point(
    point=(lat, lon),
    dist=distance,      # Distance (meters)
    network_type='drive'  # Road type
)

# Get water and park data
water = ox.features_from_point(
    point=(lat, lon),
    tags={'natural': 'water'},
    dist=distance
)
parks = ox.features_from_point(
    point=(lat, lon),
    tags={'leisure': 'park'},
    dist=distance
)
Enter fullscreen mode Exit fullscreen mode

Data layers:

  • Road network: Different road grades (motorway, primary, secondary, tertiary, residential)
  • Water bodies: Rivers, lakes, and other water features
  • Parks: Green spaces, parks, and other areas

3. Theme System

MapToPoster's theme system is very flexible β€” each theme is a JSON file:

{
  "name": "Noir",
  "description": "Pure black background, white roads",
  "bg": "#000000",
  "text": "#FFFFFF",
  "gradient_color": "#000000",
  "water": "#1A1A1A",
  "parks": "#0A0A0A",
  "road_motorway": "#FFFFFF",
  "road_primary": "#F0F0F0",
  "road_secondary": "#E0E0E0",
  "road_tertiary": "#D0D0D0",
  "road_residential": "#C0C0C0",
  "road_default": "#D0D0D0"
}
Enter fullscreen mode Exit fullscreen mode

Theme configuration options:

  • bg: Background color
  • text: Text color
  • water: Water body color
  • parks: Park color
  • road_*: Colors for different road grades

Overview of 17 themes:

Theme Name Style Description Use Case
noir Pure black background, white roads Minimalist, modern style
midnight_blue Deep blue background, gold roads Elegant, business style
blueprint Architectural blueprint style Architecture, engineering theme
neon_cyberpunk Neon cyberpunk Tech, futuristic
gradient_roads Gradient road coloring Artistic, creative
contrast_zones High-contrast urban density Emphasizes city structure
warm_beige Vintage brown tones Nostalgic, retro style
pastel_dream Soft pastel colors Soft, dreamy
japanese_ink Japanese ink wash style Eastern aesthetics
emerald Emerald green tones Natural, ecological
forest Deep green and sage Natural, forest theme
ocean Blue and cyan Coastal cities
terracotta Mediterranean warm tones Mediterranean style
sunset Warm orange and pink Warm, romantic
autumn Autumn leaf orange-red Seasonal theme
copper_patina Oxidized copper aesthetics Industrial, metallic
monochrome_blue Monochrome blue palette Unified, clean

4. Rendering System

MapToPoster's rendering system uses matplotlib, rendering in a specific layer order:

Render layers (z-order):

z=11  Text labels (city name, country name, coordinates)
z=10  Gradient masks (top and bottom gradient effects)
z=3   Road network (via ox.plot_graph)
z=2   Parks (green polygons)
z=1   Water bodies (blue polygons)
z=0   Background color
Enter fullscreen mode Exit fullscreen mode

Road grade rendering:

# Set colors and widths based on road type
def get_edge_colors_by_type(edge_types, theme):
    colors = []
    for edge_type in edge_types:
        if 'motorway' in edge_type:
            colors.append(theme['road_motorway'])
        elif 'primary' in edge_type or 'trunk' in edge_type:
            colors.append(theme['road_primary'])
        elif 'secondary' in edge_type:
            colors.append(theme['road_secondary'])
        elif 'tertiary' in edge_type:
            colors.append(theme['road_tertiary'])
        elif 'residential' in edge_type:
            colors.append(theme['road_residential'])
        else:
            colors.append(theme['road_default'])
    return colors
Enter fullscreen mode Exit fullscreen mode

Road width grades:

  • motorway, motorway_link: Thickest (1.2), darkest color
  • trunk, primary: Thick (1.0)
  • secondary: Medium (0.8)
  • tertiary: Thin (0.6)
  • residential, living_street: Thinnest (0.4), lightest color

5. Font Management System

MapToPoster includes an intelligent font management system:

Font loading logic:

  1. Prioritize local fonts (from fonts/ directory)
  2. If not available locally, download from Google Fonts
  3. Automatically cache downloaded fonts to fonts/cache/ directory

Script detection:

  • Automatically detects if text uses Latin script
  • Latin script: Apply letter spacing, producing "P A R I S" effect
  • Non-Latin script (Chinese, Japanese, Arabic, etc.): Use natural spacing
def is_latin_script(text):
    """Detect if text uses Latin script"""
    latin_chars = sum(1 for c in text if '\u0000' <= c <= '\u024F')
    total_chars = sum(1 for c in text if c.isalpha())
    return (latin_chars / total_chars) > 0.8 if total_chars > 0 else False
Enter fullscreen mode Exit fullscreen mode

Advanced Customization Tips

1. Create Custom Themes

Creating a custom theme is simple β€” just create a JSON file in the themes/ directory:

// themes/my_custom_theme.json
{
  "name": "My Custom Theme",
  "description": "A custom theme with warm colors",
  "bg": "#2C1810",
  "text": "#F5E6D3",
  "gradient_color": "#2C1810",
  "water": "#1A4A5C",
  "parks": "#3A5A3A",
  "road_motorway": "#E8B86D",
  "road_primary": "#D4A574",
  "road_secondary": "#C0956A",
  "road_tertiary": "#AD8560",
  "road_residential": "#9A7556",
  "road_default": "#AD8560"
}
Enter fullscreen mode Exit fullscreen mode

Then use it:

python create_map_poster.py -c "Paris" -C "France" -t my_custom_theme -d 10000
Enter fullscreen mode Exit fullscreen mode

2. Batch Generation Script

#!/usr/bin/env python3
# batch_generate.py

import subprocess

cities = [
    ("Paris", "France", "noir", 10000),
    ("Tokyo", "Japan", "neon_cyberpunk", 15000),
    ("New York", "USA", "blueprint", 12000),
    ("London", "UK", "midnight_blue", 10000),
]

for city, country, theme, distance in cities:
    print(f"Generating {city} with {theme} theme...")
    cmd = [
        "python", "create_map_poster.py",
        "-c", city,
        "-C", country,
        "-t", theme,
        "-d", str(distance)
    ]
    subprocess.run(cmd)
    print(f"βœ“ Completed {city}\n")
Enter fullscreen mode Exit fullscreen mode

Project Resources

Official Resources


Who Should Use This

MapToPoster is suitable for:

  1. Designers and artistic creators

    • Designers needing city map materials
    • Artists creating city-themed works
    • Creative workers who need to batch generate map designs
  2. Python developers

    • Developers interested in data visualization
    • Programmers wanting to learn geographic data processing
    • Developers needing to integrate maps into projects
  3. Geographic and urban planning professionals

    • Urban planners and architects
    • Geographic Information System (GIS) workers
    • Professionals who need to showcase city structures
  4. General users

    • Users wanting to create personalized city posters
    • Travelers documenting their journeys
    • Map and geographic data enthusiasts
  5. Educators

    • Geography teachers needing visualization tools
    • Teaching materials for data visualization courses
    • Project materials for programming and design courses

Welcome to visit my personal homepage for more useful knowledge and interesting products

Top comments (0)