☰
2009-2024中国省市县行政区划SHP矢量数据包:从解压到QGIS/ArcGIS实战
2026/10/26 9:41:12 网站建设 项目流程

简介:这份2009至2024年中国行政区划shp矢量数据,完整覆盖省、市、县三级行政单元,采用Shapefile标准格式存储边界与属性信息。数据可直接在ArcGIS、QGIS等GIS软件中加载分析,适用于城市规划、资源管理、地图制图、统计分析、交通物流与市场调研等专业场景。数据包共454个文件,以64个shp矢量文件为核心,配套shx几何索引、dbf属性表、prj坐标参考、cpg字符编码等基础文件,另有xml元数据及sbn/sbx空间索引,压缩包整体约899.13MB,目录按年份与行政层级组织,便于按需调用。该数据集已有271人学习。借助这一跨15年的序列,使用者可追溯县级设立、乡镇合并、地市调整等区划变迁,结合人口、经济、环境等多源数据开展时空分析。矢量格式能保持行政边界的拓扑精确性,适合需要精细空间分析的研究与决策,为区域发展、政策评估及公共服务精准化提供扎实基础。

1. 行政区划 shp 矢量数据包:2009-2024 省市县三级的直接用法

做地图项目的人都知道,行政区划矢量数据是出图、挂数、裁剪的底座。这份 2009-2024 中国行政区划 shp 矢量数据(省市县)7z 压缩包,把十六年间的省、市、县三级面状边界按年份整理好,解压后就能被 QGIS、ArcGIS 直接读取。它解决的不是“有没有数据”的问题,而是“历年区划怎么对齐”的问题——做时间序列分析、统计年鉴挂接、项目选址底图时,不用再满世界找单年份数据拼凑。适合经常做地图制图、空间统计和 WebGIS 底图处理的一线从业者,尤其适合被历年边界变动坑过的老手。

2. 数据包结构与字段说明:解压前先搞清楚文件构成

2.1 省市县三级目录与 shp 配套文件

7z 压缩包的压缩率比 zip 高,对边界数据这种重复度高的矢量文件尤其明显。但 7z 不是 GIS 软件默认直接读取的格式,第一步永远是解压。Windows 下建议用 7-Zip 官方版本打开,打开后右侧压缩文件树可以直接预览包内目录:按年份分目录,2009 到 2024 每一年一个目录,年份目录里再按省、市、县拆成三组 shp。这一步值得花十秒钟,因为从第三方拿到的压缩包偶尔会有目录错位的情况,先看压缩文件树能避免解压完才发现结构不对。

Linux 服务器上我一般用命令行解压:

7za x 2009-2024中国行政区划shp矢量数据(省市县).7z

这条命令里,x 参数表示保留压缩包内的目录结构;如果机器上没装 7za,Debian/Ubuntu 先执行 sudo apt install p7zip-full,CentOS/RHEL 执行 sudo yum install p7zip。这里要特别提醒:不要用 e 参数替代 x。e 会把所有文件平铺解压到当前目录,不同年份、不同级别的同名文件会互相覆盖,比如 county_2020.shp 和 county_2024.shp 如果内部都叫 county.shp,解压出来只剩最后一个,数据包基本就废了。

提示:Windows 下不要用系统自带的右键“压缩文件夹”去解 7z,会直接提示格式不支持,老老实实用 7-Zip。

shp 格式不是一个单文件,而是至少五个文件成套出现。判断数据包是否完整,最快的方法是看每个目录里五件套是否齐全。

| 扩展名 | 作用 | 缺失后的表现 | | .shp | 要素几何主体 | 软件直接提示无法打开 | | .shx | 几何位置索引 | 部分软件报索引缺失,浏览卡顿 | | .dbf | 属性表 | 能出图但属性为空 | | .prj | 坐标系描述 | 软件按未知坐标系处理 | | .cpg | 属性编码声明 | 中文地名乱码 |

从网盘二次转发的数据包最容易丢的是 dbf 和 prj。丢 dbf 的典型症状是能加载出面状图形,但属性表打不开或全是空;丢 prj 的症状是软件强行按默认坐标系加载,位置显示对但面积计算、投影转换全都失真。所以拿到数据后先检查这套文件,比直接拖进 GIS 里再折腾半天更省事。

2.2 核心字段与几何类型:先读懂属性表再动手

