
简介这份2024年安徽省村级居委会行政区划shp数据集面向从事GIS分析、城乡规划、人口统计与基层治理研究的人员提供覆盖省、市、县、乡、村五级行政边界的矢量数据可直接用于空间制图、区域统计与专题分析。压缩包共34个文件约217.02MB以shp、shx、dbf、prj等Shapefile核心文件为主分别承载几何图形、索引、属性表与投影信息另含xml、sbx、sbn等辅助文件便于在ArcGIS、QGIS等平台直接加载。属性字段包含village、town、district、city、province可逐级关联村、乡镇、县、市、省名称满足多尺度汇总需求。坐标系为WGS1984便于与常见在线底图和GPS数据叠加。目前已有253人学习下载适合需要最新村级边界底图、开展基层空间分析或搭建行政区划数据库的读者参考使用。1. 安徽省村级行政区划 shp 数据集一份能直接落到 GIS 里的基层边界底图做安徽省内某个县、某个乡镇甚至某个村的项目时最容易被卡住的往往不是分析模型而是底图。省市县三级的 shp 到处都能找到但一落到「村级居委会」这一层很多人就开始翻车要么只有名字没有边界要么边界是示意性的要么属性表里连行政区划代码都缺。这份「2024年安徽省村级居委会行政区划 shp 数据集」解决的正是这个问题——它把安徽全省的村和居委会两级基层单元以矢量边界加属性表的形式组织起来能直接拖进 QGIS、ArcGIS 或者用 GeoPandas 读进来做空间统计、制图和叠加分析。它适合谁做国土空间规划、乡村振兴专题图、人口与经济数据下沉到村、快递网点选址、应急物资投放范围测算的从业者以及需要把民政统计口径落到地图上的数据分析人员。前提是你得懂一点坐标系和属性表字段的含义否则拿到手也只是一堆打不开的线。下面按「先搞清是什么、再动手读、再避坑、最后进阶」的顺序讲透。2. 村级 shp 到底装了什么图层结构、字段与坐标系选型2.1 村级边界和省市县边界不是一回事很多人以为行政区划 shp 就是一套东西无非层级不同。实际差别很大。省市县边界是「行政管辖范围」边界线相对规整一个县就是一个闭合多边形。村级边界是「实际管理单元」它的形状高度不规则一个村可能被河流、山脊、公路切成好几块形成多部件多边形MultiPolygon城中村的居委会边界可能只有几百米见方而皖南山区的村可能横跨十几公里。这意味着你在处理时不能假设「一个要素就是一个简单多边形」必须考虑多部件和飞地。另一个关键点是属性。省市县 shp 通常带行政区划代码如 340102 这种六位码村级则一般带 12 位或更长的村级代码外加村名、所属乡镇、所属区县。如果这份数据里没有村级代码只靠村名做关联那在重名村安徽叫「王村」「李村」的太多了上必然出错。所以拿到数据第一件事不是画图是看属性表。2.2 图层结构与字段清单一份规范的村级 shp 通常包含这几个文件.shp几何、.shx索引、.dbf属性表、.prj坐标系定义、.cpg字符编码。缺了.prj坐标系就得自己猜缺了.cpg中文村名可能乱码。字段方面常见的是下面这套具体以你拿到的数据为准字段名含义典型值注意点NAME村/居委会名称双岗村可能带「村」「社区」「居委会」后缀CODE行政区划代码34012310xxxx位数决定层级别截断TOWN所属乡镇/街道双岗镇用于分组统计COUNTY所属区县长丰县与市级数据对齐CITY所属地市合肥市便于筛选TYPE单元类型村/居委会决定后续口径提示字段名大小写在不同数据里可能不一致读进来后先统一转成小写再处理能省掉一堆 KeyError。2.3 坐标系怎么选CGCS2000 是底线安徽的村级数据常见做法是地理坐标系用 CGCS2000EPSG:4490投影坐标系用 CGCS2000 3 度带高斯克吕格比如中央经线 117°E 对应 EPSG:4547 一带。为什么强调这个因为如果你要算面积、算距离用经纬度直接算出来的「度」没有物理意义。正确流程是存储和交换用地理坐标系做面积/距离统计前投影到对应带的高斯克吕格。选带的原则是按数据覆盖范围的中心经线来。安徽跨了 115°E 到 119°E 左右如果全省一起算用一个带会有边缘变形但村级尺度下影响可接受如果只做某一个市就选该市对应的带。这一步选错后面所有面积数字都是错的而且错得不明显——这是最坑的地方。3. 用 GeoPandas 把 shp 读进来并跑通第一次统计3.1 环境准备与最小读取命令先装依赖。GeoPandas 依赖 GDAL直接 pip 装有时会出问题稳妥做法是用 conda 建环境conda create -n ah_village python3.11 conda activate ah_village conda install -c conda-forge geopandas matplotlib装好后最小读取代码如下。注意encoding参数中文属性表乱码基本都出在这里import geopandas as gpd # 读取村级 shp指定编码避免中文乱码 gdf gpd.read_file(安徽省村级行政区划.shp, encodingutf-8) # 看坐标系、要素数量、字段 print(gdf.crs) # 应为 EPSG:4490 或类似 print(len(gdf)) # 村级单元总数 print(gdf.columns.tolist()) print(gdf.head(3))逻辑说明read_file会自动读取同目录下的.prj和.dbf。如果gdf.crs打印出None说明.prj缺失或损坏这时不能直接做空间运算得先手动设定坐标系。len(gdf)是要素数正常应接近安徽村级单元的实际数量级。参数上encoding优先试utf-8乱码就换gbk这是血泪经验。3.2 投影转换与面积统计拿到数据后做一次投影再算每个村的面积# 投影到 CGCS2000 3 度带以 117E 为例EPSG:4547 gdf_proj gdf.to_crs(epsg4547) # 面积单位是平方米转成平方公里 gdf_proj[area_km2] gdf_proj.geometry.area / 1e6 # 按区县汇总面积检查是否合理 summary gdf_proj.groupby(COUNTY)[area_km2].sum().sort_values(ascendingFalse) print(summary.head(10))逻辑说明to_crs做投影变换geometry.area在投影坐标系下才有物理意义。除以 1e6 是把平方米转平方公里。按区县汇总后数值应该和该区县公布的行政面积大致吻合偏差过大说明投影带选错或边界有重叠。参数上EPSG 码要和你数据实际覆盖的经度带匹配别照抄。3.3 属性表清洗与重名村处理村级数据最常见的脏数据是重名和空值。清洗思路# 去掉名称为空的记录 gdf gdf[gdf[NAME].notna() (gdf[NAME].str.strip() ! )] # 用「区县乡镇村名」构造唯一键避免重名 gdf[uid] gdf[COUNTY].astype(str) _ gdf[TOWN].astype(str) _ gdf[NAME].astype(str) # 检查唯一键是否有重复 dup gdf[gdf[uid].duplicated(keepFalse)] print(f重复键数量: {len(dup)})逻辑说明单靠村名做关联在安徽几乎必错构造复合键是标准做法。duplicated(keepFalse)会把所有重复项都列出来方便你判断是数据本身重复还是命名冲突。如果重复量大说明数据质量有问题需要回到源头核对而不是硬合并。4. 村级数据落地时的避坑与排查清单4.1 现象读进来中文全是问号或方块原因.dbf的字符编码和读取时指定的encoding不一致或者.cpg文件缺失。解决先试utf-8再试gbk还不行就用chardet探测如果.cpg缺失手动创建一个内容为UTF-8的.cpg文件放在同目录。4.2 现象面积算出来大得离谱或小得离谱原因没投影就直接算或者投影带选错。经纬度下geometry.area返回的是「平方度」数值毫无意义。解决先to_crs到对应高斯克吕格带再算面积用几个已知面积的区县做校验偏差超过 5% 就换带重试。4.3 现象村和村之间有缝隙或重叠原因不同来源的村级边界拼接时拓扑不一致或者数据本身是示意边界。解决用gdf.geometry.is_valid检查几何有效性对无效几何做buffer(0)修复缝隙和重叠在村级尺度很难完全消除做汇总统计时优先用「按属性分组求和」而不是「按空间相交」能绕开大部分拓扑问题。4.4 现象和人口数据关联后对不上原因人口数据用的是统计用区划代码而 shp 里的代码口径不同或者年份不一致。解决以代码为准做关联不要用名称关联前先确认两边代码位数和层级一致。2024 年的数据配 2024 年的人口口径跨年份关联必然有出入。4.5 现象全省数据加载慢、画图卡原因村级要素数量大几何复杂直接全量渲染很吃内存。解决按市或县做子集再处理用gdf[gdf[CITY]合肥市]先筛制图时用simplify做几何简化但注意简化后再算面积会有偏差统计和出图用两份数据。5. 把村级边界用出价值空间连接、制图与自动化校验5.1 用空间连接把点位数据下沉到村村级边界最实用的场景是把 POI、快递网点、卫生室这类点位数据落到村。做法是空间连接# points 是带经纬度的点位数据先转成 GeoDataFrame points gpd.GeoDataFrame( df, geometrygpd.points_from_xy(df[lon], df[lat]), crsEPSG:4490 ) # 统一坐标系后做空间连接把村名和代码挂到点位上 points points.to_crs(gdf.crs) joined gpd.sjoin(points, gdf[[NAME, CODE, geometry]], howleft, predicatewithin) # 统计每个村的点位数 count_by_village joined.groupby(NAME).size().sort_values(ascendingFalse) print(count_by_village.head(10))逻辑说明sjoin的predicatewithin表示点落在村多边形内部才算匹配。howleft保证没匹配上的点也保留方便你排查是哪些点落在了边界外。参数上两边坐标系必须先统一否则sjoin会报错或给出错误结果。这一步做完你就能回答「哪个村的网点最密集」这类问题。5.2 制图时的分级与标注技巧村级制图最大的问题是标注拥挤。实操中我一般这样做先按区县或乡镇分组只标注当前视图范围内的村用matplotlib出图时把村界设为细灰线乡镇界设为粗一点的线形成层级感。分级设色优先用自然断点法schemenatural_breaks比等间距更符合村级数据的分布特征。如果只是内部核对不必追求出版级效果能看清边界和名称就够。5.3 一套可复用的自动化校验脚本数据每次更新都要重新核对手动检查不现实。我习惯写一个校验脚本把关键指标打出来def validate(gdf): report {} report[要素总数] len(gdf) report[空几何] gdf.geometry.isna().sum() report[无效几何] (~gdf.geometry.is_valid).sum() report[坐标系] str(gdf.crs) report[名称空值] gdf[NAME].isna().sum() report[代码重复] gdf[CODE].duplicated().sum() if CODE in gdf else 无CODE字段 for k, v in report.items(): print(f{k}: {v}) return report validate(gdf)逻辑说明这个函数把每次更新后最该看的几项一次性打出来。无效几何不为零就要修代码重复不为零说明数据有合并错误。把它挂到数据入库流程里能挡掉大部分低级问题。参数上不用改直接复用即可。5.4 一个我踩过的坑别用村级边界直接算人口密度早年我拿村级面积去除人口得出某城中村人口密度高得离谱后来发现那个「村」的边界只画了居民点没包含耕地和空地面积被严重低估。村级边界的口径各地不统一有的包含全部管辖范围有的只画建成区。所以做密度类指标前一定先确认边界的口径必要时用更粗的乡镇级数据做交叉验证。这个习惯帮我省了很多后悔药。村级数据真正的价值不在于边界本身多精确而在于它能不能稳定地和你手上的业务数据对齐。把坐标系、代码口径、拓扑校验这三件事做扎实后面无论做规划图还是做统计都不会再被底图拖后腿。希望帮到你。本文还有配套的精品资源点击获取