MapPoster Online

May 18, 2026 · View on GitHub

MapPoster Online

Turn the cities you love into stunning designs

English | 简体中文


Project Description

A browser-based upgrade to maptoposter (Python CLI) — no installation needed, just open and go

React TypeScript Tailwind CSS Bun Rust License

Asia

China - BeijingJapan - TokyoSouth Korea - SeoulChina - Hong Kong
BeijingTokyoSeoulHong Kong
SingaporeMalaysia - Kuala LumpurThailand - BangkokIndia - New Delhi
SingaporeKuala LumpurBangkokNew Delhi

Europe

Switzerland - ZurichNorway - OsloSweden - StockholmDenmark - Copenhagen
ZurichOsloStockholmCopenhagen
Austria - ViennaGermany - BerlinUnited Kingdom - LondonFrance - Paris
ViennaBerlinLondonParis
Italy - RomeRussia - MoscowTurkey - IstanbulNetherlands - Amsterdam
RomeMoscowIstanbulAmsterdam

Americas, Africa & Oceania

USA - New YorkCanada - OttawaBrazil - São PauloMexico - Mexico City
New YorkOttawaSao PauloMexico City
Argentina - Buenos AiresAustralia - MelbourneSouth Africa - Cape TownChile - Santiago
Buenos AiresMelbourneCape TownSantiago

Features

  • 🚀 Zero installation — Runs entirely in the browser. Open the site, pick a city, and download your poster
  • Rust/WASM rendering engine — High-performance map rendering compiled from Rust to WebAssembly (powered by tiny-skia)
  • 👁️ Live preview — See changes instantly and confirm results before exporting
  • 🎨 20 built-in themes — From frozen Nordic minimalism to cyberpunk neon, vintage nautical to glitch purple
  • ✏️ Custom color controls — Fine-tune every color: background, roads, water, green spaces, POIs, and text
  • 📐 Multiple export formats — A4 (portrait/landscape), square, phone wallpaper, desktop 16:9, at 300 DPI for high-quality print
  • 🌐 Multi-language interface — Supports English, Japanese, Korean, Simplified Chinese, German, Spanish, and French
  • 💾 IndexedDB caching — Previously fetched map data is cached locally for faster regeneration
  • 🔤 Dynamic font loading — Use built-in serif fonts or upload your own TTF/OTF files
  • 🐍 Snake game — Beat boredom while waiting for your poster to generate (inspired by Chrome Dinosaur Game)

How it differs from maptoposter (Python CLI)

This project was inspired by maptoposter (Python CLI) — they each have their own strengths for different use cases:

maptoposter-onlinemaptoposter (Python CLI)
UsageOpen in browser, no install neededCommand-line interface, requires local setup
Best forQuick start, on-the-go usageCommand-line enthusiasts, advanced local customization
Rendering engineRust/WASM (tiny-skia)Python/matplotlib
PlatformCross-browser, any deviceDesktop only (requires Python)

Different tech stacks, same goal — turning your favorite city into unique art.

Local Development

Tech Stack

  • Build — Vite 7 + Bun
  • Frontend — React 19 + TypeScript
  • Styling — Tailwind CSS v4
  • UI components — Radix UI + lucide-react
  • Map data — OpenStreetMap (Overpass API) + Protomaps
  • Rendering — Rust (wasm-pack) + tiny-skia
  • i18n — @inlang/paraglide-js
  • Caching — IndexedDB (idb)

Requirements

Setup

# 1. Install dependencies
bun install

# 2. Build the Rust/WASM rendering engine
# Compile Rust to WebAssembly using wasm-pack
cd wasm && wasm-pack build --target web --out-dir ../src/pkg
# Or use the npm script:
bun run build:wasm

# 3. Start the dev server
bun run dev

# 4. App available at http://localhost:5173

Available Scripts

CommandDescription
bun run devStart dev server
bun run buildBuild for production
bun run build:wasmRebuild WASM engine
bun run previewPreview production build
bun run lintRun linter
bun run fixFormat + lint with auto-fix

Engineering Notes

Rendering Engine — Rust/WASM

  • Font anti-aliasing — 2× supersampling + Box Filter downsampling
  • Road hierarchy lacking depth — Road casing rendered in two passes (stroke first, then fill) + Z-order controls draw sequence by road class
  • Rendering too slow — Douglas-Peucker in screen coordinate space removes subpixel redundancy; single-scan dispatch by feature type

Data Processing

  • Python OSMnx workflow ported — Professional geospatial data processing logic adapted from osmnx
  • Overpass query failures — Auto-splits oversized areas into smaller chunks (2500km² default limit) to prevent Overpass failures
  • Single node timeout causing long waits — Concurrent requests to 4 mirror servers, fastest response wins

Page Responsiveness

  • Generation blocking the page — Data fetching, projection transforms, and WASM rendering all run in a Web Worker; road precision auto-reduces at large radii
  • Repeated generation taking too long — IndexedDB Gzip-compressed cache, ~100KB per city; direct read on regeneration

License

MIT License — see LICENSE

💖 Support

If this project has saved you time or made your life easier, consider buying me a coffee. Your support is the driving force behind the continued maintenance of this project!

PlatformPayment MethodLink
AfdianWeChat / Alipay👉 Click to Sponsor
Buy Me a CoffeeCredit Card / Apple Pay / Google Pay👉 Click to Sponsor

Acknowledgments

Inspired by @originalankur's maptoposter

Map data provided by OpenStreetMap and Protomaps

Font LXGW Neo ZhiSong (霞鹜新致宋) by lxgw, licensed under IPA Font License 1.0