行政区划 shp 的属性表设计并不复杂,常见的字段就那么几个。adcode 存 12 位行政区划代码,name 存省市县名称,level 存层级标记,有的版本带 parent_code 用于按省市县做父子挂接。年份一般通过目录区分,属性表里不重复存储;如果某个版本把年份也放进去了,做时间序列分析时更方便。

| 字段名 | 类型 | 说明 | 示例 | | adcode | 字符串 | 12 位区划代码 | 110108 | | name | 字符串 | 名称 | 海淀区 | | level | 字符串/整型 | 1=省 2=市 3=县 | 3 | | parent_code | 字符串 | 上级区划代码 | 110100 |

几何类型统一是 Polygon 面要素。坐标参考常见两种:WGS84 经纬度或 CGCS2000 大地坐标系。这两种坐标系在全国范围数据上经纬度数值差异很小,但面积计算时差异不能忽略。我一直的习惯是:做统计数据或地理处理之前,先把数据投影到 Albers 等积投影,再在投影坐标系里算面积,绝不在经纬度坐标系里拿“度”当长度单位。等积投影的参数后面第 3 章会详细写,这里先记住结论:直接对全国范围的 WGS84 数据算面积,结果只能当参考,不能当统计口径。

parent_code 这个字段对县级数据来说还有一个隐藏风险。某些飞地县和插花地块的上级归属在制图过程中会有跳变,典型如河北三河市的部分地块、天津市在河北境内飞地,如果源数据是按界线自动生成 parent_code,这些地块的父子关系会错。做按市汇总统计时,如果发现某个市的面积明显异常,先查飞地块的 parent_code 是否写的是正确上级,而不是急着怀疑数据包整体有问题。

3. 用 QGIS 与 ArcGIS 打开检查:坐标系、编码与几何有效性

3.1 在 QGIS 里加载 shp 并修复几何

QGIS 加载 shp 的路径是 Layer → Add Layer → Add Vector Layer,选择解压出来的 .shp 文件;新版本也支持直接把 shp 拖到图层区。加载后不要急着出图,先按 F6 打开属性表核对行数。全国县级数据正常是两千多个面要素,省级是三十多个,市级三百多个;如果行数明显偏少或偏多,说明数据包里的文件可能不是同一个版本混放的,需要回到压缩文件树重新核对年份目录。

几何质量检查用 Processing Toolbox 里的 Check validity。这个工具会列出三类高频问题:自相交(self-intersection)、重复顶点(duplicate vertex)、环缺口(gap in ring)。全国数据里最常见的错误是自相交,表现为面要素自己交叉成蝴蝶结形状,面积计算在这种几何上会得出完全错误的值。修复工具是 Fix geometries,它的原理是把无效几何拆成有效子几何再合并。

这里有一个容易被忽略的步骤:修复完还要再跑一次 Check validity。修复过程可能引入新的小碎片要素,尤其是边界上有细长飞地的县。我一般把修复前后的要素数量做一次对比,如果数量变化超过 0.5%,就用 Delete duplicate geometries 清理一遍。对网盘下载的区划数据,这一步属于必做动作,不是可选项。

编码问题也在加载阶段暴露。QGIS 默认按 UTF-8 读 dbf 属性表,如果数据实际是 GBK 编码且 .cpg 文件丢失,name 字段会显示成乱码。解决方法是回到数据源管理器对话框,把 Encoding 手动切换成 GBK 再加载一次。这个操作不需要改源数据,属于读取端设置,对整个项目共享一份数据时尤其好用。另外,资源管理器的预览窗格能看到属性值,编码判断不出来的时候多切两次很快就能看出来,比猜编码省心得多。

3.2 ArcGIS 里定义坐标系与投影转换

ArcGIS 环境下的第一件事是确认 prj 文件存在。如果网盘上下载的数据包丢了 prj,打开后地图单位显示为 Unknown。此时用 ArcToolbox → 数据管理工具 → 投影和变换 → 定义投影来给定坐标系。这里必须分清两个工具:定义投影(Define Projection)只是给数据声明当前坐标系,坐标值不会变;投影(Project)才真正把坐标从一个坐标系换算到另一个坐标系。这两个工具名字相近但职责完全不同,我见过太多人用定义投影去转坐标系,出来的数据叠加后位置偏移一大截,就是这个原因。

判断数据本身是经纬度还是投影坐标,看图层属性的源信息即可。经纬度坐标的横坐标值在 -180 到 180 之间,投影坐标的坐标值通常是几十万到几百万米量级。如果这套多年份数据里有部分年份是投影坐标、部分是经纬度,一定要先统一到同一坐标系再做后续分析,否则相邻年份的边界叠加会差出十万八千里。

