map-design

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Map Design

地图设计

You cannot draw a coastline from memory, and neither can any model. This skill gives you real geography: bundled boundary data, an offline gazetteer, proper projections, and a renderer with an editorial design system. You write a short JSON spec; the CLI draws the map.
Never hand-write map geometry, SVG paths or coordinates for countries, coasts or borders. Always go through
scripts/map.mjs
.
<skill-dir>
below is this skill's base directory. The CLI needs Node.js 20+ and nothing else. PNG export uses a local Chrome, Edge, Brave or Chromium if one exists; HTML and SVG always work.
你不能凭记忆绘制海岸线,任何模型也不能。此 Skill 提供真实地理信息:内置边界数据、离线地名库、恰当的地图投影,以及采用出版物级设计系统的渲染器。你只需编写简短的 JSON 规范;CLI 就会绘制地图。
绝不要手动编写国家、海岸线或边界的地图几何图形、SVG 路径或坐标。 始终通过
scripts/map.mjs
完成。
下文中的
<skill-dir>
表示此 Skill 的基础目录。CLI 除 Node.js 20+ 外不需要任何其他依赖。如果本地安装了 Chrome、Edge、Brave 或 Chromium,PNG 导出将使用其中之一;HTML 和 SVG 则始终可用。

Workflow

工作流

  1. Pick the kind from the table below. If the request is ambiguous, choose the closest kind and state the choice; ask only when the data is missing.
  2. Get the data. Use the user's file as is (CSV or JSON, path relative to the spec). For public statistics, fetch from a primary source and record it in
    source
    . Never invent values. If you must show placeholder numbers, say so in
    subtitle
    or
    note
    .
  3. Write the spec as
    <name>.json
    where the outputs should go. Start from the matching example in references/spec.md.
  4. Run
    node <skill-dir>/scripts/map.mjs render <name>.json
    . It writes
    <name>.html
    ,
    <name>.svg
    and
    <name>.png
    next to the spec and prints what it matched.
  5. Read the report. Fix every
    NOT MATCHED
    row (use the suggestions, an ISO code, or
    lon
    /
    lat
    ) and every ambiguity warning, then render again.
    node <skill-dir>/scripts/map.mjs check <name>.json
    validates without writing.
  6. Look at the PNG before you call it done. Check that the title states the point, labels are legible, nothing important is cut off, and the legend matches the data. Adjust and re-render; one or two passes is normal.
  7. Deliver the file paths, the data source, and anything left unmatched.
  1. 选择类型。 从下表中选择最合适的类型。如果请求不明确,选择最接近的类型并说明所选类型;仅在缺少数据时询问。
  2. 获取数据。 按原样使用用户提供的文件(CSV 或 JSON,路径相对于规范文件)。对于公开统计数据,应从一手来源获取并在
    source
    中记录。绝不编造数值。如果必须显示占位数字,请在
    subtitle
    或
    note
    中说明。
  3. 编写规范。 将规范编写为
    <name>.json
    ,输出文件将放在同一目录。以 references/spec.md 中匹配的示例开始。
  4. 运行渲染器。 执行
    node <skill-dir>/scripts/map.mjs render <name>.json
    。它会在规范文件旁写入
    <name>.html
    、
    <name>.svg
    和
    <name>.png
    ,并打印匹配到的内容。
  5. 阅读报告。 修复每一个
    NOT MATCHED
    行(使用建议项、ISO 代码或
    lon
    /
    lat
    )以及每一条歧义警告,然后重新渲染。
    node <skill-dir>/scripts/map.mjs check <name>.json
    可在不写入文件的情况下进行验证。
  6. 查看 PNG。 完成前检查 PNG。确认标题明确表达核心结论、标签清晰可辨、重要内容未被裁切,并且图例与数据匹配。调整后重新渲染;通常需要一至两轮。
  7. 交付结果。 提供文件路径、数据源以及所有未匹配项。

Choosing a kind

选择类型

