用 Python 把城市变成艺术品:地图海报生成器完全指南
把你热爱的城市,变成一幅可以挂墙上的画。
你有没有想过,把北京的环路、上海的黄浦江、威尼斯的运河,变成一幅极简风格的装饰画?
这不是什么昂贵的设计服务——几个开源项目就能做到,而且大多数只需要一行命令。
我花了一周时间,把市面上所有地图海报生成器都试了一遍。这篇文章告诉你:哪些值得用,怎么用,以及为什么不同城市适合不同主题。
先看几张实际出图效果:


OpenStreetMap 地图海报生成器这个品类,GitHub 上有几十个仓库。但砍掉 fork、平庸项目、找不到的仓库后,真正值得比的就三个:
maptoposter[1] 是这个品类的祖师爷,12.7k stars 说明了一切。
上手只需要三步:
bash# 1. 克隆项目git clone https://github.com/originalankur/maptoposter.gitcd maptoposter# 2. 生成你的第一张海报(uv 会自动创建虚拟环境、安装依赖)uv run create_map_poster.py --city "Beijing" --country "China"# 3. 海报保存在 ../../assets/geospatial-data-analysis/map-poster/ 目录下如果你已经装了 Python,也可以用 pip:

bashgit clone https://github.com/originalankur/maptoposter.gitcd maptoposterpython -m venv .venv && source .venv/bin/activatepip install -r requirements.txtpython create_map_poster.py --city "Beijing" --country "China"它的核心优势是自动化友好——CLI 工具意味着你可以写脚本批量出图,AI agent 可以直接调用。我这次文章里所有配图,都是用它生成的。
技术栈是 Python + matplotlib + osmnx[4],通过 OpenStreetMap 获取道路、水体、公园数据。支持 17 个主题、Google Fonts 自定义字体、--all-themes 批量生成。
缺点?matplotlib 渲染慢(大图 15-20 秒),只有道路+水体+公园图层,没有建筑轮廓。

TerrainInk[2] 是近两年增长最快的浏览器端方案,terraink.app[5] 打开就能用,零学习成本。
技术栈是 TypeScript + MapLibre GL[6] + OpenFreeMap[7] 矢量瓦片。比 maptoposter-online 多了建筑轮廓图层,主题也更多。
唯一的缺点:没有 CLI,不能自动化批量出图。

maptoposter-online[3] 的亮点是 Rust/WASM 渲染引擎——用 tiny-skia[8] 编译成 WebAssembly,渲染速度和质量都碾压纯 JS/Python 方案。
maptoposter.com[9] 在线可用,7 种 UI 语言(含中文),20 个主题,生成等待时还有贪吃蛇游戏。
缺点:只有道路图层,没有建筑。
这不是"哪个更好"的问题,而是"你要干什么":
| 上手门槛 | ||
| 自动化 | ||
| 批量出图 | --all-themes 一键全出 | |
| 适合人群 |
如果你是程序员,想要批量生成不同城市的海报,或者集成到 AI 工作流里,选 maptoposter。
如果你只是想快速出一张好看的城市海报挂墙上,打开 terraink.app[5] 或 maptoposter.com[9] 就够了。
我用 maptoposter 生成了多个中国城市+地区的海报,逐个评分后,只保留了 8 分以上的 6 个。
bashpython create_map_poster.py --city "Beijing" --country "China" \ --latitude 39.9042 --longitude 116.4074 \ --theme midnight_blue --distance 12000 \ --display-city "北京" --display-country "中国" \ --font-family "Noto Sans SC"北京的"棋盘+环路"结构在 midnight_blue 主题下辨识度极高。深蓝底+金色路网的配色像一本奢华城市地图集,东二环、南二环的弧线和棋盘式胡同路网形成鲜明对比。中文字体渲染完美,"北京"两个字在深色背景下锐利清晰。

bashpython create_map_poster.py --city "Shanghai" --country "China" \ --latitude 31.2304 --longitude 121.4737 \ --theme neon_cyberpunk --distance 10000 \ --display-city "上海" --display-country "中国" \ --font-family "Noto Sans SC"黄浦江把城市一分为二,浦西的老城厢细密路网和浦东的"大路网、大街区"规划形成有趣对比。霓虹青色的线条让上海看起来像一座数字夜城。

bashpython create_map_poster.py --city "Xi'an" --country "China" \ --latitude 34.3416 --longitude 108.9398 \ --theme warm_beige --distance 6000 \ --display-city "西安" --display-country "中国" \ --font-family "Noto Sans SC"西安古城的棋盘式路网在 warm_beige 主题下像一幅古地图。浅棕色线条精准还原了老城区的规整网格,米白底色营造出复古宁静的氛围。这是"城市气质"和"主题风格"最契合的一组。