全国范围区划数据做投影转换时,我常用的参数是 Albers 等积投影:中央经线 105°E,标准纬线 25°N 和 47°N。这个参数组合在国内底图里非常常见,适合做面积统计和密度分析。操作上用投影工具,输入图层选原始数据,输出坐标系选自定义的 Albers,执行后确认坐标值变化。要注意投影转换不会自动重算面积字段,原来属性表里的面积是旧坐标系的,必须用字段计算器重新算一遍。

3.3 多年份一起加载时的图层管理习惯

十六年份数据全部加载进工程会非常卡,而且默认配色会随机变化,干扰判断。我的习惯是每次只加载两个年份:一个做底图,一个做对比,然后用表达式过滤单独突出某一个县域。比如统计“某个县十年边界变化”时,只需要加载 county_2010 和 county_2024 两个图层,用属性查询过滤 name 字段即可。这样既保留对比上下文,也不会被 16 个同名图层搞昏头。

在 QGIS 里可以用书签工具保存关键范围的视图,ArcGIS 里则用书签或命名视图,避免每次找同一个县都要重新缩放。这个习惯对长时间在多个年份间切换检查的人特别有用,尤其是做区划调整梳理时,频繁在十八年数据里来回跳,没有书签基本就是在浪费时间。

4. 行政区划数据使用避坑:五个高频问题和排查顺序

先说一个原则:这套数据包本身大概率是完整的,真正出问题的是使用方式。下面几条坑按我在项目里的踩坑频率排序,前两条最费时间,后三条属于老手也会偶尔翻车的类型。

4.1 属性表中文乱码:cpg 编码声明丢失

现象:在 QGIS 里打开属性表,name 字段全是乱码,常见的是“鍖椾含”这类双行混乱文本;在 ArcGIS 里表现为字段值显示为问号或空白。

原因:shp 的 dbf 属性表编码常见两种,GBK 和 UTF-8。数据包里的 .cpg 文件如果丢失或写错,GIS 软件无法判断读取编码。QGIS 默认按 UTF-8 读,遇到 GBK 数据就出现乱码。

解决:在数据源管理器把 Encoding 设置为 GBK 重新加载,这是零侵入的临时方案;如果想彻底改好,用文本编辑器打开对应的 cpg 文件改成 UTF-8,并在 GIS 里另存一份统一编码的数据。注意改 cpg 只影响读取声明,不会转换 dbf 里面的实际编码,要真正统一必须做一次另存。

4.2 县界与市界对不齐:跨年份数据混用

现象:把 2020 年的市界和 2015 年的县界叠在一起,边界之间有细缝、有重叠,叠加统计时某个县的面积波动超过 10%。

原因:行政区划在这十六年里经历了大量真实调整。2019 年莱芜并入济南、2011 年巢湖拆分、2017 年雄安新区成立后保定市域内县界重构、近几年多地撤县设区,都会让县界整体变化。不同年份的数据源只要混在一个工程里,边界必然对不齐。

解决:叠加分析统一使用同一年的数据包,不要贪图省事混用。如果业务必须跨年份对比,最低要求是跑一遍父子一致性校验:用县界与市界做交集,检查每个县是否完整落在对应市界内,覆盖率低于 99.5% 的逐条排查。这个校验用 QGIS 的 Join attributes by location 就能做,跑完对照名称字段定位异常县。

4.3 面积计算异常:几何自相交和飞地碎片

现象:字段计算器算面积,个别县的值比地理常识大出好几倍;或者做缓冲区操作时报“几何无效”。

原因:源数据里存在自相交、重复顶点或环缺口。自相交的面要素在面积算法里会被解释成非简单多边形,结果不可信。还有一种情况是飞地碎片,像河北三河市夹在北京和天津之间,边界复杂导致碎面多。

解决:先 Check validity 找出无效要素,再用 Fix geometries 修复。修复后重新检查一次,并用面积字段和行政区代码做联动核对,比如同一 adcode 出现两块不相连的面时,确认是飞地还是重复要素。重复要素用 Delete duplicate geometries 清理,飞地则保留但要单独标记,统计时按主面和飞地合并计算。

4.4 Linux 解压 7z 报错:缺 p7zip 组件

现象:在 Linux 服务器上对 .7z 执行 unzip 直接报“Not a zip archive”,用 tar 也报格式不支持。