The user has or wantskindNotes
A rate or share per country, state, province or county
choropleth
Rates, not raw counts.
Counts or totals at places
bubbles
Circle area ∝ value.
Many values at points, dense areas
spikes
Height ∝ value; good for population.
Locations, optionally by category
points
Stores, offices, sightings.
An ordered trip, voyage or itinerary
route
mode: "flight"
uses airport codes.
Movement between places with volume
flows
Migration, trade, flights.
"Where is X?"
locator
Highlight a country, region or place, with an inset globe.
A city or neighborhood as art
poster
Streets from OpenStreetMap; needs network.
Raw counts on a choropleth mostly show which areas are large. Divide by population or area, or switch to
bubbles
. The CLI warns when a value column looks like a count.
用户拥有或需要的内容kind备注
各国、各州、各省或各县的比例或占比
choropleth
使用比率,而非原始计数。
各地点的计数或总量
bubbles
圆面积 ∝ 数值。
点位上有大量数值且区域密集
spikes
高度 ∝ 数值;适合表示人口。
位置,可按类别划分
points
门店、办公室、目击事件等。
有序的旅行、航行或行程
route
mode: "flight"
使用机场代码。
地点之间带数量或体量的移动
flows
迁移、贸易、航班等。
“X 在哪里?”
locator
突出显示国家、地区或地点,并附带插图地球仪。
将城市或社区作为艺术作品呈现
poster
街道来自 OpenStreetMap;需要网络连接。
在分级设色图上使用原始计数通常只会显示哪些区域面积较大。应除以人口或面积,或者改用
bubbles
。当数值列看起来像计数时,CLI 会发出警告。

Spec essentials

规范要点

json
{
  "kind": "choropleth",
  "title": "Where people are packed in",
  "subtitle": "People per square kilometre, by country",
  "data": "builtin:countries",
  "join": "iso3",
  "value": "density",
  "scale": { "type": "threshold", "breaks": [10, 25, 50, 100, 250], "palette": "purple" },
  "legend": { "title": "People per km²" },
  "source": "Natural Earth (2019 estimates)"
}
This one runs as is:
builtin:countries
is bundled.
  • region
    :
    "world"
    (default; Antarctica cropped unless
    "antarctica": true
    ),
    "usa"
    , a continent or area (
    "europe"
    ,
    "africa"
    ,
    "south asia"
    , …), one country (
    "IND"
    ,
    "Brazil"
    ), a list of countries,
    [west, south, east, north]
    , or
    "auto"
    to frame the data.
  • Locations in rows:
    lon
    /
    lat
    ,
    iata
    ,
    place
    (+ optional
    country
    ),
    country
    , US
    state
    , or
    admin1
    +
    country
    . Gazetteer place names cover about 7,300 cities and towns; anything smaller needs
    lon
    /
    lat
    .
  • theme
    :
    paper
    (default),
    atlas
    ,
    ink
    ,
    antique
    ,
    swiss
    ,
    blueprint
    . Posters:
    noir
    ,
    paper
    ,
    blueprint
    ,
    sumi
    ,
    terracotta
    ,
    azulejo
    ,
    neon
    ,
    forest
    ,
    mono
    .
  • size
    :
    landscape
    ,
    wide
    ,
    square
    ,
    portrait
    ,
    story
    ,
    poster
    , or
    { "width": W, "height": H }
    . Default: chosen from the region's shape.
  • annotations
    :
    [{ "at": "Lagos", "text": "Africa's largest city\n15.4 million", "dx": 60, "dy": -40 }]
    .
Everything else, per kind: references/spec.md.
json
{
  "kind": "choropleth",
  "title": "Where people are packed in",
  "subtitle": "People per square kilometre, by country",
  "data": "builtin:countries",
  "join": "iso3",
  "value": "density",
  "scale": { "type": "threshold", "breaks": [10, 25, 50, 100, 250], "palette": "purple" },
  "legend": { "title": "People per km²" },
  "source": "Natural Earth (2019 estimates)"
}
该规范可直接运行:
builtin:countries
已内置。
  • region
    :
    "world"
    (默认;除非设置
    "antarctica": true
    ,否则会裁剪南极洲)、
    "usa"
    、某个洲或区域(
    "europe"
    、
    "africa"
    、
    "south asia"
    等)、单个国家(
    "IND"
    、
    "Brazil"
    )、国家列表、
    [west, south, east, north]
    ,或用于自动取景的
    "auto"
    。
  • 行中的位置:
    lon
    /
    lat
    、
    iata
    、
    place
    (+ 可选
    country
    )、
    country
    、美国
    state
    ,或
    admin1
    +
    country
    。地名库涵盖约 7,300 个城市和城镇;更小的地点需要提供
    lon
    /
    lat
    。
  • theme
    :
    paper
    (默认)、
    atlas
    、
    ink
    、
    antique
    、
    swiss
    、
    blueprint
    。海报主题:
    noir
    、
    paper
    、
    blueprint
    、
    sumi
    、
    terracotta
    、
    azulejo
    、
    neon
    、
    forest
    、
    mono
    。
  • size
    :
    landscape
    、
    wide
    、
    square
    、
    portrait
    、
    story
    、
    poster
    ,或
    { "width": W, "height": H }
    。默认根据区域形状自动选择。
  • annotations
    :
    [{ "at": "Lagos", "text": "Africa's largest city\n15.4 million", "dx": 60, "dy": -40 }]
    。
