
简介这份全国省、县界线shp格式矢量图面向地理信息系统从业者、地图可视化开发者及需要行政区划底图的学生与研究人员解决全国范围内精确到县级的行政边界数据获取问题可用于专题制图、空间分析、区域统计与GIS教学等场景。资源以rar压缩包形式提供整体约14.56MB核心为shp矢量文件配套dbf属性表与shx索引等标准Shapefile组件便于在ArcGIS、QGIS等软件中直接加载与编辑。目前已有1613人学习下载说明其在同类数据中具备一定参考价值。读者可借助该数据快速搭建全国省、县两级行政边界底图省去逐级搜集与拼接的繁琐过程并在此基础上完成区域裁剪、面积量算、分级设色等操作为后续空间统计与可视化表达提供可靠的地理基准。1. 拿到一份县级界线的 shp 文件先别急着往 QGIS 里拖做区域统计、选址分析、配送范围划分的人迟早会撞上同一个需求我需要一份能精确到县级的行政边界矢量图。Excel 里那列「XX 县」看着挺整齐可一旦要落到地图上算面积、做空间叠加、统计每个县的点位密度没有一份靠谱的县级 shp后面全是空谈。这份「全国省、县界线 shp 格式矢量图精确到县区域」解决的正是这件事——它把全国省级和县级两级行政边界整理成标准 shapefile能直接进 QGIS、ArcGIS、GeoPandas 或者 PostGIS。适合谁做区域经济分析的研究生、搞物流网点规划的数据分析师、需要给业务系统配底图的开发以及任何被「县级 地图 shp 区域 行政」这组词折磨过的人。但先别急着拖进软件坐标系和字段没搞明白后面每一步都是坑。2. 拆开 shp 之前坐标系、字段与两级边界的关系2.1 为什么县级边界比省级更容易翻车省级边界粗一个省几十个折点就能画个大概误差肉眼看不出来。县级不一样全国将近三千个县级单元边界要贴着河流、山脊、乡镇界走折点密度高得多。这就带来两个直接后果一是文件体积上去了二是坐标系选错时偏移在县级尺度上会被放大到肉眼可见。常见做法是拿到 shp 第一件事不是打开属性表而是先确认它用的是地理坐标系如 CGCS2000 经纬度还是投影坐标系如 Albers 等积投影。前者适合存储和展示后者适合算面积。如果你要统计各县面积却拿着经纬度坐标直接算得到的数字会随纬度变化而失真这就是很多人第一次做区域统计时「数对不上」的根源。2.2 属性表里到底该看哪几个字段一份合格的全国县级 shp属性表通常包含行政区划代码、名称、所属省级单位、几何类型这几类字段。区划代码是关键它是连接外部数据统计年鉴、人口表、业务库的唯一稳定主键。名称字段反而容易出问题——同名县、名称带「市/区/县」后缀不一致、简称和全称混用都会让按名称关联的脚本在某几个县上静默失败。我一般会先跑一遍代码把字段名和样例值打出来看而不是凭经验假设。import geopandas as gpd # 读取县级 shp注意 encoding 参数中文属性表常见 utf-8 或 gbk gdf gpd.read_file(county_boundary.shp, encodingutf-8) # 看坐标系是经纬度还是投影 print(CRS:, gdf.crs) # 看字段名和前几行确认区划代码字段叫什么 print(gdf.columns.tolist()) print(gdf[[adcode, name]].head()) # 看几何类型县级数据一般是 Polygon 或 MultiPolygon print(gdf.geom_type.value_counts())这段代码的作用是「体检」gdf.crs告诉你坐标系columns告诉你字段命名习惯有的叫 adcode有的叫 code有的叫 XZQHDMgeom_type告诉你有没有海岛县被拆成 MultiPolygon。参数上encoding是最容易忽略的一项中文乱码十有八九出在这里utf-8 读出来是乱码就换 gbk 试。逻辑说明一句先摸清数据长什么样再决定怎么处理比上来就做空间连接稳妥得多。2.3 省级和县级两级边界怎么配合用这份资源同时给了省、县两级很多人只取县级用其实两级配合能省不少事。比如做分省汇总时用省级边界做裁剪或分组比用县级边界 dissolve 上去更快也更不容易因为县级边界的小缝隙导致汇总数字对不上。常见做法是县级做精细统计省级做展示和校验两边数字对不上时问题往往出在县级边界的拓扑缝隙上而不是你的统计算错了。3. 把 shp 用起来从读取、裁剪到区域统计的完整链路3.1 统一坐标系算面积前必须做的一步前面说了经纬度坐标直接算面积会失真。正确做法是先投影到一个等积投影国内常用 Albers 投影参数按全国范围设定。这一步不做后面所有面积、密度指标都不可信。import geopandas as gpd gdf gpd.read_file(county_boundary.shp, encodingutf-8) # 若原始是经纬度EPSG:4490 或 4326投影到 Albers 等积投影 # 参数为全国范围常用设置中央经线 105双标准纬线 25 和 47 albers projaea lat_125 lat_247 lat_00 lon_0105 x_00 y_00 datumCGCS2000 unitsm no_defs gdf_proj gdf.to_crs(albers) # 投影后算面积单位是平方米换算成平方公里 gdf_proj[area_km2] gdf_proj.geometry.area / 1e6 print(gdf_proj[[name, area_km2]].sort_values(area_km2, ascendingFalse).head())参数说明lat_1、lat_2是双标准纬线选在全国纬度跨度内能让形变最小lon_0105是中央经线大致在全国中部datumCGCS2000对应国内常用大地基准。逻辑上to_crs只改坐标不改几何形状area才是真正基于投影平面算的。如果你拿到的 shp 已经是投影坐标这步可以跳过但一定要先print(gdf.crs)确认别想当然。3.2 按区域裁剪只留你关心的那几个县全国数据动辄几百 MB做局部分析时没必要全量加载。常见做法是用一个省或一个市的边界去裁剪或者用矩形框选。裁剪不仅能提速还能避免跨区域的空间关系干扰结果。from shapely.geometry import box # 方式一用矩形框裁剪比如只保留经度 110-120、纬度 30-40 的范围 clip_box box(110, 30, 120, 40) subset gdf_proj[gdf_proj.intersects(clip_box)].copy() # 方式二用某个省的边界裁剪假设你另有一份省级 shp province gpd.read_file(province_boundary.shp, encodingutf-8).to_crs(albers) target province[province[name] 某省] clipped gpd.clip(gdf_proj, target) print(裁剪后县级单元数:, len(clipped))逻辑说明intersects是判断几何是否相交比within宽松能保留边界压线的县gpd.clip会把几何真正切掉适合做精确范围统计。参数上注意裁剪前两边坐标系必须一致否则clip会报错或给出错误结果。这一步的坑在于用矩形框选时压线的县会被整块保留面积统计会偏大要精确就得用clip而不是intersects。3.3 空间连接把业务点位落到县上这是县级 shp 最高频的用法——你有一批带经纬度的点位门店、基站、采样点想知道每个县有多少个。核心是空间连接spatial join把点的坐标转成几何后判断它落在哪个县的多边形里。import pandas as pd from shapely.geometry import Point # 假设业务数据有 lon、lat 两列 df pd.read_csv(points.csv) geometry [Point(xy) for xy in zip(df[lon], df[lat])] points gpd.GeoDataFrame(df, geometrygeometry, crsEPSG:4490) # 统一到同一投影坐标系 points_proj points.to_crs(albers) # 空间连接每个点匹配它所在的县 joined gpd.sjoin(points_proj, gdf_proj[[name, adcode, geometry]], howleft, predicatewithin) # 按县统计点位数量 count_by_county joined.groupby(name).size().reset_index(namepoint_count) print(count_by_county.sort_values(point_count, ascendingFalse).head(10))参数说明predicatewithin表示点必须在县多边形内部才算匹配压在边界上的点可能匹配不上这时可以改用intersects。howleft保证没匹配上的点也保留方便你排查是哪些点落到了数据范围外。逻辑上sjoin之后每个点会带上所在县的名称和代码groupby一聚合就是各县计数。这一步最常见的翻车是坐标系没统一——点用经纬度、县用投影sjoin不报错但结果全空因为两套坐标根本不在一个空间里。3.4 导出与入库shp 之外你还有哪些选择shp 是通用格式但有它的老毛病字段名限长 10 个字符、不支持中文编码存储、单文件超过 2GB 会出问题。如果只是交付给 GIS 软件用shp 没问题如果要进数据库或做 Web 展示常见做法是转成 GeoJSON 或直接入库 PostGIS。# 用 ogr2ogr 把 shp 转成 GeoJSON注意指定编码 ogr2ogr -f GeoJSON -lco ENCODINGUTF-8 county.geojson county_boundary.shp # 导入 PostGIS假设已建好表结构 ogr2ogr -f PostgreSQL PG:hostlocalhost dbnamegis userpostgres county_boundary.shp -nln county_boundary -lco ENCODINGUTF-8逻辑说明-lco ENCODINGUTF-8是图层创建选项保证中文属性不乱码-nln指定入库后的表名。这一步的坑在于 shp 自带的 .cpg 文件如果缺失编码判断会出错转出来的中文可能是问号所以转换前确认 shp 同目录下有 .cpg 文件没有就手动补一个写 UTF-8。4. 避坑与排查县级 shp 处理中最容易栽的五个地方4.1 现象面积算出来比官方数字大一圈原因直接用经纬度坐标算面积或者投影参数选错。经纬度下 1 度对应的实际距离随纬度变化高纬度地区会被严重放大。解决先to_crs到 Albers 等积投影再算并拿几个已知面积的县做校验偏差超过 5% 就回头检查投影参数。4.2 现象空间连接结果全为空原因点和面的坐标系不一致一个经纬度一个投影sjoin不报错但匹配为零。解决连接前统一to_crs并打印两边的crs确认。另一个可能是点的经纬度写反了lon 和 lat 对调这种错误在数据源里很常见。4.3 现象中文属性读出来是乱码原因shp 的编码声明缺失或与实际不符。解决读取时显式指定encodingutf-8 不行换 gbk再不行用chardet探测。转 GeoJSON 时记得加-lco ENCODINGUTF-8否则乱码会带进新文件。4.4 现象按名称关联外部数据总有几个县匹配不上原因同名县、名称后缀不一致、简称全称混用。解决放弃按名称关联改用行政区划代码做主键。如果外部数据只有名称先做一轮名称标准化把「XX市」「XX县」「XX区」的后缀统一再关联。4.5 现象裁剪后面积总和对不上原数据原因用intersects做矩形框选时压线的县被整块保留面积重复计算。解决需要精确面积时用gpd.clip真正切割几何而不是用intersects筛选。另外县级边界之间可能存在微小缝隙或重叠做汇总前可以先dissolve到省级校验总数。5. 进阶技巧用区划代码做稳定关联以及一份可复用的校验脚本县级 shp 用久了会发现真正让分析稳定的不是几何处理多花哨而是主键选得对不对。名称会变、后缀会调、简称会混但行政区划代码在相当长的时间内是稳定的。我现在的习惯是任何外部数据进空间分析前先想办法映射到区划代码映射不上的单独列出来人工确认绝不硬凑。下面这份校验脚本是我每次拿到新 shp 都会跑一遍的覆盖坐标系、字段、几何有效性、面积合理性四个维度import geopandas as gpd def validate_county_shp(path, encodingutf-8): gdf gpd.read_file(path, encodingencoding) report {} # 1. 坐标系 report[crs] str(gdf.crs) # 2. 字段检查确认区划代码和名称字段存在 cols gdf.columns.tolist() report[has_adcode] any(c.lower() in [adcode, code, xzqhdm] for c in cols) report[has_name] any(c.lower() in [name, xzqhmc] for c in cols) # 3. 几何有效性无效几何会导致后续操作报错 invalid (~gdf.geometry.is_valid).sum() report[invalid_geoms] int(invalid) # 4. 空几何 report[empty_geoms] int(gdf.geometry.is_empty.sum()) # 5. 面积合理性投影后最大县不应超过某阈值按实际数据调整 if gdf.crs and gdf.crs.is_projected: areas gdf.geometry.area / 1e6 report[max_area_km2] round(areas.max(), 2) report[min_area_km2] round(areas.min(), 2) return report print(validate_county_shp(county_boundary.shp))这份脚本的价值在于把「凭感觉判断数据能不能用」变成「看几个数字决定」。invalid_geoms不为零就先修复几何再往下走empty_geoms不为零说明有县是空壳max_area_km2异常大往往意味着投影没做对或者混进了省级边界。参数上encoding按实际调整面积阈值按你数据的实际情况设不要照搬。还有一个习惯处理完的县级数据我会单独存一份带区划代码的 GeoPackage.gpkg而不是继续用 shp。GeoPackage 字段名不限长、编码没问题、单文件管理比 shp 那一堆 .shp/.shx/.dbf/.prj 清爽得多。从那以后我每次拿到新的行政边界数据都强制先跑一遍校验脚本、再转一份 gpkg 存档省得下次又在一堆同名文件里找哪个是最新的。希望帮到你。本文还有配套的精品资源点击获取