原因:7z 是 7-Zip 专有格式,系统自带的 unzip 和 tar 都不认它,需要额外安装 p7zip。

解决:Debian 系执行 sudo apt install p7zip-full,RHEL 系执行 sudo yum install p7zip,装好后用 7za x 解压。这里再强调一次参数问题:x 保留目录结构,e 会平铺文件且同名覆盖,处理按年份分目录的数据包时千万用 x。如果解压过程中看到 skipped 的提示,多半是磁盘空间不够或者文件名编码问题,先 df -h 看空间再排查。

4.5 把 shp 导出成 WKT 或 TXT 后坐标对不上

现象:用 shp 转 txt、shp 导出为 WKT 之后,打开文本看到的坐标不是预期经纬度,数值范围像投影坐标;把文本导入 PostGIS 后位置偏移明显。

原因:导出工具默认按图层当前坐标系输出。如果图层是 Albers 投影,导出的 WKT 就是 Albers 坐标值,不是 WGS84 经纬度。

解决:导出前先明确目标坐标系。在 QGIS 里右键图层 → 导出 → 另存要素,格式选 CSV,CRS 强制选 EPSG:4326,同时勾选生成 WKT 字段;在 PostgreSQL 侧用 ST_GeomFromText 导入,函数第二个参数写 4326。这个顺序不能反,先转坐标系再导出,不要先导出再转文本,否则文本里记录的就是错误坐标。

5. 把区划数据用到真实项目:属性挂接、CAD 转 shp 与渔网裁剪

5.1 将统计年鉴 Excel 挂接到县界面要素

拿到这套区划数据后,最常做的一步是把统计年鉴、人口普查或经济数据挂到面要素上。匹配键是行政区划代码,必须保证两边的 adcode 完全一致。Excel 里的区划代码经常被表格软件自动转成科学计数法,比如 110108 显示为 1.10108E+05,这会导致 join 不上,这是最典型的低级翻车。

用 Python 的 geopandas 处理更可控:

import pandas as pd import geopandas as gpd gdf = gpd.read_file("county_2024.shp") df = pd.read_excel("stats_2024.xlsx", dtype={"adcode": str}) df["adcode"] = df["adcode"].str.zfill(12) merged = gdf.merge(df, on="adcode", how="left") missing = merged[merged["your_value"].isna()] print(f"未匹配条数: {len(missing)}") print(missing[["adcode", "name"]].head())

这段代码的关键点有两个:read_excel 里通过 dtype 参数把 adcode 强制读成字符串,避免科学计数法;merge 用 how="left" 保留全部面要素,缺数据的县会在目标字段里显示为 NaN。这里的 your_value 要替换成统计表里实际要挂的指标列名。如果缺失条数不为零,把 missing 打印出来看是代码不一致还是数据源本身缺该县。

QGIS 里也有对等操作:图层属性 → 连接 → 添加连接,选择统计表,连接字段设为 adcode。但 QGIS 的连接在图层另存后才会真正写入,不另存的话每次打开工程都要重新连接,批量处理十六个年份时脚本更省事。

5.2 从 CAD dwg 转 shp 并做边界对齐

项目里经常会碰到甲方给的用地范围是 dwg 图纸,想和行政区划叠加出图。最常见的问题不是格式转换本身,而是坐标对不齐。dwg 里常见的是建筑坐标系或无投影的当地坐标,和 shp 的经纬度相差成百上千米。直接把 dwg 转成 shp 就叠加,结果一定是“边界在另一个次元”。

标准流程是:先用 CAD 把 dwg 另存为 dxf,保证几何被完整保留;再在 QGIS 里用 DXF 导入插件读取。导入后先找一个已知坐标的参考点做空间对齐,常见做法是在 dwg 里找两个已知经纬度的特征点(路口交叉点、地块角点),在 QGIS 里用 Georeferencer 或手动计算平移参数,把整个 dwg 图层平移到正确位置。平移后再做 dwg 转 shp,边界的形状不会变,位置才可能对上。

这个场景里 dwg 转 shp 只是链路的中间一环,真正的坑在坐标基准。如果你拿到的 dwg 自带正确的地理坐标标注,直接转换即可;如果没有,先对齐再转,别跳过参考点校验这一步。对齐完成后把转换出的 shp 和区划数据叠一次,检查是否有明显的旋转误差,有的话还要补一个旋转参数。

5.3 按行政区裁剪与渔网分割 shp