其他内容因类型而异,请参阅 references/spec.md。

Basemaps (street-level detail)

底图(街道级细节)

The bundled Natural Earth geography is designed for country-scale maps. For streets under the data, add a basemap. Prefer
"streets"
: vector roads, water, parks and buildings coloured by the map's theme, sharp at any size, in any projection, with street and park names on hover in the HTML. No key needed.
json
{ "kind": "points", "basemap": "streets", "theme": "ink",
  "region": { "center": [12.55, 55.68], "radiusKm": 6 } }
Raster presets embed tile images instead:
osm
,
osm-hot
,
light
and
dark
are keyless;
voyager
and the
carto-*
presets need a provider key in a custom URL. They force Mercator. The default budget is 144 distinct tiles;
maxTiles
applies to both kinds.
check
validates configuration without fetching tiles or writing caches. Keep the generated attribution and copyright links visible.
Before choosing a provider, read basemap options and provider terms. OSM, OSM France and CARTO have different access, cache and export requirements; self-contained output does not grant permission for every use. Use your own tile service or a provider permitting your workload for bulk or offline map products.
内置的 Natural Earth 地理数据适用于国家尺度地图。若需要数据所覆盖区域以下的街道信息,请添加底图。优先使用
"streets"
:矢量道路、水体、公园和建筑会按地图主题着色,在任意尺寸和投影下都保持清晰,并且 HTML 中悬停时可显示街道和公园名称。无需密钥。
json
{ "kind": "points", "basemap": "streets", "theme": "ink",
  "region": { "center": [12.55, 55.68], "radiusKm": 6 } }
栅格预设会嵌入瓦片图像:
osm
、
osm-hot
、
light
和
dark
无需密钥;
voyager
和
carto-*
预设则需要在自定义 URL 中提供服务商密钥。它们强制使用 Mercator 投影。默认预算为 144 张不同瓦片;
maxTiles
同时适用于两种底图。
check
会在不获取瓦片或写入缓存的情况下验证配置。请保持生成的署名和版权链接可见。
选择服务商前,请阅读底图选项和服务商条款。OSM、OSM France 和 CARTO 在访问、缓存及导出方面具有不同要求;自包含输出并不意味着可以用于所有场景。对于批量或离线地图产品,请使用自己的瓦片服务,或选择允许此类工作负载的服务商。

Design rules

设计规则

  • The title states the finding; the subtitle says what is measured, where and when.
  • Always set
    source
    . Add
    note
    for caveats (estimates, missing data, borders).
  • 4–6 classes for choropleths. Use
    quantile
    for even groups,
    threshold
    with round breaks when the numbers mean something to readers,
    jenks
    for clusters.
  • Sequential palettes for magnitude; diverging (
    red-blue
    ,
    brown-teal
    , …) only with a meaningful midpoint, set via
    scale.center
    .
  • Do not add Mercator to world maps; the defaults (Equal Earth, conic, azimuthal equal-area, Albers USA) already preserve area. Use
    "projection": "globe"
    for an orthographic view.
  • Label sparingly: the top values, the places the story is about. The renderer drops overlapping labels and lists them in the report.
  • Pick the theme for the audience:
    paper
    or
    swiss
    for reports,
    ink
    for slides and dark UIs,
    atlas
    for reference,
    antique
    for history.
More guidance with examples: references/cartography.md.
  • 标题应点明核心结论;副标题应说明测量内容、地区和时间。
  • 始终设置
    source
    。对于估算值、缺失数据或边界等注意事项,请添加
    note
    。
  • 分级设色图使用 4–6 个分级。
    quantile
    适合创建大小均衡的分组;当数值对读者具有明确含义时,使用带合理整数分界点的
    threshold
    ;
    jenks
    适合识别聚类。
  • 数量级数据使用顺序色板;仅在存在有意义中点时使用发散色板(
    red-blue
    、
    brown-teal
    等),并通过
    scale.center
    设置中点。
  • 不要为世界地图添加 Mercator 投影;默认投影(Equal Earth、conic、azimuthal equal-area、Albers USA)已经能够保持面积。设置
    "projection": "globe"
    可使用正射视图。
  • 谨慎添加标签:仅标注最高值和故事重点地点。渲染器会移除重叠标签,并在报告中列出这些标签。
  • 按受众选择主题:报告使用
    paper
    或
    swiss
    ;幻灯片和深色界面使用
    ink
    ;参考资料使用
    atlas
    ;历史内容使用
    antique
    。