bashpython create_map_poster.py --city "Chengdu" --country "China" \ --latitude 30.5728 --longitude 104.0668 \ --theme terracotta --distance 10000 \ --display-city "成都" --display-country "中国" \ --font-family "Noto Sans SC"成都的环形路网和北京类似,但更有机、更"生长"的感觉。terracotta 的地中海暖色调给这座西南城市增添了一丝异域感。中文字体厚重复古,和赤陶暖调高度匹配。一侧是规整方格路网+大型互通立交,另一侧是依蜿蜒水系发展的路网,展现了"因水兴城"的老城格局。

bashpython create_map_poster.py --city "Hong Kong" --country "China" \ --latitude 22.3193 --longitude 114.1694 \ --theme noir --distance 6000 \ --display-city "香港" --display-country "中国" \ --font-family "Noto Sans SC"香港的高密度路网在 noir(纯黑白)主题下像一幅版画。九龙半岛密集的白色路网几乎填满画面,视觉冲击力极强。维多利亚港通过"路网缺失的黑色区域"自然呈现,青马大桥的复杂交织结构清晰可见。路网遇到山体时的蜿蜒走向,无声展示了城市规划与自然环境的互动。

bashpython create_map_poster.py --city "Macau" --country "China" \ --latitude 22.1987 --longitude 113.5439 \ --theme ocean --distance 3000 \ --display-city "澳门" --display-country "中国" \ --font-family "Noto Sans SC"澳门半岛面积很小,3000m 半径就能覆盖整个核心区。ocean 主题的蓝色调呼应了这座海滨城市的身份。老城区蜿蜒街巷和新城区规整网格的对比一目了然,半岛"北窄南宽"的形态清晰完整。
经过实测,我发现城市路网特征和主题风格之间存在一些规律:
| 棋盘+环路 | ||
| 现代网格 | ||
| 古城网格 | ||
| 高密度有机 | ||
| 水城/海滨 | ||
| 放射状 |
maptoposter 支持自定义主题,只需要在 themes/ 目录下放一个 JSON 文件:
json{"name":"我的主题","bg":"#1a1a2e","water":"#16213e","parks":"#0f3460","road_primary":"#e94560","road_secondary":"#533483","road_default":"#0f3460","text":"#e94560"}每个颜色字段控制地图的不同元素:背景、水体、公园、各级道路、文字。
如果你想像我一样批量生成多个城市的海报,可以写一个简单的脚本:
bash#!/bin/bash# batch_poster.sh — 批量生成城市海报CITIES=("Beijing,China,39.9042,116.4074,midnight_blue,12000,北京""Shanghai,China,31.2304,121.4737,neon_cyberpunk,10000,上海""Xi'an,China,34.3416,108.9398,warm_beige,6000,西安""Chengdu,China,30.5728,104.0668,terracotta,10000,成都""Hong Kong,China,22.3193,114.1694,noir,6000,香港""Macau,China,22.1987,113.5439,ocean,3000,澳门")for entry in"${CITIES[@]}"; do IFS=','read -r city country lat lon theme dist display <<< "$entry"echo"生成: $display ($theme)..." python create_map_poster.py \ --city "$city" --country "$country" \ --latitude "$lat" --longitude "$lon" \ --theme "$theme" --distance "$dist" \ --display-city "$display" --display-country "中国" \ --font-family "Noto Sans SC" \ --width 10 --height 14done这就是 CLI 工具的核心价值——可编程。AI agent 可以调用它,CI/CD 可以运行它,你的 cron job 可以每天自动生成不同城市的海报。
试了一圈下来,我发现一个有趣的空白:没有一个项目同时做到 CLI 自动化 + 在线零安装 + 多图层 + 建筑轮廓。
如果谁先把这几个能力整合到一起,就能吃掉整个市场。
把你热爱的城市变成艺术品,真的只需要一行命令。
本文所有配图均由 maptoposter[1] 生成,数据来自 OpenStreetMap[10]。感谢开源社区。
参考链接
[1] https://github.com/originalankur/maptoposter
[2] https://github.com/yousifamanuel/terraink
[3] https://github.com/ianho7/maptoposter-online
[4] https://github.com/gboeing/osmnx
[5] https://terraink.app
[6] https://github.com/maplibre/maplibre-gl-js
[7] https://openfreemap.org
[8] https://github.com/RazrFalcon/tiny-skia
[9] https://maptoposter.com
[10] https://www.openstreetmap.org/