做局部区域项目时,不需要加载全国数据,裁剪是常规动作。QGIS 里用 Processing Toolbox → 矢量叠加 → 裁剪,输入图层选全国县界,叠加图层选目标市界,运行后得到裁剪结果。要注意裁剪后的属性表仍保留所有字段,做统计前要按名称或 adcode 再做一次过滤,否则会出现全国其他县的历史记录残留。经常有人搜北京 shp、杭州社区 shp,其实用这份全国数据裁剪对应区域就能得到,不用再去网上找来源不明的单市文件。

渔网分割适合做网格化统计。这个场景里我会先检查坐标系:经纬度坐标系下生成的网格单位是度,想要 1 公里网格必须先把数据投影到米制坐标系。正确流程是:用 Create Grid 生成渔网,网格宽度单位选米,再用相交工具把区划面按网格切块。切块后的每个网格块都有原区划的属性,按网格聚合统计时就不会丢范围。

| 参数 | 推荐值 | 说明 | | 网格类型 | 矩形 | 最常用,正方形网格便于统计 | | 网格宽度 | 按业务定 | 单位必须和坐标系投影单位一致 | | 裁剪范围 | 目标市界 | 先裁剪再生成渔网,减少计算量 |

关于网格大小,默认参数往往不适合项目需求,建议先用 5 公里试算一次,再用 1 公里精细跑,对比两次结果差异,确认无明显边界抖动后再全量计算。这一步在人口密度、POI 分布类型项目里尤其重要。

这套数据还有一个隐藏用途是离线底图。很多项目环境不允许访问在线地图服务,用区划数据包作为离线出图的基层是不错的选择。有人搜离线全球矢量数据,其实全球数据的获取和整理成本很高,在中国范围内用这套省市县数据做离线底图反而更贴合业务。渲染时给省界、市界、县界分别设置线宽和透明度,就能得到一张干净的灰度行政底图。

6. 进阶:用 Python geopandas 批量处理十六年份区划数据

最后一个技巧是把这套数据的价值放大:用 geopandas 写一个脚本,批量检查 2009 到 2024 每个年份目录的 shp,修复几何、统一坐标系,最后导出 WKT 文本。这样生成的结果既能交给 PostGIS,也能转成 GeoJSON 给前端,甚至能进一步转 3D Tiles。

import glob import geopandas as gpd from pathlib import Path Path("output").mkdir(exist_ok=True) for year in range(2009, 2025): matches = glob.glob(f"行政区划/{year}/*.shp") if not matches: print(f"{year}: 未找到shp,跳过") continue for shp_path in matches: gdf = gpd.read_file(shp_path) invalid = (~gdf.geometry.is_valid).sum() if invalid: gdf["geometry"] = gdf.geometry.buffer(0) gdf = gdf.to_crs("EPSG:4326") tag = Path(shp_path).stem wkt_path = f"output/{year}_{tag}.txt" with open(wkt_path, "w", encoding="utf-8") as f: for geom, name in zip(gdf.geometry, gdf["name"]): f.write(f"{name}\t{geom.wkt}\n") print(f"{year} {tag}: {len(gdf)}要素, 修复{invalid}个, 已导出{wkt_path}")

这段脚本循环 2009 到 2024 这十六个年份,glob 匹配每个目录下所有 shp,避免漏掉省、市、县任一层级。is_valid 检测无效几何,buffer(0) 是 geopandas 里修复自相交的惯用手段,对绝大多数面要素有效。to_crs("EPSG:4326") 统一坐标系,导出的 WKT 里的点就是经纬度,配合 ST_GeomFromText(text, 4326) 直接写入 PostGIS,字段刚好是 name 和几何体。

这里要注意 buffer(0) 不是万能的,遇到复杂飞地可能还是留下碎面;脚本打印的“修复 N 个”如果 N 很大,建议回到 QGIS 里人工检查对应年份的县界。导出 TXT 后,想要 GeoJSON 就把循环里的写入逻辑改成 gdf.to_file("xx.geojson", driver="GeoJSON"),想要 3D Tiles 就先把 GeoJSON 做要素简化,再用转换工具生成 b3dm 瓦片,全国县界几何节点太多时直接转瓦片会非常慢。

我最早做全国分县人口图时,把 2015 年和 2020 年数据混在一个工程里,结果河北超过一半县的面积对不上,查了一下午才发现是年份混用。从那以后,每次拿到新的区划 shp,我都先让这个批量脚本过一遍几何、编码和字段完整性,再开始干活。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询