<img src="https://github.com/cnmetlab/cnmaps/actions/workflows/python-package.yml/badge.svg" alt="Pytest" />
<img src="https://github.com/cnmetlab/cnmaps/actions/workflows/pypi-publish.yml/badge.svg" alt="Pypi publish"/>
<img src="https://badge.fury.io/py/cnmaps.svg" alt="PyPI version" />
<img src="https://static.pepy.tech/personalized-badge/cnmaps?period=total&units=international_system&left_color=grey&right_color=orange&left_text=Pypi%20Downloads" alt="Pypi Downloads" />
<img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="contributions welcome" />
<img src="https://img.shields.io/badge/code%20style-black-000000.svg" alt="style" />
cnmaps 是一个以中国领土主张为标准开发的地图类 Python 扩展包
安装
安装 cnmaps 需要满足 Python 的解释器在 3.9 版本及以上。
使用 pip 安装
cnmaps 最简单也最快的安装方法是使用 pip:
pip install -U cnmaps
从 2.0.0 开始,官方边界与样例数据已经拆分到独立包 cnmaps-data;安装 cnmaps 时会默认一并安装该数据包,无需再手动准备内置数据目录。
使用 conda 安装
你也可以使用 conda-forge:
conda install -c conda-forge cnmaps
补充说明:conda-forge 当前只维护到 1.1.7 版本;2.x 及后续版本仅发布到 PyPI,conda 发行将停止后续维护。
从源码安装(参与开发)
若需修改源码或运行测试,可在克隆 主仓库 后使用 Poetry 安装依赖:
poetry install
AI Skill
cnmaps 支持安装 AI Skill 描述,可以让 AI 更快、更准确地理解 cnmaps 的常用 API、绘图套路和能力边界。对于习惯用 vibe coding 方式开发、让 AI 协助写科研绘图代码、或希望减少 API 试错成本的用户来说,这份 Skill 可以显著改善上下文质量,让 AI 可以具备流畅使用 cnmaps 各种函数功能的能力。
Note AI Skill 能力仅支持
2.1.x及以上版本。
如果你已经安装了 cnmaps,也可以把这份 AI 指南安装到当前项目目录中,针对不同助手生成对应格式:
cnmaps install-skill codex --mode local
cnmaps install-skill cursor --mode local
cnmaps install-skill claudecode --mode local
如果你想安装到当前用户的全局目录,可以使用:
cnmaps install-skill codex --mode global
cnmaps install-skill cursor --mode global
cnmaps install-skill claudecode --mode global
local 模式下如需指定其他项目目录,可传 --dir /path/to/project。如需覆盖已有安装,可执行:
cnmaps install-skill codex --mode local --force
Note
--mode local会安装到当前项目目录,只会在该安装目录下生效;如果切换到其他项目目录,需要在新的目录里重新安装。--mode global会安装到用户主目录下对应助手的全局路径,通常是$HOME/.claude、$HOME/.cursor、$HOME/.agents等目录,因此跨项目目录也可以生效。cnmaps版本更新后,尤其是 Skill 定义本身有更新时,通常也推荐追加--force重新安装一遍,使本地 Skill 描述与当前版本保持同步。
Tip 目前 Cursor 兼容 Claude Code 的 Skill 定义格式,所以通常来说,如果你已经按
claudecode模式安装了 Skill,Cursor 也往往可以自动识别这一份定义。
快速开始
绘制国界
用最简单直接的方式,来绘制你的第一张中国地图。
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from cnmaps import get_adm_maps, draw_maps
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
draw_maps(get_adm_maps(country='中国', level='国'))
plt.show()

绘制省界
cnmaps还可以绘制各省(特区/直辖市)的地图
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from cnmaps import get_adm_maps, draw_maps
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
draw_maps(get_adm_maps(level='省'), linewidth=0.8, color='r')
plt.show()

绘制市界
cnmaps可以绘制市级的行政区地图。
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from cnmaps import get_adm_maps, draw_maps
fig = plt.figure(figsize=(15,15))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
draw_maps(get_adm_maps(level='市'), linewidth=0.5, color='g')
plt.show()

绘制区县界
cnmaps可以绘制区县级的行政区地图。
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from cnmaps import get_adm_maps, draw_maps
fig = plt.figure(figsize=(20,20))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
draw_maps(get_adm_maps(level='区县'), linewidth=0.8, color='r')
plt.show()

绘制全球国家边界
如果你想快速验证 cnmaps 现在的全球国家级边界能力,可以直接执行下面这段最小示例代码。
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from cnmaps import get_adm_maps, draw_maps
fig = plt.figure(figsize=(14, 7))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree(central_longitude=105))
draw_maps(get_adm_maps(level='国', source='世界银行'), linewidth=0.4, color='#666666')
draw_maps(get_adm_maps(country='中国', level='国'), linewidth=1.0, color='crimson')
plt.show()

命令行导出矢量边界
如果你希望直接在命令行里按筛选条件导出边界文件,可以使用 cnmaps export。它支持与 get_adm_maps 接近的筛选方式,例如 country、province、city、district、level、source、provider、record、simplify 等。
cnmaps export ./jingjin.geojson --province 北京市 天津市 --level 省
cnmaps export ./east-asia.geojson --country 中国 JPN KOR --level 国
cnmaps export ./henan.shp --province 河南省 --level 省 --record first
输出格式默认按文件后缀推断:.geojson / .json 对应 GeoJSON,.shp 对应 ESRI Shapefile。
检查并读取自定义边界文件
如果你有自己的 GeoJSON 或 Shapefile,也可以先把它整理成符合 cnmaps boundary spec 的结构,再交给 cnmaps 检查和读取。
cnmaps check-boundary ./my-boundary.geojson
cnmaps check-boundary ./my-boundary.shp --json # 将检查结果以 JSON 输出
检查通过后,就可以在 Python 代码中读取为 MapPolygon,继续用于 make_mask_array(...)、maskout(...) 或 clip_*:
from cnmaps import read_boundary_file
boundary = read_boundary_file("./my-boundary.geojson")
如果你的原始 shp / geojson 还不符合这套规范,推荐先安装 cnmaps 自带的 AI Skill,再向 AI 发送类似下面的提示词:
帮我把 <path/filename.shp> 转为符合 cnmaps 可识别格式的 shapefile/geojson 文件,并通过 cnmaps 的 check-boundary 检查。
这样 AI 会更容易按 cnmaps boundary spec 整理文件结构;整理完成后,再执行 cnmaps check-boundary ... 验证即可。
使用指南
针对本项目更多的使用方法,我们还有一份更详细的文档:cnmaps使用指南
引用
本项目适用的地图边界的数据源包括:
- GaryBikini/ChinaAdminDivisonSHP: v2.0, 2021, DOI: 10.5281/zenodo.4167299
- The World Bank Administrative Level 0 Boundaries(用于全球国家和地区边界数据)
海拔高度地形数据来自ASTER数字高程模型,并对原始数据进行了稀释。