更多指导和示例:references/cartography.md。

Data you can use without fetching anything

无需联网即可使用的数据

  • "data": "builtin:countries"
    gives
    iso3
    ,
    name
    ,
    continent
    ,
    region
    ,
    population
    ,
    gdpMillionsUsd
    ,
    gdpPerCapita
    ,
    areaKm2
    ,
    density
    and
    income
    for every country (Natural Earth, 2019 estimates). Cite it as "Natural Earth (2019 estimates)".
  • find
    looks up anything in the bundled data:
    node <skill-dir>/scripts/map.mjs find "Springfield" --country USA
    .
Datasets, join keys, licenses and border caveats: references/data.md.
  • "data": "builtin:countries"
    提供每个国家的
    iso3
    、
    name
    、
    continent
    、
    region
    、
    population
    、
    gdpMillionsUsd
    、
    gdpPerCapita
    、
    areaKm2
    、
    density
    和
    income
    (Natural Earth,2019 年估算值)。请将其引用为
    "Natural Earth (2019 estimates)"
    。
  • find
    可查询内置数据中的任何内容:
    node <skill-dir>/scripts/map.mjs find "Springfield" --country USA
    。
有关数据集、连接键、许可证和边界注意事项,请参阅 references/data.md。

City posters

城市海报

bash
node <skill-dir>/scripts/map.mjs poster --place "Lisbon" --country PRT --theme azulejo --radius 4
Or a spec with
"kind": "poster"
.
radiusKm
is half the poster's width on the ground: 1.5–3 for an old town (building footprints fill the blocks), 4–6 for a city center, 10–30 for a whole metro as fine street lace. Add
--pin "Label"
(or
markers
in a spec) to mark a spot. Neighborhoods and landmarks need coordinates: ask the user rather than guessing. Posters download OpenStreetMap vector tiles from OpenFreeMap (Overpass as fallback) and cache them. Keep the generated credit: "© OpenMapTiles.org © OpenStreetMap contributors" for vector tiles, or "© OpenStreetMap contributors" for Overpass. The HTML shows hover details for supported features with names in the source data. Details: references/posters.md.
bash
node <skill-dir>/scripts/map.mjs poster --place "Lisbon" --country PRT --theme azulejo --radius 4
也可以使用包含
"kind": "poster"
的规范。
radiusKm
是海报地面宽度的半径:老城区为 1.5–3(建筑轮廓会填满街区),市中心为 4–6,整个都会区为 10–30,以呈现精细的街道网络。添加
--pin "Label"
(或在规范中使用
markers
)来标记位置。社区和地标需要坐标:请询问用户,不要猜测。海报会从 OpenFreeMap 下载 OpenStreetMap 矢量瓦片(以 Overpass 作为回退)并进行缓存。使用矢量瓦片时,请保留生成的版权信息:“© OpenMapTiles.org © OpenStreetMap contributors”;使用 Overpass 时,请保留:“© OpenStreetMap contributors”。HTML 会为源数据中包含名称的受支持要素显示悬停详情。
详情:references/posters.md。

When something goes wrong

出现问题时

  • Could not locate "X"
    : use the suggested match, add
    country
    , or give
    lon
    /
    lat
    .
  • matched no countries feature
    : use ISO alpha-3 codes in the join column.
  • A point "falls outside this projection": Albers USA only covers the 50 states and DC; use
    "region": "auto"
    or a bbox.
  • No PNG: no supported browser was found. Set
    MAP_DESIGN_BROWSER
    to a Chrome or Edge binary, or use the HTML's PNG button.
  • Overpass errors for posters: wait a minute and retry, reduce
    radiusKm
    , or set
    "overpass"
    to another endpoint.
  • Could not locate "X"
    :使用建议的匹配项,添加
    country
    ,或提供
    lon
    /
    lat
    。
  • matched no countries feature
    :在连接列中使用 ISO alpha-3 代码。
  • 点“超出此投影范围”:Albers USA 仅覆盖美国 50 个州和哥伦比亚特区(DC);请改用
    "region": "auto"
    或边界框。
  • 没有 PNG:未找到受支持的浏览器。请将
    MAP_DESIGN_BROWSER
    设置为 Chrome 或 Edge 可执行文件,或者使用 HTML 中的 PNG 按钮。
  • 海报的 Overpass 报错:等待一分钟后重试、减小
    radiusKm
    ,或将
    "overpass"
    设置为其他端点。