- CLI
- 数据可视化
【免费下载链接】maptoposter
Transform your favorite cities into beautiful, minimalist designs. MapToPoster lets you create and export visually striking map posters with code.
本文基于 maptoposter 仓库的 README.md 撰写,系统讲解如何为任意城市生成极简风格地图海报:从uv/pip环境安装、create_map_poster.py的完整 CLI 参数(含 i18n 多语言字体、分辨率与距离调优),到 17 个内置主题的 JSON 定制格式,再到create_poster()渲染管线、道路分级着色、Unicode 文字排版检测等源码级实现细节。读完本文,你可以独立生成、调参与扩展该项目,并理解每一层渲染的 z-order 与缓存机制。
1. 项目概览与核心工作流
maptoposter 是一个命令行工具:输入城市与国家名,它通过 Nominatim 地理编码定位,用 OSMnx 从 OpenStreetMap 拉取街道网络、水域与公园要素,经 matplotlib 按主题配色分层渲染,最终导出 300 DPI 的 PNG(或 SVG/PDF)海报。核心文件只有两个:主脚本 create_map_poster.py 与字体管理模块 font_management.py,主题以 JSON 形式存放在 themes/ 目录。
README 给出的架构流程如下:
┌─────────────────┐ ┌──────────────┐ ┌─────────────────┐ │ CLI Parser │────▶│ Geocoding │────▶│ Data Fetching │ │ (argparse) │ │ (Nominatim) │ │ (OSMnx) │ └─────────────────┘ └──────────────┘ └─────────────────┘ │ ┌──────────────┐ ▼ │ Output │◀────┌─────────────────┐ │ (matplotlib)│ │ Rendering │ └──────────────┘ │ (matplotlib) │ └─────────────────┘这条链路与源码完全对应:
- CLI Parser:
argparse解析器位于 create_map_poster.py#L860-L957,无参数运行时打印print_examples()帮助文本。 - Geocoding:
get_coordinates()(create_map_poster.py#L319-L370)使用geopy.geocoders.Nominatim(user_agent="city_map_poster", timeout=10),请求前主动time.sleep(1)以遵守 Nominatim 使用策略,并兼容 geopy 返回协程的环境。 - Data Fetching:
fetch_graph()(create_map_poster.py#L409-L441)调用ox.graph_from_point(point, dist=dist, dist_type='bbox', network_type='all', truncate_by_edge=True)拉取街道网络;水域、公园则通过fetch_features()按 OSM tag 拉取。 - Rendering/Output:
create_poster()(create_map_poster.py#L482)负责分层绘制与保存。
依赖清单见 requirements.txt(osmnx==2.0.7、matplotlib==3.10.8、geopy==2.4.1、geopandas==1.1.2、networkx、shapely、tqdm、lat_lon_parser等),pyproject.toml 中声明requires-python = ">=3.11"。
README 中的效果示例(城市 × 主题组合):
| Country | City | Theme | 示例海报 |
|---|---|---|---|
| USA | San Francisco | sunset | san_francisco_sunset |
| Spain | Barcelona | warm_beige | barcelona_warm_beige |
| Italy | Venice | blueprint | venice_blueprint |
| Japan | Tokyo | japanese_ink | tokyo_japanese_ink |
| India | Mumbai | contrast_zones | mumbai_contrast_zones |
| Morocco | Marrakech | terracotta | marrakech_terracotta |
| Singapore | Singapore | neon_cyberpunk | singapore_neon_cyberpunk |
| Australia | Melbourne | forest | melbourne_forest |
| UAE | Dubai | midnight_blue | dubai_midnight_blue |
| USA | Seattle | emerald | seattle_emerald |
2. 安装
方式一:uv(推荐)
前提是本机已安装 uv。uv run会自动创建并管理虚拟环境:
# 首次运行会自动安装依赖 uv run ./create_map_poster.py --city "Paris" --country "France" # 或先显式同步依赖(使用锁定版本),再运行 uv sync --locked uv run ./create_map_poster.py --city "Paris" --country "France"仓库提供了uv.lock锁文件,uv sync --locked保证依赖版本可复现。
方式二:pip + venv
python -m venv .venv source .venv/bin/activate # Windows 下使用 .venv\Scripts\activate pip install -r requirements.txt注意运行环境需要 Python 3.11+,且能访问 Nominatim、OpenStreetMap 与(可选的)Google Fonts 网络服务。
3. CLI 参数全解
生成海报
# uv 用户 uv run ./create_map_poster.py --city <city> --country <country> [options] # pip + venv 用户 python create_map_poster.py --city <city> --country <country> [options]必选参数
| Option | Short | 说明 |
|---|---|---|
--city | -c | 城市名(用于地理编码) |
--country | -C | 国家名(用于地理编码) |
可选参数
| Option | Short | 说明 | 默认值 |
|---|---|---|---|
--latitude | -lat | 覆盖纬度中心点(需与--longitude一起使用) | — |
--longitude | -long | 覆盖经度中心点(需与--latitude一起使用) | — |
--country-label | 覆盖海报上显示的国名文本 | — | |
--theme | -t | 主题名 | terracotta |
--distance | -d | 地图半径(米) | 18000 |
--list-themes | 列出所有可用主题 | — | |
--all-themes | 为所有可用主题各生成一张海报 | — | |
--width | -W | 图片宽度(英寸) | 12(上限 20) |
--height | -H | 图片高度(英寸) | 16(上限 20) |
几点源码级补充:
--latitude/--longitude仍需同时提供--city/--country。入口处if not args.city or not args.country会直接报错退出(create_map_poster.py#L972-L975),城市/国家名仍用于海报文字显示;坐标参数只是绕过地理编码定位地图中心。坐标值通过lat_lon_parser.parse()解析,因此也接受更宽松的经纬度写法。- 20 英寸上限是硬约束:入口处
if args.width > 20/if args.height > 20会把超限值强制截为 20.0 并打印警告(create_map_poster.py#L977-L987),这对应 CHANGELOG.md 中"max dimensions enforced at 20 inches(支持到 4K 分辨率)"的说明。 - 输出格式:README 参数表未单列,但源码支持
--format/-f,取值为png、svg、pdf,默认png(create_map_poster.py#L951-L957),对应 0.2.1 版本引入的矢量导出能力。仅png会显式以 300 DPI 保存(save_kwargs["dpi"] = 300),SVG/PDF 为矢量输出。 - 输出文件命名:由
generate_output_filename()生成,格式为{city}_{theme}_{YYYYMMDD_HHMMSS}.{ext},城市名转小写并将空格替换为下划线(create_map_poster.py#L147-L158),与 README 的 Output 一节一致。 --list-themes:list_themes()会读取每个主题 JSON 的name与description字段逐条打印(create_map_poster.py#L834-L857)。--all-themes:遍历themes/下全部 JSON 主题依次渲染,街道网络等数据因缓存机制只下载一次。
输出位置
海报保存到posters/目录,命名规则:
{city}_{theme}_{YYYYMMDD_HHMMSS}.png4. 多语言支持(i18n)与字体管理
海报文字可以显示为原生文字并匹配对应字体(字体来自 Google Fonts,自动下载并缓存):
| Option | Short | 说明 |
|---|---|---|
--display-city | -dc | 城市自定义显示名(如 "東京") |
--display-country | -dC | 国家自定义显示名(如 "日本") |
--font-family | Google Fonts 字体族名(如 "Noto Sans JP") |
示例:
# 日语 python create_map_poster.py -c "Tokyo" -C "Japan" -dc "東京" -dC "日本" --font-family "Noto Sans JP" # 韩语 python create_map_poster.py -c "Seoul" -C "South Korea" -dc "서울" -dC "대한민국" --font-family "Noto Sans KR" # 阿拉伯语 python create_map_poster.py -c "Dubai" -C "UAE" -dc "دبي" -dC "الإمارات" --font-family "Cairo"注意:字体自动从 Google Fonts 下载并缓存到fonts/cache/目录。
底层实现值得展开:
- 字体下载:font_management.py 中
download_google_font()(#L17-L134)请求https://fonts.googleapis.com/css2?family={family}:wght@300;400;700,用正则解析@font-face块提取 300/400/700 三种字重的 woff2/ttf 地址并逐个下载,缺字重时取最接近的字重或复用 regular。load_fonts()(#L137-L170)在没有指定字体族或下载失败时,回退到仓库内置的fonts/Roboto-{Bold,Regular,Light}.ttf。 - 拉丁文字检测:
is_latin_script()(create_map_poster.py#L114-L144)统计字母字符中ord(char) < 0x250(Basic Latin + Latin-1 + Latin Extended A/B,即 U+0000–U+024F 区间)的占比,超过 80% 判定为拉丁文字。这与 README 描述一致。 - 排版差异:在
create_poster()中,拉丁文字城市名会被转大写并逐字符加两个空格(" ".join(list(display_city.upper())),产生 "P A R I S" 效果);非拉丁文字则原样输出、不加空隙(create_map_poster.py#L651-L660)。 - 长城市名自动缩字:城市名超过 10 个字符时,主字号按
10/字符数比例缩小,下限为10 * scale_factor,避免截断(create_map_poster.py#L662-L672)。
5. 分辨率、尺寸与地图范围
分辨率指南(300 DPI)
输出分辨率由英寸尺寸 × 300 DPI 决定(PNG 固定 300 DPI 保存),README 给出的常用目标如下:
| Target | 分辨率 (px) | 英寸 (-W / -H) |
|---|---|---|
| Instagram Post | 1080 x 1080 | 3.6 x 3.6 |
| Mobile Wallpaper | 1080 x 1920 | 3.6 x 6.4 |
| HD Wallpaper | 1920 x 1080 | 6.4 x 3.6 |
| 4K Wallpaper | 3840 x 2160 | 12.8 x 7.2 |
| A4 Print | 2480 x 3508 | 8.3 x 11.7 |
距离指南
| Distance | 适用场景 |
|---|---|
| 4000-6000m | 小型/密集城市(Venice、Amsterdam 市中心) |
| 8000-12000m | 中型城市、聚焦市中心(Paris、Barcelona) |
| 15000-20000m | 大型都市、全貌视图(Tokyo、Mumbai) |
一个容易忽略的源码细节:--distance传入的半径不会原样使用。create_poster()中会先做视口补偿:
compensated_dist = dist * (max(height, width) / min(height, width)) / 4 # To compensate for viewport crop(create_map_poster.py#L534)即按画幅长宽比放大下载半径,再配合get_crop_limits()(create_map_poster.py#L373-L406)向内侧裁剪以匹配海报宽高比——横版会裁高度、竖版会裁宽度,同时保证所请求半径内的内容完整覆盖。这意味着:画幅越狭长,实际下载的 OSM 范围越大,首次运行(无缓存)耗时也更长。文字字号同理按min(height, width) / 12.0缩放(scale_factor,create_map_poster.py#L618-L626),保证横竖版下版式比例一致。
6. 使用示例
基础示例
# 默认主题(terracotta) python create_map_poster.py -c "Paris" -C "France" # 自定义主题与距离 python create_map_poster.py -c "New York" -C "USA" -t noir -d 12000多语言示例(非拉丁文字)
# 日语 python create_map_poster.py -c "Tokyo" -C "Japan" -dc "東京" -dC "日本" --font-family "Noto Sans JP" -t japanese_ink # 韩语 python create_map_poster.py -c "Seoul" -C "South Korea" -dc "서울" -dC "대한민국" --font-family "Noto Sans KR" -t midnight_blue # 泰语 python create_map_poster.py -c "Bangkok" -C "Thailand" -dc "กรุงเทพมหานคร" -dC "ประเทศไทย" --font-family "Noto Sans Thai" -t sunset # 阿拉伯语 python create_map_poster.py -c "Dubai" -C "UAE" -dc "دبي" -dC "الإمارات" --font-family "Cairo" -t terracotta # 中文(简体) python create_map_poster.py -c "Beijing" -C "China" -dc "北京" -dC "中国" --font-family "Noto Sans SC" # 高棉语 python create_map_poster.py -c "Phnom Penh" -C "Cambodia" -dc "ភ្នំពេញ" -dC "កម្ពុជា" --font-family "Noto Sans Khmer"进阶示例(按城市街道形态选参)
# 标志性网格 python create_map_poster.py -c "New York" -C "USA" -t noir -d 12000 # 曼哈顿网格 python create_map_poster.py -c "Barcelona" -C "Spain" -t warm_beige -d 8000 # Eixample 区 # 水岸与运河 python create_map_poster.py -c "Venice" -C "Italy" -t blueprint -d 4000 # 运河网络 python create_map_poster.py -c "Amsterdam" -C "Netherlands" -t ocean -d 6000 # 同心圆运河 python create_map_poster.py -c "Dubai" -C "UAE" -t midnight_blue -d 15000 # 棕榈岛与海岸线 # 放射状路网 python create_map_poster.py -c "Paris" -C "France" -t pastel_dream -d 10000 # 奥斯曼大道 python create_map_poster.py -c "Moscow" -C "Russia" -t noir -d 12000 # 环路 # 有机老城 python create_map_poster.py -c "Tokyo" -C "Japan" -t japanese_ink -d 15000 # 高密度有机路网 python create_map_poster.py -c "Marrakech" -C "Morocco" -t terracotta -d 5000 # 老城迷宫 python create_map_poster.py -c "Rome" -C "Italy" -t warm_beige -d 8000 # 古代布局 # 滨海城市 python create_map_poster.py -c "San Francisco" -C "USA" -t sunset -d 10000 # 半岛网格 python create_map_poster.py -c "Sydney" -C "Australia" -t ocean -d 12000 # 港湾城市 python create_map_poster.py -c "Mumbai" -C "India" -t contrast_zones -d 18000 # 滨海半岛 # 江河城市 python create_map_poster.py -c "London" -C "UK" -t noir -d 15000 # 泰晤士河弯道 python create_map_poster.py -c "Budapest" -C "Hungary" -t copper_patina -d 8000 # 多瑙河两岸 # 覆盖中心坐标 python create_map_poster.py --city "New York" --country "USA" -lat 40.776676 -long -73.971321 -t noir # 列出可用主题 python create_map_poster.py --list-themes # 为每个主题各生成一张 python create_map_poster.py -c "Tokyo" -C "Japan" --all-themes仓库还附带 test/all_variations.sh,它以 Bengaluru 为例把上述用法(基础、17 个主题、显示名覆盖、坐标覆盖、Kannada/Devanagari 多语言、5 档分辨率、3 档距离、--list-themes与--all-themes)串成一条批量生成流水线,可以作为参数组合的完整对照脚本参考。
7. 主题系统
内置主题
themes/目录当前提供 17 个主题(与 README 清单一致):
| Theme | 风格 |
|---|---|
gradient_roads | 平滑渐变着色 |
contrast_zones | 高对比城市密度 |
noir | 纯黑底白路 |
midnight_blue | 藏蓝底金线 |
blueprint | 建筑图纸风格 |
neon_cyberpunk | 深色底配电光粉/青 |
warm_beige | 复古棕褐色调 |
pastel_dream | 柔和马卡龙色 |
japanese_ink | 极简水墨 |
emerald | 浓郁墨绿美学 |
forest | 深绿与鼠尾草绿 |
ocean | 滨海城市的蓝与青 |
terracotta | 地中海暖调 |
sunset | 暖橙与粉 |
autumn | 季节性的焦橙与红 |
copper_patina | 氧化铜绿 |
monochrome_blue | 单一蓝色系 |
主题 JSON 格式
在themes/目录新建 JSON 文件即可添加自定义主题(文件名去掉.json即主题名):
{ "name": "My Theme", "description": "Description of the theme", "bg": "#FFFFFF", "text": "#000000", "gradient_color": "#FFFFFF", "water": "#C0C0C0", "parks": "#F0F0F0", "road_motorway": "#0A0A0A", "road_primary": "#1A1A1A", "road_secondary": "#2A2A2A", "road_tertiary": "#3A3A3A", "road_residential": "#4A4A4A", "road_default": "#3A3A3A" }各字段的实际用途(对照 themes/terracotta.json 与 themes/noir.json):
bg:画布背景色,同时用作plt.subplots(facecolor=...)、ax.set_facecolor(...)与保存时的facecolor;text:城市名、国名、坐标、装饰线与版权文字的绘制色;gradient_color:顶部/底部渐隐层颜色(通常与背景同色,实现"淡出"效果);water/parks:水域、公园多边形的填充色;road_*:按 OSM highway 类型分级的 6 档道路颜色(见下文映射表)。
容错机制:load_theme()(create_map_poster.py#L177-L207)在找不到themes/<name>.json时打印警告并回退到内置的 terracotta 调色板;但 CLI 入口在加载前会先校验主题名是否在themes/目录内,不存在则直接报错退出(create_map_poster.py#L997-L1000),所以正常命令行路径下不会触发内置回退。另外从源码结构看,主题 JSON 中新增的任意键(如"railway")都会原样进入THEME字典,可以在渲染代码中直接以THEME['railway']读取。
8. 渲染管线深度解析(Hacker's Guide)
README 的 Hacker's Guide 面向想扩展或修改脚本的开发者,以下是其核心内容结合源码的完整解读。
关键函数速查
| 函数 | 职责 | 何时修改 |
|---|---|---|
get_coordinates() | 城市 → 经纬度(Nominatim) | 更换地理编码服务 |
create_poster() | 主渲染管线 | 新增地图图层 |
get_edge_colors_by_type() | 按 OSM highway 标签分配道路颜色 | 修改道路配色逻辑 |
get_edge_widths_by_type() | 按道路等级分配线宽 | 调整线宽层级 |
create_gradient_fade() | 顶部/底部渐隐效果 | 修改渐变叠加 |
load_theme() | JSON 主题 → dict | 新增主题属性 |
is_latin_script() | 文字脚本检测(排版用) | 支持新文字体系 |
load_fonts() | 加载自定义/默认字体 | 修改字体加载逻辑 |
渲染层与 z-order
README 给出的层叠示意:
z=11 Text labels (city, country, coords) z=10 Gradient fades (top & bottom) z=3 Roads (via ox.plot_graph) z=2 Parks (green polygons) z=1 Water (blue polygons) z=0 Background color对照当前源码,实际取值为:背景ax.set_position((0.0, 0.0, 1.0, 1.0))铺满画布;水域多边形zorder=0.5、公园多边形zorder=0.8(create_map_poster.py#L572-L593);道路经ox.plot_graph(..., node_size=0, edge_color=..., edge_linewidth=...)绘制,保持 matplotlib 默认zorder=2;上下渐变zorder=10;文字与装饰线zorder=11。CHANGELOG.md 记录了这一处刻意修复:0.2 早期版本道路曾与公园/水域发生层叠冲突,修复方案就是把水层从 1 降到 0.5、公园层从 2 降到 0.8,确保道路始终压在面要素之上——上表中的 z=1/z=2 可理解为该修复前或简化示意。
另外两个保证画面正确的细节:
- 几何过滤:水域/公园只绘制
Polygon/MultiPolygon几何,ax.get_geom_type之外的点要素被过滤,避免小圆点污染画面(create_map_poster.py#L574-L576); - 投影:图先经
ox.project_graph(g)投影到米制 CRS,保证距离与宽高比线性,随后ax.set_aspect("equal", adjustable="box")+get_crop_limits()完成等比例裁剪。
道路分级:OSM highway 类型 → 颜色与线宽
get_edge_colors_by_type()与get_edge_widths_by_type()(create_map_poster.py#L255-L316)遍历图的每条边,读取highway属性(兼容列表取值),按以下层级映射:
# In get_edge_colors_by_type() and get_edge_widths_by_type() motorway, motorway_link → Thickest (1.2), 主题键 road_motorway trunk, primary(含 *_link) → Thick (1.0), 主题键 road_primary secondary(含 _link) → Medium (0.8), 主题键 road_secondary tertiary(含 _link) → Thin (0.6), 主题键 road_tertiary residential, living_street, unclassified → Thinnest (0.4), road_residential 其余类型 → 线宽 0.4,颜色 road_default源码中颜色分支额外覆盖了unclassified(归入 residential 色),宽度分支未列出的类型一律落到 0.4。也就是说主题里的road_*键与 OSM 标签之间是"语义映射",改配色只需改 JSON,不用动代码。
渐隐层实现
create_gradient_fade()(create_map_poster.py#L214-L252)构造 256 行单色 alpha 渐变图:底部渐变占据坐标轴 y 范围 0–0.25(alpha 从 1 到 0),顶部占据 0.75–1.0(alpha 从 0 到 1),颜色取THEME['gradient_color']。由于create_poster()在顶部/底部各调用一次,文字区域(底部 y<0.14 的轴坐标)会平滑融入背景。
文字排版与定位
所有文字使用transform=ax.transAxes(0–1 归一化坐标),基准位置为:
y=0.14 城市名(拉丁文字加宽间距显示) y=0.125 装饰横线(x 0.4–0.6) y=0.10 国名(大写) y=0.07 坐标(如 48.8566° N / 2.3522° E,负经度自动显示 W) y=0.02 版权文字(右下角,"© OpenStreetMap contributors")字号基准(12 英寸参考尺寸下):主标题 60、副标题 22、坐标 14、版权 8,再乘以scale_factor = min(height, width) / 12.0。脚本检测逻辑如前所述:拉丁文字 → 大写 + 字符间距;非拉丁文字 → 自然间距直排(create_map_poster.py#L651-L660)。
扩展新功能:README 给出的两个路径
新增地图图层(以铁路为例),在create_poster()公园获取之后:
try: railways = ox.features_from_point(point, tags={'railway': 'rail'}, dist=dist) except: railways = None # 然后绘制在道路之前: if railways is not None and not railways.empty: railways = railways.to_crs(g_proj.graph["crs"]) railways.plot(ax=ax, color=THEME['railway'], linewidth=0.5, zorder=2.5)新增主题属性:
- 在主题 JSON 中加键:
"railway": "#FF0000"; - 代码中使用
THEME['railway']; - 在
load_theme()的内置回退 dict 中补充默认值。
常用 OSMnx 模式
# 获取所有建筑 buildings = ox.features_from_point(point, tags={'building': True}, dist=dist) # 获取特定设施 cafes = ox.features_from_point(point, tags={'amenity': 'cafe'}, dist=dist) # 不同网络类型 G = ox.graph_from_point(point, dist=dist, network_type='drive') # 仅驾车道路 G = ox.graph_from_point(point, dist=dist, network_type='bike') # 自行车道 G = ox.graph_from_point(point, dist=dist, network_type='walk') # 步行网络注意当前脚本拉取路网用的是network_type='all'(create_map_poster.py#L431),性能建议中"改用drive提速"即针对此处。
性能建议(来自 README)
- 大
dist(>20km)= 下载慢 + 内存开销大; - 本地缓存坐标,规避 Nominatim 限速;
- 用
network_type='drive'替代'all'可加快渲染; - 快速预览时可把 DPI 从 300 降到 150(对应当前
save_kwargs["dpi"] = 300处)。
9. 数据缓存与网络行为
README 未单列、但 create_map_poster.py 源码中很重要的部分:
- 缓存目录:
CACHE_DIR_PATH = os.environ.get("CACHE_DIR", "cache"),即默认在项目根目录建cache/,可用环境变量CACHE_DIR重定向(create_map_poster.py#L40-L42); - 缓存内容:地理编码结果(键
coords_{city}_{country})、街道网络(键graph_{lat}_{lon}_{dist})、水域/公园要素(键{name}_{lat}_{lon}_{dist}_{tags}),均以 pickle 序列化(pickle.HIGHEST_PROTOCOL)存为.pkl; - 限速策略:地理编码请求前
sleep(1);街道图下载后sleep(0.5)、要素下载后sleep(0.3),对应 CHANGELOG 中 0.2.1 引入的"rate limiting"; - 容错:缓存读写异常统一包装为
CacheError并降级为普通打印,不会中断渲染;OSMnx 拉取失败时fetch_graph()/fetch_features()返回None——网络失败会抛RuntimeError("Failed to retrieve street network data."),而水域/公园失败只是静默跳过该图层。
因此典型工作流是"首次运行慢(全量下载 + 缓存),同城市同参数二次运行快(全部命中缓存)"。
10. 项目结构
maptoposter/ ├── create_map_poster.py # 主脚本(CLI、取数、渲染、输出) ├── font_management.py # 字体加载与 Google Fonts 集成 ├── themes/ # 主题 JSON 文件(17 个) ├── fonts/ # 字体文件 │ ├── Roboto-*.ttf # 默认 Roboto 字体 │ └── cache/ # 下载的 Google Fonts(自动生成) ├── posters/ # 生成的海报 └── README.md配套文件:requirements.txt(pip 安装)、pyproject.toml(uv/项目元数据,Python >=3.11)、uv.lock(锁定依赖版本)、CHANGELOG.md(版本记录)、test/all_variations.sh(批量生成脚本)。
11. 贡献者须知与已知限制
README 的 Contributors Guide 明确了社区约定:欢迎 bug 修复;暂不接受 Web/桌面 UI 提交;暂不 Dockerize;AI 辅助的修复须附改动前后海报对比验证;大功能先在 Discussions/Issue 确认是否会被合入。
结合源码可以归纳出几项使用限制与前提:
- 网络依赖:地理编码(Nominatim)、路网(OSM/OSMnx)、可选字体(Google Fonts)均需在线访问;断网时仅缓存命中的城市/参数组合可离线重绘。
--city/--country不可省略:即使提供了-lat/-long,仍会因参数校验而退出。- 尺寸上限 20×20 英寸(约对应 300 DPI 下 6000px),更高分辨率不可用命令行参数突破。
--distance是"半径"语义但会被长宽比补偿放大,狭长画幅下实际数据范围大于设定值,请预留下载时间。- 显示名与字体必须配套:
-dc/-dC指定非拉丁文字而未配对应--font-family时,默认 Roboto 不含相应字形,文字可能无法正常显示。
以上即为 maptoposter 从安装、调参、主题定制到渲染架构的完整技术图景:以 README.md 的实操指南为骨架,配合 create_map_poster.py 与 font_management.py 的实现细节,足以支撑日常使用与二次开发。
- CLI
- 数据可视化
【免费下载链接】maptoposter
Transform your favorite cities into beautiful, minimalist designs. MapToPoster lets you create and export visually striking map posters with code.
相关推荐
Printrun终极指南:5分钟快速掌握3D打印控制软件
Printrun终极指南:5分钟快速掌握3D打印控制软件 还在为复杂的3D打印控制软件而头疼吗?Printrun作为一款纯Python编写的开源3D打印主机软件
智能硬件桌面应用MapToPoster快速上手:3分钟生成您的第一份城市地图海报
MapToPoster快速上手:3分钟生成您的第一份城市地图海报 MapToPoster是一款能将您喜爱的城市转化为极简风格设计的工具,只需简单几步,就能用代码
CLI数据可视化React-primitives VR开发实战:构建沉浸式虚拟现实应用
React primitives VR开发实战:构建沉浸式虚拟现实应用 在当今快速发展的虚拟现实(VR)技术领域,React开发者也渴望能够使用熟悉的工具和框架
UI库/组件
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考