简介这份全国县级行政区划shp文件面向GIS从业者、地理信息专业学生及区域研究分析人员提供中国全部县级行政区域的精确边界数据可用于地图制作、人口统计、资源管理、城市规划与灾害响应等空间分析场景。资源包共14个文件约29.94MB以shp、shx、dbf三类核心文件为主分别承载几何边界、空间索引与属性数据另含prj投影文件、xml元数据及sbx、sbn空间索引文件采用GCS_WGS_1984经纬度坐标系可直接在ArcGIS、QGIS等主流软件中打开、查询与叠加分析。目前已有3477人学习下载数据覆盖县、自治县、市辖区、旗、县级市等县级单位属性表包含县名、代码等信息便于筛选统计与投影转换、缓冲区分析等操作是理解中国地理空间格局、开展区域研究与规划的基础数据资源。1. 全国县级行政区划shp文件从数据获取到空间分析的完整落地路径做空间分析的人迟早会撞上一个需求把业务数据挂到县级行政区划上。不管是做门店覆盖评估、物流分区规划还是做人口热力图的底图你都需要一份全国县级行政区划的 shp 文件。这份数据听起来简单——不就是一堆多边形加几个属性字段吗但真正动手找过的人都知道坑从数据获取那一刻就开始了坐标系不统一、行政区划代码对不上、飞地和飞地式边界缺失、属性表里连县名都拼错。我前后折腾过三四套方案从公开渠道下载过、从地图服务里导出过、也自己拼接清洗过最后才摸出一套相对稳定的流程。这篇笔记就是把这套流程拆开讲清楚数据从哪来、字段怎么理解、坐标系怎么统一、怎么和你的业务表做关联、以及那些只有踩过才知道的边界问题。适合已经会用 QGIS 或 ArcGIS 基本操作、但还没系统处理过全国尺度行政区划数据的同学。2. 拿到 shp 文件之后先别急着画图字段、坐标系与拓扑检查2.1 全国县级行政区划 shp 文件里到底有什么一份标准的全国县级行政区划 shp 文件通常包含三类信息几何图形多边形边界、属性字段行政区划代码、名称、层级、以及空间参考信息坐标系定义。属性表里最常见的字段包括adcode行政区划代码、name名称、level层级如 province/city/county、parent上级代码、center中心点坐标等。不同来源的数据字段名可能略有差异但核心逻辑一致用adcode做唯一标识用parent做层级关联。我一般拿到文件后第一件事不是打开地图看而是先看属性表。用 Python 的geopandas读进来打印前几行和字段类型import geopandas as gpd # 读取 shp 文件注意指定编码避免中文乱码 gdf gpd.read_file(county.shp, encodingutf-8) # 查看字段名、数据类型、非空数量 print(gdf.dtypes) print(gdf.head(3)) # 检查 adcode 是否有重复 dup gdf[gdf.duplicated(subsetadcode, keepFalse)] print(f重复的 adcode 数量: {len(dup)}) # 检查几何是否有效 invalid gdf[~gdf.geometry.is_valid] print(f无效几何数量: {len(invalid)})这段代码做了三件事确认字段名和类型、检查adcode唯一性、检查几何有效性。参数上encodingutf-8是关键很多 shp 文件属性表用 GBK 编码读出来中文全是乱码这时候换成encodinggbk再试。duplicated的subset参数指定按adcode判重如果发现有重复说明数据里混入了不同层级的记录需要按level字段过滤。2.2 坐标系不统一是第一个翻车点全国县级行政区划 shp 文件常见的坐标系有三种WGS84EPSG:4326、CGCS2000EPSG:4490、以及 Web 墨卡托EPSG:3857。WGS84 是经纬度坐标单位是度Web 墨卡托是投影坐标单位是米。如果你拿到的文件是 WGS84但业务数据是 Web 墨卡托直接叠加就会错位到十万八千里。统一坐标系的逻辑是先确认源坐标系再转换到目标坐标系。用geopandas的to_crs方法# 查看当前坐标系 print(gdf.crs) # 如果 crs 为空需要手动指定源坐标系 if gdf.crs is None: gdf gdf.set_crs(EPSG:4326) # 转换到 CGCS2000 地理坐标系 gdf_cgcs2000 gdf.to_crs(EPSG:4490) # 如果要做面积计算转成投影坐标系比如 Albers 等面积投影 gdf_albers gdf.to_crs(EPSG:6370) # CGCS2000 / Albers参数说明set_crs只是给数据打上坐标系标签不改变坐标值to_crs才是真正的坐标转换。做面积统计时一定要用投影坐标系经纬度坐标系下算出来的面积单位是“平方度”没有物理意义。我一般用 Albers 等面积投影适合全国尺度。2.3 拓扑检查飞地、缝隙和自相交全国县级行政区划数据最让人头疼的是拓扑问题。常见的有三类自相交一个多边形自己和自己交叉、缝隙相邻县之间有空隙、重叠两个县边界有重叠区域。这些问题在画图时可能看不出来但做空间叠加分析时会导致结果错误。用geopandas做基础拓扑检查# 检查自相交 self_intersect gdf[~gdf.geometry.is_valid] if len(self_intersect) 0: # 尝试修复用 buffer(0) 是常见做法但会轻微改变边界 gdf[geometry] gdf.geometry.buffer(0) # 检查重叠两两求交面积大于阈值的视为重叠 from shapely.ops import unary_union union unary_union(gdf.geometry) if union.geom_type MultiPolygon: print(存在重叠或缝隙需进一步排查)buffer(0)是修复自相交的常用技巧原理是把多边形先向外缓冲再向内缓冲消除自相交点。但它会轻微改变边界形状如果对边界精度要求高建议用make_valid方法Shapely 1.8 支持。重叠检查用unary_union把所有多边形合并如果结果是 MultiPolygon说明有分离的碎片可能是缝隙或重叠导致的。3. 把业务数据挂到行政区划上关联、聚合与空间连接3.1 用 adcode 做属性关联是最稳的方式拿到县级行政区划 shp 文件后最常见的需求是把业务表比如各县的销售额、人口数关联上去。关联键就是adcode。但这里有个坑业务表里的行政区划代码可能是 6 位而 shp 文件里可能是 12 位带省市前缀。需要先统一长度。import pandas as pd # 读取业务表 biz pd.read_csv(biz_data.csv, dtype{adcode: str}) # 统一 adcode 长度取前 6 位 biz[adcode_6] biz[adcode].str[:6] gdf[adcode_6] gdf[adcode].astype(str).str[:6] # 关联 merged gdf.merge(biz, onadcode_6, howleft) # 检查关联率 match_rate merged[biz_value].notna().sum() / len(merged) print(f关联成功率: {match_rate:.2%})参数说明dtype{adcode: str}是关键否则 pandas 会把代码当成数字丢掉前导零。str[:6]取前 6 位是因为县级代码固定 6 位省市前缀不影响县级匹配。关联后用notna().sum()算匹配率如果低于 95%说明代码体系有问题需要排查。3.2 空间连接当业务数据只有经纬度时如果业务数据只有经纬度而没有行政区划代码就需要用空间连接Spatial Join。逻辑是把业务点转成 GeoDataFrame然后判断每个点落在哪个县的多边形内。from shapely.geometry import Point # 业务表有 lon, lat 字段 biz_gdf gpd.GeoDataFrame( biz, geometry[Point(xy) for xy in zip(biz[lon], biz[lat])], crsEPSG:4326 ) # 统一坐标系 biz_gdf biz_gdf.to_crs(gdf.crs) # 空间连接点落在哪个县内 joined gpd.sjoin(biz_gdf, gdf[[adcode, name, geometry]], howleft, predicatewithin) # 检查未匹配的点 unmatched joined[joined[adcode].isna()] print(f未匹配点数: {len(unmatched)})predicatewithin表示点完全落在多边形内部。如果点刚好在边界上可能匹配不到这时候可以用predicateintersects但会带来重复匹配的问题。未匹配的点通常是坐标偏移或落在水域、飞地等特殊区域需要单独处理。3.3 聚合到上级行政区dissolve 的用法有时候需要把县级数据聚合到市级或省级。用dissolve方法按parent字段合并多边形# 按 parent 字段聚合同时求和业务字段 city_gdf gdf.dissolve(byparent, aggfunc{biz_value: sum}) # 重置索引保留 parent 作为列 city_gdf city_gdf.reset_index()dissolve的原理是把相同parent的多边形合并成一个aggfunc指定数值字段的聚合方式。注意合并后的几何可能产生新的自相交建议再做一次buffer(0)修复。4. 避坑指南全国县级行政区划 shp 文件最常见的 5 个问题4.1 现象地图上少了一块某个县不见了原因数据源本身缺失或者该县是飞地几何被错误地合并到了相邻县。解决先用gdf[gdf[name].str.contains(某县)]确认是否存在如果存在但画不出来检查几何类型是否为 Polygon 或 MultiPolygon以及is_valid是否为 True。4.2 现象adcode 关联后大量为空原因业务表的 adcode 是 6 位shp 文件是 12 位或者反过来。解决统一截取前 6 位再做关联。另外注意有些数据用code而不是adcode作为字段名需要先重命名。4.3 现象面积计算结果明显偏大或偏小原因在经纬度坐标系下直接算面积。解决先to_crs转到投影坐标系推荐 Albers 等面积投影EPSG:6370 或自定义参数。如果只是做相对比较也可以用gdf.geometry.area在投影坐标系下计算。4.4 现象空间连接时一个点匹配到多个县原因点落在边界上或者数据存在重叠区域。解决用predicatewithin替代intersects或者对匹配结果按距离排序取最近的一个。如果数据本身有重叠需要先做拓扑修复。4.5 现象中文属性表乱码原因shp 文件的.dbf文件编码不是 UTF-8。解决读取时指定encodinggbk或encodinggb18030。如果还是乱码用QGIS打开后另存为 UTF-8 编码的 GeoJSON再用geopandas读取。5. 进阶技巧用 GeoPandas 做县级行政区划的批量出图与自动化校验5.1 批量出图每个县一张图做汇报时经常需要每个县单独出一张图。用matplotlib循环绘制import matplotlib.pyplot as plt # 按省分组每个省出一张图 for province, group in gdf.groupby(parent): fig, ax plt.subplots(figsize(10, 8)) group.plot(axax, columnbiz_value, legendTrue, cmapOrRd, edgecolorgray, linewidth0.5) ax.set_title(fProvince {province} County-Level Data) ax.axis(off) plt.savefig(foutput_{province}.png, dpi150, bbox_inchestight) plt.close()groupby(parent)按上级代码分组columnbiz_value指定着色字段cmapOrRd是颜色映射方案。bbox_inchestight去掉多余白边。注意如果某个省的数据量太大出图会很慢可以先用simplify简化几何gdf[geometry] gdf.geometry.simplify(tolerance0.01, preserve_topologyTrue)tolerance是简化容差单位是度经纬度坐标系下。preserve_topologyTrue保证简化后不会产生自相交。5.2 自动化校验每次更新数据后跑一遍数据更新后手动检查容易漏。我一般写一个校验脚本每次更新后自动跑def validate_county_shp(gdf): 校验县级行政区划 shp 文件的完整性 errors [] # 1. 检查 adcode 唯一性 if gdf[adcode].duplicated().any(): errors.append(adcode 存在重复) # 2. 检查几何有效性 if not gdf.geometry.is_valid.all(): errors.append(存在无效几何) # 3. 检查坐标系是否定义 if gdf.crs is None: errors.append(坐标系未定义) # 4. 检查是否有空几何 if gdf.geometry.is_empty.any(): errors.append(存在空几何) # 5. 检查 adcode 长度是否一致 if gdf[adcode].astype(str).str.len().nunique() 1: errors.append(adcode 长度不一致) return errors # 使用 errors validate_county_shp(gdf) if errors: print(校验失败) for e in errors: print(f - {e}) else: print(校验通过)这个校验函数覆盖了 5 个最常见的坑重复代码、无效几何、坐标系缺失、空几何、代码长度不一致。每次拿到新数据先跑一遍能省掉后面很多返工。5.3 一个我踩过的坑别用 buffer(0) 修复所有几何早期我图省事所有几何问题都用buffer(0)修复。后来发现buffer(0)会把一些细长的多边形“压扁”导致面积变化超过 5%。对于做面积统计的场景这是不可接受的。正确的做法是先用make_valid尝试修复如果还不行再手动检查具体是哪个县出了问题。make_valid是 Shapely 1.8 引入的方法能更好地保留原始几何形状。from shapely.validation import make_valid # 只对无效几何做修复 invalid_mask ~gdf.geometry.is_valid gdf.loc[invalid_mask, geometry] gdf.loc[invalid_mask, geometry].apply(make_valid)这个习惯帮我省了很多后悔药。每次处理行政区划数据先跑校验再针对性修复最后再跑一遍校验确认。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?