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.
Welcome Contributors
Thank you for your interest in contributing to MapToPoster! This guide will help you set up your development environment and understand the contribution workflow.MapToPoster is a CLI-focused project. We welcome bug fixes and feature enhancements that align with the project’s minimalist design philosophy.
Contribution Philosophy
Before starting work, please review these guidelines:✅ We Welcome
- Bug fixes for rendering issues, crashes, or incorrect output
- Performance improvements for data fetching or rendering speed
- New themes with well-designed color palettes
- Documentation improvements for clarity and completeness
- New map layers (railways, buildings, etc.) that enhance poster quality
- Internationalization improvements for better font/script support
- Test coverage additions and improvements
❌ Please Don’t Submit
- User interfaces (web apps, desktop GUIs, mobile apps)
- MapToPoster is intentionally CLI-only to maintain simplicity
- Dockerization for now
- May be considered in the future, but not a current priority
- Major architectural rewrites without prior discussion
- Please open an issue or discussion first
Development Setup
Prerequisites
- Python 3.11 or higher (required since v0.3.0)
- Git for version control
- Text editor or IDE (VS Code, PyCharm, etc.)
Installation Methods
Option 1: Using uv (Recommended)
Option 1: Using uv (Recommended)
uv is the recommended package manager for MapToPoster. It provides faster dependency resolution and automatic virtual environment management.Install uv:Clone and setup:The
--locked flag ensures you get exact dependency versions from uv.lock for reproducible builds.Option 2: Using pip + venv
Option 2: Using pip + venv
Traditional Python virtual environment setup:
Verify Installation
Test that everything is working:- Progress bars for data fetching
- Theme loading confirmation
- A new PNG file in
posters/directory
Project Structure
Understanding the codebase layout:Key Files to Know
| File | Lines | Purpose |
|---|---|---|
create_map_poster.py | ~1052 | Main entry point, CLI parsing, rendering pipeline |
font_management.py | ~171 | Font loading, Google Fonts API integration |
themes/*.json | ~15 each | Color palette definitions |
pyproject.toml | ~30 | Python 3.11+ requirement, dependency list |
Making Changes
Development Workflow
Make your changes
Edit the relevant files. See Architecture Overview for code structure.For bug fixes:
- Identify the problematic function(s)
- Add print statements or use a debugger to trace the issue
- Fix the root cause, not just the symptom
- Follow existing code patterns (see Extension Points)
- Add necessary theme properties to ALL theme JSON files
- Update fallback values in
load_theme()function
Test your changes
CRITICAL: Test before and after versions!Test multiple scenarios:
- Different cities (grid vs organic layouts)
- Different themes (light vs dark backgrounds)
- Different distances (small 4000m vs large 18000m)
- Edge cases (coastal cities, islands, etc.)
Commit your changes
fix:for bug fixesfeat:for new featuresdocs:for documentation changestest:for test additionsrefactor:for code refactoring
Testing Guidelines
Manual Testing Checklist
Before submitting a PR, test these scenarios:Core Functionality
Core Functionality
- Basic poster generation works
- Geocoding resolves city/country correctly
- Cache is created and reused on second run
- Theme loading works for all built-in themes
- Error handling doesn’t crash the script
Visual Quality
Visual Quality
- Roads render above water and parks (z-order bug fixed in PR #42)
- Text is readable and properly positioned
- Gradients blend smoothly at top/bottom
- Aspect ratio is maintained (no distortion)
- Line weights are consistent across zoom levels
Edge Cases
Edge Cases
- Long city names don’t get cut off
- Non-Latin scripts render correctly (test with Japanese/Arabic)
- Custom coordinates override works
- Invalid city/country shows helpful error
- Network failures are handled gracefully
Cross-Platform
Cross-Platform
If possible, test on multiple platforms:
- macOS
- Linux
- Windows
Test Coverage Areas
We don’t have formal unit tests yet (contributions welcome!), but manual testing should cover:- Data Fetching: Verify OSMnx queries return expected data
- Rendering: Check layer composition and z-order
- Typography: Test Latin and non-Latin scripts
- Themes: Load all 17 themes successfully
- Caching: Confirm cache files are created and reused
- CLI Arguments: Test all flag combinations
Code Style Guidelines
Python Conventions
- Formatting: Follow PEP 8 style guide
- Line length: Max 120 characters (existing code uses ~100)
- Docstrings: Use triple-quoted strings with clear descriptions
- Type hints: Use when possible (see
fetch_graph()return type at line 409) - Naming:
- Functions:
snake_case(e.g.,get_edge_colors_by_type) - Classes:
PascalCase(e.g.,CacheError) - Constants:
UPPER_CASE(e.g.,FONTS_DIR,THEME)
- Functions:
Example Function
Comments
- Use comments to explain why, not what
- Complex algorithms should have explanatory comments
- Reference issue numbers when fixing bugs:
Adding New Themes
Themes are the easiest way to contribute!Creating a Theme
Design your color palette
Choose colors that work well together. Use tools like:
- Coolors.co for palette generation
- Adobe Color for harmony rules
- Paletton for color relationships
- Background should contrast with roads
- Water should be distinguishable from background
- Road hierarchy should be visible (motorway darkest/lightest)
- Text must be readable against background
Create JSON file
themes/my_theme.json
Test the theme
- Grid layouts (Barcelona, New York) - tests road hierarchy
- Water-heavy (Venice, Amsterdam) - tests water/road contrast
- Organic streets (Tokyo, Marrakech) - tests density rendering
Theme Design Tips
Road hierarchy matters! The difference between motorway and residential should be visually clear but not jarring. Aim for 15-20% brightness difference between adjacent levels.
- Background and gradient color mismatch (causes visible seam)
- Insufficient text contrast (hard to read city name)
- Water too similar to background (loses definition)
- All roads same color (loses street hierarchy)
Bug Fixes
Reporting Bugs
Before fixing a bug, check if it’s already reported in GitHub Issues. Good bug reports include:- MapToPoster version (check recent commits or tags)
- Python version (
python --version) - Operating system (macOS, Linux, Windows)
- Full command you ran
- Expected vs actual behavior
- Error messages or stack traces
- Sample poster showing the issue (if visual)
Example Bug Fix PR
See PR #42 for the road z-order fix: Problem: Roads were rendering below water/parks (issue #39) Solution: Adjusted z-order values:Common Development Tasks
Adding a New Map Layer
Example: Adding railway lines to posterscreate_map_poster.py (after line 558)
- Add
"railway": "#...",to ALL theme JSON files (17 files) - Update
load_theme()fallback dict at line 186 - Update total in
tqdm(line 526):total=4instead oftotal=3 - Test with cities that have railways (Tokyo, Paris, London)
Modifying Road Styling
To change how roads are colored/sized:- Color changes: Edit
get_edge_colors_by_type()at line 255 - Width changes: Edit
get_edge_widths_by_type()at line 289 - New road types: Add cases to both functions
Adjusting Typography
Text positioning uses normalized coordinates (0-1 range):y values (second argument).
Font sizes scale with poster dimensions (see create_map_poster.py:618-681):
base_main, base_sub, etc.
Performance Optimization
If you’re working on performance improvements:Profiling
Common Bottlenecks
-
OSM data fetching: Already cached, but initial fetch is slow
- Solution: No way around this, OSM API is the bottleneck
- Use smallest effective distance
-
Graph projection:
ox.project_graph()can be slow for large graphs- Solution: Already optimized, but could cache projected graphs
-
Matplotlib rendering:
plt.savefig()at high DPI- Solution: Use lower DPI for previews, 300 DPI for final
Memory Usage
For very large cities (dist > 25km), memory usage can spike:Getting Help
Stuck on something? Here’s where to ask:- GitHub Discussions: Best for questions about contributing, architecture, or design decisions
- GitHub Issues: For bugs you’ve found (check existing issues first)
- Code Comments: Read inline comments in
create_map_poster.py- they explain complex logic - This Documentation: Architecture Overview has detailed technical info
Changelog & Version History
When your PR is merged, it will be added toCHANGELOG.md. See Keep a Changelog format.
Recent significant changes:
- v0.3.0 (2026-01-27): Custom coordinates, emerald theme, default theme changed to terracotta
- v0.2.1 (2026-01-18): SVG/PDF export, variable dimensions, caching improvements
- v0.1.0 (2026-01-17): Initial release with 17 themes
- uv package manager support (PR #20)
- Z-order bug fix (PR #42, fixes #39)
- Text scaling for landscape orientations (#112)
License & Attribution
MapToPoster uses data from OpenStreetMap contributors. All posters must include the OSM attribution (automatically added at bottom-right):Thank You!
Every contribution - whether it’s a bug fix, new theme, documentation improvement, or feature enhancement - helps make MapToPoster better for everyone. Next Steps:- Set up your development environment
- Browse open issues for ideas
- Join discussions to share ideas
- Read the Architecture Overview for deep technical details