
简介全国县级行政区划shp文件是GIS领域常用的基础地理数据面向地理信息专业学生、规划人员及数据分析师用于获取中国县级行政单元的精确边界。Shapefile基于Esri标准格式由几何、属性、索引三类子文件协同工作本资源共14个文件覆盖.shp、.dbf、.shx核心类型并附prj坐标投影、xml元数据、sbx/sbn空间索引等辅助文件压缩包整体29.94MB。数据采用GCS_WGS_1984坐标系经纬度表示便于在ArcGIS、QGIS等平台直接加载覆盖县、自治县、市辖区、旗等各类县级单位配合属性库中的县名、代码等信息可实现叠加分析、缓冲区分析、人口统计、城市规划等应用也可与人口密度、交通网络等图层联合做空间决策。已有3477人学习下载适合在地图制图、政策规划、灾害响应等场景中作为基础底图使用。资源内含县级面状与线状要素并支持标准格式互操作可显著降低边界数据采集与配准成本。1. 全国县级shp文件——为什么很多项目会卡在边界底图上县级shp文件听起来不过是一个矢量压缩包但真拿去做叠加分析和面积统计时坐标系定义、属性表编码、相邻边界版本差异三个环节随便踩中一个返工成本都会成倍上升。最常见的开局是解压后把shp直接拖进ArcGIS或QGIS看起来毫无问题换一张底图或统计字段后错位、乱码、面积对不上全部冒出来。这篇笔记围绕一份全国县级行政区划shp资源包按“体检→转换→避坑→进阶”的顺序逐层拆解新手能照着操作有经验的GIS开发者也能直接对照参数清单快速落地。2. 拿到shp先做数据体检坐标系、属性结构与版本口径2.1 打开文件前先看坐标系地理坐标与投影坐标的差别一个完整的shapefile至少包含三个伴随文件.shp存储几何、.shx存储空间索引、.dbf存储属性。压缩包里通常还有.prj和.cpg这两个文件最容易被人忽视却恰恰决定了数据能不能直接用。如果解压出来根本没有.prj说明源数据在导出时没有携带坐标定义后续按压“未知坐标系”处理而不是默认它和当前地图一致。第一步不是拖进软件而是用Python读取元数据from pyogrio import read_info info read_info(全国县级.shp) print(info.crs) # 坐标系统名称或EPSG编号 print(info.encoding) # 属性表编码常见GBK或UTF-8 print(info.bbox) # 数据范围用于判断是否经纬度逻辑说明read_info()返回的是shapefile的元数据不加载几何体适合快速体检。crs能直接告诉我们坐标系encoding能提前预判属性表是否会出现乱码bbox则用来核对数据范围是否符合预期。参数说明crs如果返回None说明缺少.prj文件bbox如果返回类似[73, 18, 135, 53]这样的范围说明是经纬度地理坐标如果返回米制的大数值比如[13400000, 3500000]说明已经是投影坐标。拿到数据后先分清三种常见坐标形态坐标系类型特征面积计算经纬度地理坐标bbox在-180到180之间不能直接算面积高斯克吕格投影bbox带带号单位为米可选择中央经线带投影Web墨卡托bbox数值上千万单位为米高纬度区域面积明显偏大判断要点如果资源包是给WebGIS前端用的转成Web墨卡托或者EPSG:4326都行如果用于统计面积、国土底图一定要保留或转换为国家大地坐标系不要在Web墨卡托上直接算面积。2.2 属性表结构区划代码、名称字段怎么读县级shp的属性表最常见的字段是省名、市名、县名、区划代码。不同来源字段名差异很大有的叫NAME、CITY、PROVINCE有的叫XZQMC、XZQDM初看很乱但核心就两类名称类和代码类。用GeoPandas看一下表结构import geopandas as gpd gdf gpd.read_file(全国县级.shp, encodingGBK) print(gdf.columns.tolist()) print(gdf.head(5)) print(gdf[XZQDM].str.len().value_counts())逻辑说明第一行打印全部字段名第二行预览前5行数据第三行统计区划代码字段的位数分布。参数说明encodingGBK是老数据的常用编码如果属性中文读取正常说明编码匹配如果出现乱码改成encodingutf-8再试。代码长度分布很有参考价值6位是标准县级代码9位或12位往往包含了更细的乡级代码扩展。属性表里经常混入特殊情况例如“省直辖县级行政单位”“直辖市下辖县”等。如果只是做可视化保留这些记录没问题如果要做省级统计建议先按省名字段做分组再检查每个省的县级数量是否异常避免把县级代码与乡级代码混在一起计算。2.3 旧版与新版边界版本口径怎么识别县级行政边界每年都可能调整有的是撤县设区有的是乡镇合并。两个不同年份的shp放在一起做跨期对比时不能直接叠加因为版本口径不同边界已经变了。对比版本差异可以用代码自动筛查import geopandas as gpd new_df gpd.read_file(新版全国县级.shp, encodingutf-8) old_df gpd.read_file(旧版全国县级.shp, encodinggbk) diff set(old_df[XZQDM]) - set(new_df[XZQDM]) print(len(diff), 个代码在新版中不存在)逻辑说明用集合差集找出“旧版有、新版没有”的区划代码数量越多说明这段时间区划调整越大。参数说明XZQDM是代码字段名不同资源包字段名不同请替换为实际字段encoding参数按数据源编码调整。真正做跨年份分析时最稳妥的做法是统一使用新版边界旧数据只保留统计属性不保留旧边界线。否则两张图边界对不齐最后做出来的图表会带有肉眼可见的接缝误差。3. 落地转换实操重投影、多格式输出与DWG融合3.1 重投影把来自不同口径的shp规范到统一坐标系项目里最常见的情况是拿到的全国县级shp是WGS84地理坐标而数据库或地图服务要求CGCS2000。坐标转换用GDAL一行命令解决ogr2ogr -s_srs EPSG:4326 -t_srs EPSG:4490 -lco ENCODINGUTF-8 \ 全国县级_cgcs2000.shp 全国县级.shp逻辑说明-s_srs指定源坐标系-t_srs指定目标坐标系-lco ENCODINGUTF-8在输出shapefile时把属性编码统一成UTF-8避免后续再处理乱码。参数说明WGS84对应EPSG:4326CGCS2000地理坐标对应EPSG:4490。如果源数据本身缺.prj必须手动加-s_srs参数否则转换结果会产生系统性偏移。GDAL转换时默认会做动态坐标系换算WGS84转CGCS2000这种地理坐标之间的转换偏差很小。但要注意高斯克吕格投影的情况例如带号为3度分带的CGCS2000投影要根据中央经线选择对应的EPSG编号。选错带号不会报错只会让整个图平移几百米。Python中对应写法import geopandas as gpd gdf gpd.read_file(全国县级.shp, encodinggbk) gdf gdf.to_crs(EPSG:4490) gdf.to_file(全国县级_cgcs2000.shp, encodingutf-8)逻辑说明to_crs(EPSG:4490)完成重投影to_file导出为新的shapefile。参数说明to_crs只改变几何坐标不影响属性表内容。导出时指定encodingutf-8但后续用其他软件打开时如果软件默认按GBK读取仍可能显示乱码这是读取端的问题不是数据文件的问题。3.2 多格式输出GeoJSON、WKT、TXT与CSV县级shp经常要转给前端或数据库使用。GeoJSON是Web端通用格式WKT适合写进SQL数据库做空间字段CSV适合做数据分析脚本的输入。批量输出三份文件ogr2ogr -f GeoJSON 全国县级.geojson 全国县级.shp ogr2ogr -f CSV 全国县级_wkt.csv 全国县级.shp -lco GEOMETRYAS_WKT逻辑说明-f GeoJSON直接输出前端可加载的GeoJSON-f CSV加GEOMETRYAS_WKT把每个面的几何体写成WKT字符串方便后续在PostgreSQL或其他空间数据库中解析。参数说明CSV文件里如果包含完整多边形WKT文件会比较大适合小范围或筛选后的数据不适合直接拿全国几十万县级面导出成CSV。如果项目需要把shp坐标导出为纯文本用pyshp处理比较直观import shapefile sf shapefile.Reader(A县.shp, encodinggbk) with open(A县边界.txt, w, encodingutf-8) as f: for rec in sf.iterShapeRecords(): name rec.record[NAME] pts rec.shape.points f.write(f{name}:{pts[0][0]:.6f},{pts[0][1]:.6f}\n)逻辑说明iterShapeRecords()逐个读取几何和属性这里只写了每个面第一个点的坐标演示“shp转txt”的一种实现思路。参数说明实际项目中如果要把完整边界导出为文本建议循环所有点并在每个环结束后写入换行符。但文本格式缺少拓扑结构后续做空间分析时远不如GeoJSON或WKT可靠。3.3 DWG转shp把规划图纸接进县级底图DWG转shp是规划类项目里逃不开的步骤。施工图、规划图、地籍图里大量是CAD格式要跟县级shp叠加需要先转成矢量面。ogr2ogr直接读DWG时很多GDAL版本并不支持常见做法是先把DWG另存为DXF再执行转换ogr2ogr -f ESRI Shapefile 规划地块.shp 规划图.dxf -where LayerJMD逻辑说明-where LayerJMD表示只导出图层名为JMD的要素避免CAD里的注记文字、辅助线、填充线全部混进shp。参数说明不知道图层名时先用ogrinfo 规划图.dxf -so -al查看所有图层名再决定过滤条件。真正麻烦的不是文件格式而是图纸坐标。很多CAD图纸的原点是图纸内部相对坐标不是实地位置转出来的shp范围对不上底图。遇到这种情况先在CAD里找两个已知控制点在QGIS中用“地理配准”做仿射变换或者让CAD导出DXF前把坐标系统设置成实地坐标。经验是大部分“DWG转shp之后错位”的问题不是转换步骤错了而是源图纸坐标就没对齐。4. 避坑指南坐标错位、属性乱码与接边缝隙排查4.1 边界整体偏移单独看正常放到底图就露馅现象单独在ArcGIS里打开县级shp图形显示完全正常但叠加在线影像或标准底图后整个边界平移了几十米甚至几百米。原因最常见的两种情况。一种是shp本身是地理坐标底图是Web墨卡托视图空间发生动态投影边界虽然画出来了但位置对应不上另一种是原数据缺少.prj文件软件默认按WGS84加载而数据实际是CGCS2000两个坐标系之间的差异会被当成平移误差。解决先在QGIS图层属性里确认当前CRS。如果确实缺.prj不要靠猜用已知点判断坐标系后执行“定义投影”修复再做重投影ogr2ogr -t_srs EPSG:3857 全国县级_web.shp 全国县级.shp逻辑说明-t_srs EPSG:3857把数据转为Web墨卡托适合在线底图叠加。但这行命令要求源文件有正确的坐标定义如果源坐标就是错的转完还是错位。4.2 属性表乱码GBK老编码被当成UTF-8读现象在QGIS中打开属性表字段名或中文名称显示成乱码类似“ʡ”或“?????”。原因早期制作shp大多用GBK编码写.dbf属性而GDAL 3.x版本默认按UTF-8读取读出来的字节串变成乱码。这个问题在中文GIS数据里非常普遍。解决读取时指定编码最简单的方式是GeoPandas加参数import geopandas as gpd gdf gpd.read_file(全国县级.shp, encodinggbk) gdf.to_file(全国县级_utf8.shp, encodingutf-8)逻辑说明encodinggbk保证读出来是正确的中文再输出成UTF-8编码的新shp从源头解决后续所有软件的编码兼容问题。参数说明如果encodinggbk仍乱码可以试gb2312或cp936三者本质相同但兼容范围有细微差异。转码时机越早越好等数据已经写进GeoJSON再处理麻烦会翻倍。4.3 相邻县域接边出现缝隙或重叠现象放大两个相邻县的边界中间出现一条窄窄的空白带或者两条边界交叉出一个小三角。原因相邻县域的shp可能来自不同数据源的矢量化结果边界虽然在属性上相邻但几何坐标没有完全重合。县级边界从省级边界裁切时也可能因为不同批次比例尺不同导致接边不齐。解决如果项目只需要显示可以用对称Buffer做微小修正import geopandas as gpd gdf gpd.read_file(全国县级.shp) gdf[geometry] gdf.geometry.buffer(0.0001).buffer(-0.0001) gdf.to_file(全国县级_clean.shp, encodingutf-8)逻辑说明先向外扩张0.0001度再向内收缩0.0001度能把细小缝隙“抹平”代价是边界会有一点轻微变形。参数说明0.0001度大约对应10米左右适用于低精度可视化。如果做面积统计或精度要求高的项目不要用这个方法应该直接找原始数据源重新接边。另外如果把县级shp转成3dTiles发布这类微小缝隙在Web端往往不可见优先保证整体拓扑合理即可。4.4 面积统计偏大用投影坐标平面面积当真实面积现象在属性表中计算某县面积结果比公开资料大了接近一倍。原因数据是Web墨卡托投影高纬度地区投影面积被放大。直接用投影坐标计算多边形面积得到的是平面投影面积不是椭球面积。解决如果是全国范围的数据推荐直接用PostGIS算地理类型面积SELECT name, ST_Area(geom::geography) / 1e6 AS area_km2 FROM county;逻辑说明geom::geography把几何体转成地理类型PostGIS会自动用椭球模型计算面积不需要关心投影带。参数说明如果只能在Python里做也可以对每个县按其中心点选择最近的UTM带动态投影再计算面积。全国范围不要只固定用一个UTM带否则跨带区域误差会非常大。5. 进阶技巧用渔网网格把县级shp和DEM做统计5.1 用shp范围生成渔网网格县级shp往往是大面积面做生态评价或地形分析时直接对整个县统计指标太粗糙常见做法是先切成规则渔网再以网格为单位提取统计值。用Python生成并裁剪渔网import geopandas as gpd import numpy as np from shapely.geometry import box gdf gpd.read_file(A县.shp).to_crs(EPSG:3857) minx, miny, maxx, maxy gdf.total_bounds cell 1000 # 网格边长单位米 xs np.arange(minx, maxx, cell) ys np.arange(miny, maxy, cell) grids [box(x, y, x cell, y cell) for x in xs for y in ys] grid gpd.GeoDataFrame(geometrygrids, crsEPSG:3857) grid gpd.overlay(grid, gdf, howintersection)逻辑说明先转成米制投影再按固定步长生成规则方块最后用overlay把超出县界的网格裁掉。参数说明cell1000是1公里网格实际项目中也可以设成500或2000网格越小计算量成倍上升。如果县界范围很大生成网格数量可能超过数万建议先用total_bounds估算网格数量再决定是否调整边长。5.2 把DEM数值统计到渔网网格网格生成后叠加DEM提取每个格网的高程统计值from rasterstats import zonal_stats stats zonal_stats(网格.shp, dem.tif, statsmin mean max std) grid[elev_mean] [s[mean] for s in stats] grid[elev_std] [s[std] for s in stats]逻辑说明zonal_stats把每个网格与DEM像元对齐按网格边界聚合出最小值、均值、最大值和标准差。参数说明dem.tif必须与网格使用同一坐标系否则统计结果会是空值。如果坐标系不一致先用gdf.to_crs()把网格投影转到DEM坐标系再执行统计。这个流程在山地、丘陵项目中非常稳定。网格级别的高程均值和标准差能把“平均海拔”和“地形起伏程度”同时量化适合做灾害风险初筛和国土空间规划的高程分带统计。ArcGIS里也有对应的“分区统计”工具而上面这套命令更适合批量处理多个县。从那以后我每次拿到一份新的县级shp资源包都会强制走一遍“元数据体检→投影统一→编码确认→接边缝隙检查”四步再进入项目流程。这套流程帮我挡掉了大量无谓返工希望帮到你。本文还有配套的精品资源点击获取