V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
爱意满满的作品展示区。
IanHo

开源自荐✨把你爱的城市搓成专业级艺术海报

  •  
  •   IanHo · 3h 5m ago · 259 views

    做了一个小工具,叫 MapPoster Online,可以在浏览器里把城市地图生成装饰画/海报。

    在线体验: https://maptoposter.0v0.one
    GitHub: https://github.com/ianho7/maptoposter-online

    这个项目的来源比较简单:之前看到过一个 Python CLI 项目 maptoposter,可以生成城市地图海报,效果挺有意思。但 CLI 对非 Python 用户来说还是有一点点门槛,需要装环境、跑命令、找输出文件。

    所以我做了一个网页版,目标是 0 门槛、打开网页后就能选城市、调样式、导出图片。

    现在能做什么

    • 选择城市并生成地图海报
    • 调整地图半径、主题、颜色、字体和版式
    • 支持 A4 竖版、A4 横版、方形、手机壁纸、桌面 16:9 等尺寸
    • 支持 300 DPI 导出,主要是为了打印
    • 内置 20 种主题
    • 可以上传 TTF/OTF 字体
    • 支持英文、中文、日文、韩文、德文、西班牙文、法文界面
    • 已获取的地图数据会缓存在浏览器 IndexedDB 里,重复生成会快一些

    一些生成效果:

    hongkong-map-poster (7).webp

    guangzhou-map-poster (2).webp

    技术上主要做了什么

    前端是 React 19 + TypeScript + Vite + Tailwind CSS 。渲染部分用了 Rust/WASM ,底层是 tiny-skia 。

    地图数据默认主要来自 OpenStreetMap ,通过 Overpass API 获取道路、水体、公园和 POI 数据。

    比较麻烦的地方是数据量。比如东京 18km 半径的测试数据,道路要素可以到 56 万以上,原始 GeoJSON 大约 40MB 。直接在浏览器里处理这种 GeoJSON ,很容易被 JSON.parse、对象转换、JS 和 WASM 之间的数据传输拖慢。

    后面做了几类优化:

    • 把复杂 GeoJSON 压平成 Float64Array,减少嵌套对象转换
    • 用 Worker 处理数据获取和投影转换,避免主线程卡死
    • 大块道路数据按道路边界切成多个 shard ,并行处理
    • WASM 渲染时尽量单次扫描,把道路按类型分发到不同 PathBuilder
    • Overpass 查询面积过大时做分块,并发检查多个公共镜像节点
    • 使用 IndexedDB 缓存获取过的数据

    因为地图数据量上来以后,普通 JSON 对象流转的成本会非常明显。

    目前的不足

    先说几个已知问题,免得大家试用时踩坑:

    • 第一次获取数据,特别是大城市、大半径生成还是可能慢,尤其受 Overpass 节点状态影响,哪怕已经做了多节点的竞速机制和分批获取数据(毕竟是公益节点,而且数据量特别大)
    • 不同城市的 OSM 数据完整度不一样,有些地方水域、绿地或 POI 效果会受影响。

    想听听大家的反馈

    主要想问几个问题:

    • 默认主题是否够用?本地开发是做了一个直接从剪贴板获取 JSON 的,因为我定义了一套 prompt 让 AI 帮我根据上传的图片生成配色,还挺实用,但是感觉解释成本有点高,所以暂时在线上版本隐藏起来了
    • 如果作为地图海报工具,大家更希望加哪些控制项?比如控制是否渲染 POI 、道路等级、水域样式等。
    • 在浏览器端处理 OSM / Overpass 数据,还有没有更稳的实践?

    在线体验: https://maptoposter.0v0.one
    GitHub: https://github.com/ianho7/maptoposter-online

    欢迎直接回复,也可以在 GitHub 开 issue ,当然如果能给我一个 Star 就更好了 😊

    3 replies    2026-04-30 18:30:15 +08:00
    Hiok
        1
    Hiok  
       2h 8m ago
    不错 支持一下
    IlIl
        2
    IlIl  
       2h 3m ago
    和这个网址有点像 https://terraink.app/
    quanmz0zhang
        3
    quanmz0zhang  
       1h 28m ago
    shanxi shanxi 陕西山西怎么区分?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2647 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 11:58 · PVG 19:58 · LAX 04:58 · JFK 07:58
    ♥ Do have faith in what you're doing.