简介:这份覆盖夏商周至清代二十八个政权阶段的中国历史朝代行政范围矢量数据集,依据谭其骧《中国历史地图集》与历代正史地理志等权威文献数字化重构,包含州府县三级行政边界与37项结构化元数据,专供历史地理研究者、GIS学习者及文化遗产数字化项目使用。压缩包共178个文件,以dbf、shp、prj、shx等GIS标准格式为主,另有证书pdf与说明txt,整体约38MB。目前已有166人学习下载。数据经过拓扑检查,无重叠缝隙,每个朝代独立成层,并区分实际控制区与羁縻地区,可直接用于历史地理教学、丝绸之路复原、古代交通网络重建、军事防御体系研究等场景;属性表含朝代名称、建置时间、治所坐标、今地名对照及考古置信等级,支持叠加分析、时空演变与空间统计,是历史地理与GIS交叉研究的实用基础数据。 做历史地图、区域经济研究、家族迁徙分析的朋友,一定经历过这种尴尬:兴致勃勃想画一张某朝代行政范围图,结果满网找资源,要么是挂在公众号里“点赞过50发网盘”,要么是付费社群里“9.9元拿走”,真要下载下来一看,边界毛糙、属性表缺字段,有的甚至坐标系都是错的,压根没法直接用。
这套中国历史朝代行政范围矢量 SHP 数据,是我花了不少力气从公开学术资源里整理、清洗、配准过的。包含秦、汉、唐、宋、元、明、清等主要大一统朝代的疆域轮廓与省级政区边界,格式为标准 shapefile,可直接拖进 ArcGIS、QGIS、GeoServer 等主流 GIS 软件使用,也可以作为底图叠加现代行政边界做对比分析。这篇就来分享这套数据的真实情况、获取思路、使用时的坑,以及怎么把它玩出花来。
1. 为什么历史朝代矢量 SHP 这么难找:数据现状与真实价值
先说一个反直觉的结论:历史地理领域不缺原始资料,缺的是“能直接用的矢量数据”。谭其骧主编的《中国历史地图集》是绕不开的权威底本,但它本质是纸质地图,8 开本厚厚的几大册,要用就得先扫描、配准、数字化,这一套流程下来,非专业人士基本劝退。
另一个现状是,网上流传的所谓“中国历史朝代 shp 免费下载”,很多其实是同一份数据反复转手。源头多半是海外的 CHGIS(China Historical GIS)项目、CShapes 数据库,或者某些高校课题组的内部成果,传到后来不少被加了水印、改了属性、丢了投影信息。你下载十份,可能有七份是同一个东西,还有三份是坏的。
这套数据我整理时的原则很简单:只认准学术来源,不碰来路不明的“精品资源”。底图以 CHGIS 公开发布的历代政区数据为核心,辅以《中国历史地图集》公开图版的矢量化成果,再用现代行政区划矢量数据做几何校正。所以它在学术引用、宏观趋势分析这种场景下是可靠的,但你要拿它去做村级尺度的历史地名考证,那肯定不行——历史精度达不到那个颗粒度。
数据价值主要体现在三件事上:
- 历史教学与科普制图。做课件配图、公众号历史长图、B站历史疆域变迁视频,这套数据是最省事的底图方案,不需要自己一笔一笔描边界。
- 区域经济史的宏观分析。研究人口迁徙、农业区扩展、交通路网演变时,需要把历代政区作为分析单元,这套 SHP 可以直接挂接统计数据。
- 多源数据叠加。把历史疆域边界叠在现代高程、降水、植被数据上,能快速看出“这个朝代的核心区为什么在这里”,这是纸质地图集做不到的。
我自己常用的是 QGIS + 这套数据的组合,配合时间管理器插件,几行设置就能做出疆域随年代变化的动画,比手动截图再剪辑省太多事了。
2. 真正无套路的数据来源:渠道筛选与质量对比
既然说“无套路分享”,我就不整什么“后台回复关键词获取下载链接”那套了。但我得坦白说,数据是整理过的,可我不能在这里把网盘链接直接扔出来——一方面文件确实不小,另一方面每次更新版本都需要维护,链接很容易失效。所以我给的是比链接更有用的东西:你自己能持续获取、更新、校验的数据渠道,以及我对每个渠道的质量判断。
渠道一:CHGIS 官网。这是哈佛大学与复旦大学合作的学术项目,提供从秦到清的政区变迁数据,版本迭代到 V6,数据质量在同类里是天花板级别。唯一的问题是它从 V4 之后改为注册制下载,而且数据组织方式是“时间切片”,不是“一个朝代一个文件”,需要花点时间理解它的数据模型。研究型用户强烈推荐,出论文引用它绝对站得住脚。
渠道二:CShapes 数据库。这个偏政治学和冲突研究,覆盖 1946 年至今的全球国家边界,粒度太偏现代。如果你只做近现代史(比如民国、共和国初期),CShapes 非常顺手,因为它是 R 语言包直接管理,一条命令就能拉数据,做定量分析极其方便。
渠道三:GitHub 开源项目。搜索“china historical map shp”或“中国历史地图 矢量”能找到不少个人整理的数据仓库,质量参差不齐,但有个好处是能直观看到别人是怎么清洗数据的,对想自己动手处理数据的读者很有参考价值。我建议盯着 stars 多、最近还在更新的仓库,这种通常有人维护、问题反馈响应快。
渠道四:国家基础地理信息中心的 1:100 万公众版数据。这不是历史数据,但它是现代表底的最佳来源,行政边界、河流湖泊、居民地分层清晰,叠加历史疆域时用来做参照物非常好用。
不同渠道的数据质量差异,我整理了一个直接经验性的对比:
| 渠道 | 时间范围 | 坐标参考 | 属性完整度 | 上手难度 | 推荐场景 |
|---|---|---|---|---|---|
| CHGIS V6 | 秦至清 | 经纬度,WGS84 | 完整,含政区沿革 | 中高 | 学术研究、长时段分析 |
| CShapes | 1946 至今 | 经纬度 | 一般,含国家属性 | 低 | 近现代定量分析 |
| GitHub 个人项目 | 杂 | 杂,需自查 | 参差不齐 | 中 | 快速出图、学习处理流程 |
| 国家基础地理信息中心 | 现代 | CGCS2000 / WGS84 | 完整 | 低 | 制图底图、地理配准参照 |
一句话总结:要省事就直接用我整理好的这套,要权威就花时间啃 CHGIS,要灵活就自己攒一套 GitHub 脚本流程。各有取舍,没有万能方案。
3. 拿到 SHP 后的第一步:坐标、编码与属性表的三大坑
不管你是从哪儿弄到的历史 shp 数据,打开之后第一件事不是急着画图,而是先看三样东西:坐标系、属性表编码、文件完整性。这三样任何一个出问题,后面全白干。
坐标系这块最坑。历史疆域数据的原始来源通常有两种坐标:一种是经纬度(WGS84),一种是投影坐标(比如 Asia North Albers Equal Area Conic 或 Lambert Conformal Conic)。如果你直接拿投影坐标的数据去和现代 WGS84 的边界数据叠图,会发现所有要素整体偏移几百米甚至几公里,不明所以的人还以为是历史边界画错了。正确的做法是在 QGIS 里右键图层 → 图层属性 → 信息,先看它标注的 CRS 是什么,再用“导出 → 另存为”时指定目标 CRS 完成重投影,而不是直接修改 CRS 定义。
属性表编码是第二个高频坑。历史数据大多是从中文环境的数据集转出来的,dbf 属性表常用 GBK 编码。你用 QGIS 打开显示正常,但用 ArcGIS 打开就满眼乱码;或者反过来,Python 的 geopandas 读取时默认按 UTF-8 解析,直接抛 UnicodeDecodeError。解决思路其实很粗暴:用 QGIS 重新打开 dbf 时手动指定编码(图层属性 → 数据源 → 编码覆盖),或者在 geopandas 里加 encoding="gbk" 参数。我的经验是,下载任何历史 shp 后先统一做一个“编码标准化的预处理”——把所有属性表转成 UTF-8 再存一份,之后无论用什么工具打开都不闹心。
文件完整性这个问题,很多人会忽略。SHP 不是一个文件,而是一组文件的集合,至少包含 .shp(几何)、.shx(索引)、.dbf(属性),推荐还有 .prj(投影)、.cpg(编码)、.sbn/.sbx(空间索引)。网上有些“精简分享”只传了三件套,丢了 .prj,结果你在 QGIS 里指定不了坐标系,全是未知 CRS。拿到数据先检查文件后缀,缺 .prj 的话也可以根据你对数据源的判断手动指定,但我碰到过太多因为缺 .prj 就误判整个数据坐标系的案例了,所以我的建议是:缺文件的资源宁可不下载,不然后续纠错的成本比你重新找数据还高。
做好这三步检查,数据才算“真正可用”。到这一步才有资格谈制图和空间分析。
4. 历史边界最大的坑:不同朝代同名政区的定位差异
等你能顺利把数据画出来了,真正的专业问题才开始浮现:同名政区在不同朝代之间的位置差异,完全不是一个概念。
最典型的例子是“南京”。明朝的南京(应天府)在今天的南京市区没太大出入,但明朝的“南直隶”大致是今天江苏、安徽、上海一带,而北宋的“南京”却是今天的河南商丘——因为北宋有四京制,南京应天府是陪都之一。如果你把属性表里所有朝代的“南京”字段提出来做地名匹配,不结合时间维度,得到的结果会非常混乱。这就是历史 GIS 与现代表层数据最本质的区别:现代地名的空间位置是固定的,历史地名的空间位置是随时间漂移的。
再比如“州”这一级。唐代的“州”是核心行政区划,疆域小、数量多,一个州大约相当于今天的一两个地级市;而明清的“州”有些是散州,隶属府,有些是直隶州,地位等于府。如果不理解这些制度差异,你拿唐代的州边界去对应明清的州,空间关系完全乱套。
这套 SHP 数据里,我尽量把不同朝代的政区拆分到不同的图层文件里,而不是全部堆在一个文件多个字段里,原因就在这儿。你可以按朝代加载对应图层,避免命名冲突。但在做跨朝代对比时,依然需要中间做一道“地名归一化”的工序:先把所有朝代涉及的目标地名列出来,核对每个地名在各朝代对应的空间范围,再决定分析单元。这一步没有现成工具能自动完成,我在实操中的做法是:先用属性表按“朝代 + 地名”联合搜索(如 select * from layer where dynasty='宋' and name='南京'),把命中的所有要素导出来放到一个临时图层,逐个目视检核位置,再决定是保留还是标记为“歧义地名”。
有个小技巧可以分享:在 QGIS 中给同一组历史地名做跨朝代对比时,不要直接用默认的红色、绿色区分,而要用透明度渐变。先加载唐代图层半透明红色,再叠明清图层半透明蓝色,两者重叠区域会变成紫色,一眼就能看出哪些政区边界在不同朝代剧烈变动、哪些保持稳定。这比逐个点击查看属性高效得多。
5. 从“会打开”到“会展示”:动画、切片与三维扩展
数据能正确显示之后,大部分人的下一个需求是“输出”。结合目前被问爆的几个方向,我把三个高频玩法的关键步骤和避坑点都捋一遍。
玩法一:时间序列动画。用 QGIS 自带的 Temporal Controller(时间控制器)配合这套按朝代分层的 SHP,就能做出疆域变迁动画。关键步骤是把每个图层的时间范围写进属性表(比如 start_year 和 end_year 两个字段,秦朝就写成 -221 和 -206,注意公元前的年份在字段里是负数),然后在时间控制器面板里选择字段,设置动画帧间隔,导出视频时选择“每帧导出图片”,再交给剪映或 ffmpeg 合成视频。我踩过的坑是:忘记给所有图层统一 CRS,结果动画播放到宋代时边界突然跳了一下,原因不是历史数据错,而是该图层还是旧的投影坐标,重投影之后就顺滑了。
玩法二:GeoServer 发布矢量切片。如果你是想做一个在线历史地图站点,或者给前端地图调用,建议把 SHP 转成 GeoJSON 或直接发布为 Vector Tiles。我最顺手的路径是:QGIS 里先把各朝代图层做“按属性拆分”(Split vector layer),得到每朝独立的 GeoJSON;再用 Tippecanoe 把 GeoJSON 打成 .pmtiles 或 .mbtiles 切片;最后放到 GeoServer 的矢量切片扩展里发布。这里有件特别容易翻车的事:切片时如果不对属性字段做压缩(-ai 参数),前端加载时传输体积会大好几倍,历史地图本来就是大量细碎边界,几兆的属性轻松被撑到几十兆。发布前记得用 tippecanoe 的 -ai 去做字段裁剪,只保留 name、dynasty、year 这些核心字段就够了。
玩法三:转 3D Tiles 做三维历史场景。这两年数字孪生、大屏可视化项目里,把历史政区放上三维地球成了刚需,于是“shp 转 3dtiles”需求暴增。工具上直接用 CesiumLab 就能完成:导入 SHP 后设置高度模式(历史疆域一般贴地,用 clampToGround),设置属性字段绑定(用于前端点击弹窗),输出 3D Tiles 目录。这里最大的坑是源 SHP 的坐标系和 CesiumLab 默认的地形坐标系不一致时,生成的瓦片会漂移,我一般是导入前先在 QGIS 里统一重投影成 EPSG:4978(地球坐标系),再交给 CesiumLab,成功率最高。
还有一个出镜率很高的需求是“根据 shp 批量裁剪影像”,比如你想把每个朝代的核心区域对应的现代卫星影像批量裁出来做对比图。ArcGIS 的模型构建器(Model Builder)能很容易实现:遍历图层列表 → 用 Clip 工具按各要素范围裁剪影像 → 输出到独立文件夹。整套流程不涉及写代码,但有一个前置条件:所有要素必须先在同一个坐标系下,且影像数据要先做金字塔构建,否则批量跑一半就会因为金字塔缺失报错中断,这一点很容易在数据量大时被忽略。
6. 两点补充与实际操作建议
数据使用过程中,还有两件事我要单独拿出来说。
第一,这套数据适合做什么、不适合做什么,边界要清楚。它是基于历史文献与测绘成果的整理性数据,空间精度到“政区级”是可靠的,但到了“县界”往下就存在大量推断成分。做宏观历史叙事、教学演示、科普传播、区域尺度量化分析,它完全够用;做精密的地籍式考证、宗族村落级空间重建,你必须去找考古报告和地方志原文交叉验证。期待一套公开的 shp 解决所有历史地理精确制图问题,这不现实。
第二,历史疆域不等于现代边界,制图时务必考虑展示语境。历史朝代的疆域范围和今天的国界没有任何对等关系,不同朝代的实际控制范围也存在学术争议。我在公开场合使用这套数据时,都会在图名或脚注里明确标注“本图仅表示历史时期政区的大致范围,不代表任何现时边界主张”。这不是套话,而是对数据应有严谨态度的体现。
最后说点使用习惯上的建议。这个数据我更新过两版,最大的体会是:不要迷信“下载到就是永久可用”,GIS 数据、软件版本、坐标系规范都在迭代,更重要的是每次使用前检查一遍数据属性、坐标系和几何有效性。我已经养成了固定流程:新数据到手 → QGIS 打开 → 检查 CRS → 跑一次“检查有效性”(Check validity)→ 另存为 UTF-8 编码的工作副本 → 才开始分析。你也照这个顺序来一遍,基本能避开数据本身 90% 的坑。
也希望这份“无套路分享”能真正让你省下那些在无用的营销号资源帖里浪费的时间。数据是工具,能不能讲出历史背后的故事,还得看拿工具的手。
本文还有配套的精品资源,点击获取