简介:这份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 是底线
安徽的村级数据,常见做法是地理坐标系用 CGCS2000(EPSG: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 python=3.11 conda activate ah_village conda install -c conda-forge geopandas matplotlib装好后,最小读取代码如下。注意encoding参数,中文属性表乱码基本都出在这里:
import geopandas as gpd # 读取村级 shp,指定编码避免中文乱码 gdf = gpd.read_file("安徽省村级行政区划.shp", encoding="utf-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(epsg=4547) # 面积单位是平方米,转成平方公里 gdf_proj["area_km2"] = gdf_proj.geometry.area / 1e6 # 按区县汇总面积,检查是否合理 summary = gdf_proj.groupby("COUNTY")["area_km2"].sum().sort_values(ascending=False) 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(keep=False)] print(f"重复键数量: {len(dup)}")逻辑说明:单靠村名做关联在安徽几乎必错,构造复合键是标准做法。duplicated(keep=False)会把所有重复项都列出来,方便你判断是数据本身重复还是命名冲突。如果重复量大,说明数据质量有问题,需要回到源头核对,而不是硬合并。
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, geometry=gpd.points_from_xy(df["lon"], df["lat"]), crs="EPSG:4490" ) # 统一坐标系后做空间连接,把村名和代码挂到点位上 points = points.to_crs(gdf.crs) joined = gpd.sjoin(points, gdf[["NAME", "CODE", "geometry"]], how="left", predicate="within") # 统计每个村的点位数 count_by_village = joined.groupby("NAME").size().sort_values(ascending=False) print(count_by_village.head(10))逻辑说明:sjoin的predicate="within"表示点落在村多边形内部才算匹配。how="left"保证没匹配上的点也保留,方便你排查是哪些点落在了边界外。参数上,两边坐标系必须先统一,否则sjoin会报错或给出错误结果。这一步做完,你就能回答「哪个村的网点最密集」这类问题。
5.2 制图时的分级与标注技巧
村级制图最大的问题是标注拥挤。实操中我一般这样做:先按区县或乡镇分组,只标注当前视图范围内的村;用matplotlib出图时,把村界设为细灰线,乡镇界设为粗一点的线,形成层级感。分级设色优先用自然断点法(scheme="natural_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 一个我踩过的坑:别用村级边界直接算人口密度
早年我拿村级面积去除人口,得出某城中村人口密度高得离谱,后来发现那个「村」的边界只画了居民点,没包含耕地和空地,面积被严重低估。村级边界的口径各地不统一,有的包含全部管辖范围,有的只画建成区。所以做密度类指标前,一定先确认边界的口径,必要时用更粗的乡镇级数据做交叉验证。这个习惯帮我省了很多后悔药。
村级数据真正的价值不在于边界本身多精确,而在于它能不能稳定地和你手上的业务数据对齐。把坐标系、代码口径、拓扑校验这三件事做扎实,后面无论做规划图还是做统计,都不会再被底图拖后腿。希望帮到你。
本文还有配套的精品资源,点击获取