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

巴黎 midnight_blue — 8.5/10

纽约 neon_cyberpunk — 8/10
OpenStreetMap 地图海报生成器这个品类,GitHub 上有几十个仓库。但砍掉 fork、平庸项目、找不到的仓库后,真正值得比的就三个:
项目 | 类型 | Stars | 适合谁 |
|---|---|---|---|
maptoposter[1] | Python CLI | 12.7k | 程序员、自动化批量出图 |
TerrainInk[2] | 在线 Web | 2k | 普通用户、设计师 |
maptoposter-online[3] | 在线 Web | — | 在意渲染质量和中文界面的用户 |
maptoposter[1] 是这个品类的祖师爷,12.7k stars 说明了一切。
上手只需要三步:
bash# 1. 克隆项目
git clone https://github.com/originalankur/maptoposter.git
cd maptoposter
# 2. 生成你的第一张海报(uv 会自动创建虚拟环境、安装依赖)
uv run create_map_poster.py --city "Beijing" --country "China"
# 3. 海报保存在 ../../assets/geospatial-data-analysis/map-poster/ 目录下
如果你已经装了 Python,也可以用 pip:

Beijing
bashgit clone https://github.com/originalankur/maptoposter.git
cd maptoposter
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python 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 界面
TerrainInk[2] 是近两年增长最快的浏览器端方案,terraink.app[5] 打开就能用,零学习成本。
技术栈是 TypeScript + MapLibre GL[6] + OpenFreeMap[7] 矢量瓦片。比 maptoposter-online 多了建筑轮廓图层,主题也更多。
唯一的缺点:没有 CLI,不能自动化批量出图。

maptoposter-online 界面
maptoposter-online[3] 的亮点是 Rust/WASM 渲染引擎——用 tiny-skia[8] 编译成 WebAssembly,渲染速度和质量都碾压纯 JS/Python 方案。
maptoposter.com[9] 在线可用,7 种 UI 语言(含中文),20 个主题,生成等待时还有贪吃蛇游戏。
缺点:只有道路图层,没有建筑。
这不是"哪个更好"的问题,而是"你要干什么":
CLI (maptoposter) | 在线 (TerrainInk / maptoposter-online) | |
|---|---|---|
上手门槛 | 需装 Python 环境 | 打开浏览器就行 |
自动化 | ✅ 脚本/AI 可调用 | ❌ 手动操作 |
批量出图 | ✅ --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 主题下辨识度极高。深蓝底+金色路网的配色像一本奢华城市地图集,东二环、南二环的弧线和棋盘式胡同路网形成鲜明对比。中文字体渲染完美,"北京"两个字在深色背景下锐利清晰。

Shanghai
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"
黄浦江把城市一分为二,浦西的老城厢细密路网和浦东的"大路网、大街区"规划形成有趣对比。霓虹青色的线条让上海看起来像一座数字夜城。

Xi’an
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 主题下像一幅古地图。浅棕色线条精准还原了老城区的规整网格,米白底色营造出复古宁静的氛围。这是"城市气质"和"主题风格"最契合的一组。

Chengdu
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 的地中海暖色调给这座西南城市增添了一丝异域感。中文字体厚重复古,和赤陶暖调高度匹配。一侧是规整方格路网+大型互通立交,另一侧是依蜿蜒水系发展的路网,展现了"因水兴城"的老城格局。

Hong Kong
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(纯黑白)主题下像一幅版画。九龙半岛密集的白色路网几乎填满画面,视觉冲击力极强。维多利亚港通过"路网缺失的黑色区域"自然呈现,青马大桥的复杂交织结构清晰可见。路网遇到山体时的蜿蜒走向,无声展示了城市规划与自然环境的互动。

Macau
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 主题的蓝色调呼应了这座海滨城市的身份。老城区蜿蜒街巷和新城区规整网格的对比一目了然,半岛"北窄南宽"的形态清晰完整。
经过实测,我发现城市路网特征和主题风格之间存在一些规律:
城市类型 | 推荐主题 | 原因 |
|---|---|---|
棋盘+环路(北京、成都) | midnight_blue | 金色路网凸显环路弧线,奢华地图集质感 |
现代网格(上海、深圳) | neon_cyberpunk | 霓虹色强化科技感,像数字脉络 |
古城网格(西安) | warm_beige | 复古暖调契合历史感,像古地图 |
高密度有机(香港) | noir | 黑白突出密度,版画质感 |
水城/海滨(澳门、威尼斯) | ocean / blueprint | 蓝色调呼应水元素 |
放射状(巴黎) | midnight_blue | 金色放射线像太阳光芒 |
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 14
done
这就是 CLI 工具的核心价值——可编程。AI agent 可以调用它,CI/CD 可以运行它,你的 cron job 可以每天自动生成不同城市的海报。
试了一圈下来,我发现一个有趣的空白:没有一个项目同时做到 CLI 自动化 + 在线零安装 + 多图层 + 建筑轮廓。
如果谁先把这几个能力整合到一起,就能吃掉整个市场。
想要什么 | 用什么 |
|---|---|
快速出一张好看的城市海报 | terraink.app[5] 或 maptoposter.com[9] |
批量生成、自动化工作流 | maptoposter[1] CLI |
最多图层和主题 | TerrainInk[2](有建筑图层) |
最高渲染质量 | maptoposter-online[3](Rust/WASM) |
中文界面 | maptoposter-online[3](7 种语言) |
把你热爱的城市变成艺术品,真的只需要一行命令。
本文所有配图均由 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/