首页 / 资讯中心 / 文章详情

重庆五级行政区划SHP数据全解析:从村界到乡镇的矢量底图实战指南

重庆五级行政区划SHP数据全解析:从村界到乡镇的矢量底图实战指南 ★ FEATURED ARTICLE
简介本资源为2025年重庆市五级行政区划SHP矢量数据包面向GIS从业者、城市规划研究人员、地理信息专业师生及需要行政区划底图的数据分析人员可解决省、市、县、乡镇街道、社区村界多级边界获取与制图分析的问题适用于空间统计、专题制图、区域规划等场景。资源共29个文件以shp、shx、dbf、prj、cpg等Shapefile核心组件为主辅以sbn、sbx空间索引文件及xml元数据压缩包约24.72MB各层级数据均包含完整的几何、属性与投影信息可直接在ArcGIS、QGIS等平台加载使用。目前已有605人学习下载。数据覆盖重庆全市五级行政单元层级完整、边界清晰便于读者直接用于行政区划可视化、人口与经济指标空间连接、乡镇尺度分析等任务省去多源数据拼接与坐标校正的重复工作是一份开箱即用的基础地理数据资料。1. 重庆五级区划 SHP 数据从村界到乡镇一套矢量底图能省掉多少返工做过重庆项目的人都知道这里的行政区划底图是个硬骨头。主城九区街道密集、渝东北渝东南乡镇跨度大再加上村社一级的边界很多团队拿到手的 SHP 要么只到区县要么村界缺胳膊少腿。标题里的五级行政区划 SHP 数据说的就是省直辖市、区县、乡镇街道、村社这一整条链路落到矢量数据上就是一套带行政代码、名称、层级字段的多边形图层。它解决的核心问题很直接让做专题图、做空间统计、做区划聚合的人不用再自己一层层拼边界。适合谁做重庆本地 GIS 分析、国土空间规划、人口经济数据落图、以及需要把业务数据挂到村社颗粒度的从业者。矢量数据、SHP 这几个词看着普通真正用起来才知道层级字段和坐标系没对齐后面全是返工。2. 五级区划 SHP 到底包含什么图层、字段与坐标系的选型逻辑2.1 五个层级分别对应哪些几何对象先把五级这个词拆开。重庆是直辖市行政层级和普通省份不完全一样但落到矢量数据上通常按这几层组织层级几何类型典型对象常见字段省级Polygon重庆市全域省级代码、省级名称区县级Polygon38 个区县区县代码、区县名称、上级代码乡镇街道级Polygon乡镇、街道乡镇代码、乡镇名称、上级代码村社级Polygon村、社区村社代码、村社名称、上级代码村级点位可选Point村委会/居委会驻地名称、坐标这里有个容易翻车的点很多人以为五级就是五个 SHP 文件实际上更稳的做法是一个图层带层级字段或者按层级拆成多个 SHP 但字段结构统一。前者便于做空间叠加和聚合后者便于分发给不同岗位。我一般会两种都留一份分析用合并图层出图用拆分图层。几何类型上区县及以上基本都是面村社级在山区可能出现飞地、狭长地块甚至自相交。拿到数据第一件事不是画图是跑一遍几何有效性检查这个后面避坑章节会细说。2.2 字段设计行政代码是命根子矢量数据能不能用八成看字段。行政区划 SHP 最核心的字段是行政代码它是把业务数据挂上来的唯一钥匙。常见的字段命名有adcode、code、xzqhdm几种不同来源不统一这是后期对不上的主要原因。我一般会要求数据至少包含这几列code12 位或更长的行政代码村社级通常到 12 位name名称注意街道和镇要区分level层级标识用数字或英文枚举别用中文parent_code上级代码用来做层级回溯parent_name上级名称方便人工核对提示如果拿到的数据只有名称没有代码先别急着用。名称在重庆这种地方重名率不低比如多个XX 村靠名称关联迟早出错。字段类型上代码列一定要用文本型不要用数值型。数值型会把前导零吃掉重庆有些区县代码开头是 50看着没事但村社级代码一旦有前导零数值型直接给你抹掉这种坑非常隐蔽。2.3 坐标系怎么选投影还是地理坐标系选错量算和叠加全废。重庆跨了 106°E 到 110°E常用的有两套CGCS2000 地理坐标系EPSG:4490适合做数据交换、入库单位是度CGCS2000 高斯投影如 EPSG:45443 度带适合做面积量算、距离分析单位是米如果你只是做区划展示、挂点数据地理坐标系够用。但一旦要算村域面积、做缓冲区必须投影。我一般会保留一份地理坐标的原始数据再另存一份投影数据专门做分析别在一个文件里反复转转多了精度会飘。选带号也有讲究。重庆主城大概在 106°E 附近渝东北靠近 109°E如果全用同一个 3 度带边缘区域变形会偏大。做全市统一分析时常见做法是用重庆本地的自定义投影或者接受一定误差具体看你的精度要求。3. 拿到 SHP 后怎么用从加载、字段清洗到村界聚合的完整流程3.1 用 Python 加载并检查五级图层拿到数据第一步是验证不是直接画图。下面这段用geopandas加载并做基础体检import geopandas as gpd # 读取五级区划 SHP注意 encoding 参数中文属性容易乱码 gdf gpd.read_file(chongqing_5level.shp, encodingutf-8) # 基础信息几何类型、坐标系、字段 print(几何类型:, gdf.geom_type.unique()) print(坐标系:, gdf.crs) print(字段列表:, gdf.columns.tolist()) print(要素数量:, len(gdf)) # 按层级统计确认五级是否齐全 if level in gdf.columns: print(gdf[level].value_counts()) # 几何有效性检查找出自相交、空几何 invalid gdf[~gdf.is_valid] print(无效几何数量:, len(invalid))逻辑说明read_file的encoding参数很关键SHP 的.dbf属性表中文乱码是高频问题UTF-8 不行就试 GBK。is_valid会标出几何有问题的要素这些要素在后续叠加时会报错或产生错误结果必须先修。参数说明geom_type用来确认是不是全是 Polygon如果混进了 Point 或 LineString说明数据组织有问题。crs如果是None说明坐标系丢失得手动指定别默认它是 WGS84。3.2 字段清洗与行政代码补全字段清洗的目标是让五级数据能通过code和parent_code串成一棵树。常见问题是代码位数不统一、有空格、有全角字符。import pandas as pd # 统一代码列为字符串去掉空格和全角字符 gdf[code] gdf[code].astype(str).str.strip() gdf[parent_code] gdf[parent_code].astype(str).str.strip() # 检查代码长度分布村社级一般 12 位 print(gdf[code].str.len().value_counts()) # 用 parent_code 回溯验证层级关系是否闭合 level_map gdf.set_index(code)[level].to_dict() def check_parent(row): if pd.isna(row[parent_code]) or row[parent_code] nan: return True # 省级没有上级 return row[parent_code] in level_map gdf[parent_ok] gdf.apply(check_parent, axis1) print(上级代码缺失数量:, (~gdf[parent_ok]).sum())逻辑说明把代码转成字符串是防止数值型丢前导零。check_parent逐行验证每个要素的上级代码是否能在数据里找到找不到就说明层级链断了这种要素在做聚合时会变成孤儿。参数说明str.len()的分布能快速暴露问题如果村社级出现 9 位、10 位混杂说明数据来源不统一需要对照行政区划代码表补齐。level_map用字典做 O(1) 查找比循环快很多。3.3 村界聚合到乡镇空间融合的正确姿势很多分析需要把村社数据聚合到乡镇比如算乡镇总人口。这里有两种做法按代码分组汇总属性或者按空间融合几何。前者快后者能生成新的乡镇边界。# 方法一按 parent_code 分组做属性聚合推荐快且不丢精度 village gdf[gdf[level] village] town_stats village.groupby(parent_code).agg( village_count(code, count), total_area(area, sum) # 假设已有面积字段 ).reset_index() # 方法二空间融合把村界面合并成乡镇面 town_geom village.dissolve(byparent_code, aggfuncsum) # 融合后检查几何有效性dissolve 可能产生无效几何 town_geom[geometry] town_geom[geometry].buffer(0) print(融合后要素数:, len(town_geom))逻辑说明groupby做属性聚合不改变几何适合统计类需求。dissolve会真正合并相邻多边形适合出图或做乡镇级空间分析。buffer(0)是修复自相交几何的常用技巧能把大部分无效多边形修好。参数说明dissolve的aggfunc决定属性怎么合并数值字段用sum或mean要按业务定。融合后要素数应该等于乡镇数量如果对不上说明有村社的parent_code缺失或错误。注意dissolve在村社数量多的时候很吃内存重庆村社级要素可能上万建议先按区县拆分再融合别一次性全跑。3.4 导出与格式转换SHP 之外的常见需求SHP 有字段名长度限制10 个字符和文件大小限制实际项目里经常要转成其他格式。热搜里出现的shp转txt、shp格式矢量数据导出为wkt、shp转3dtiles都是真实需求。# 导出为 GeoJSON字段名不受 10 字符限制 gdf.to_file(chongqing_5level.geojson, driverGeoJSON) # 导出几何为 WKT 文本方便入库或传给前端 gdf[wkt] gdf[geometry].apply(lambda geom: geom.wkt) gdf[[code, name, level, wkt]].to_csv(chongqing_wkt.csv, indexFalse) # 导出为 GeoPackage单文件、支持长字段名、支持多图层 gdf.to_file(chongqing_5level.gpkg, layerdistrict, driverGPKG)逻辑说明GeoJSON 适合 Web 端和跨工具交换但文件体积大。WKT 适合数据库存储和接口传输。GeoPackage 是目前比较推荐的本地格式单文件、跨平台、没有 SHP 那些历史包袱。参数说明to_file的driver参数决定输出格式GeoJSON 用GeoJSONGPKG 用GPKG。导出 CSV 时记得只保留需要的列WKT 字符串很长全字段导出文件会很大。4. 避坑与排查五级区划 SHP 最容易翻车的五个地方4.1 中文属性乱码打开全是问号现象用 ArcGIS 或 QGIS 打开 SHP属性表里中文名称显示为乱码或问号。原因SHP 的.dbf文件编码和软件默认编码不一致。老数据常用 GBK新数据可能用 UTF-8软件猜错了就乱码。解决QGIS 里可以在图层属性中手动指定编码Python 里read_file加encodinggbk或encodingutf-8试。如果都不行用dbfread单独读属性表确认编码。根治办法是转成 GeoPackage 或 GeoJSON这两种格式编码规范明确。4.2 行政代码变成数值前导零消失现象代码列005001变成了5001和上级代码对不上。原因数据在 Excel 或某些工具里被当成数值处理前导零被吃掉。解决读取时强制dtype{code: str}或者在 Excel 里先把列格式设为文本再导入。已经丢零的数据只能对照官方行政区划代码表补回位数没有捷径。4.3 村界和乡镇界对不上出现缝隙或重叠现象把村界融合成乡镇界后和已有的乡镇 SHP 对比边界有缝隙或重叠。原因不同来源的数据采集精度不同或者坐标系转换时产生偏移。重庆山区地形复杂边界采集误差更明显。解决先统一坐标系再做融合。如果仍有缝隙可以用snap工具做节点捕捉或者接受一定误差。做面积统计时以一套数据为准别混用。4.4 dissolve 融合后要素数对不上现象村社有 8000 多个按乡镇融合后应该得到 1000 多个乡镇结果多出几十个。原因部分村社的parent_code缺失或错误dissolve把它们单独成组了。解决融合前先跑 3.2 节的check_parent把孤儿要素找出来修好。另外检查parent_code是否有空格或全角字符这些都会导致分组失败。4.5 面积量算结果偏小或偏大现象用地理坐标系直接算面积结果和实际差很多。原因地理坐标系的单位是度直接算面积得到的是平方度没有物理意义。解决先投影到合适的投影坐标系再算面积。重庆可以用 CGCS2000 3 度带或者用等面积投影。算完再转回地理坐标系做展示。这个坑新手几乎必踩记住一句话算面积先投影。5. 进阶技巧用渔网分割和空间连接把业务数据挂到村社颗粒度前面讲的都是底图本身真正体现价值的是把业务数据挂上去。假设你有一批带经纬度的门店点位想统计每个村社有多少家门店这就是典型的空间连接场景。热搜里的渔网分割 shp其实也是类似思路用规则网格去切分区域做统计。先看空间连接的标准做法# 门店点位转 GeoDataFrame假设已有经纬度列 from shapely.geometry import Point shops pd.read_csv(shops.csv) shops_gdf gpd.GeoDataFrame( shops, geometry[Point(xy) for xy in zip(shops[lng], shops[lat])], crsEPSG:4326 ) # 统一坐标系村界用投影坐标点位也转过去 village_proj village.to_crs(EPSG:4544) shops_proj shops_gdf.to_crs(EPSG:4544) # 空间连接判断每个点落在哪个村 joined gpd.sjoin(shops_proj, village_proj, howleft, predicatewithin) # 按村社统计门店数 shop_count joined.groupby(code).size().reset_index(nameshop_count) print(shop_count.head())逻辑说明sjoin是空间连接的核心函数predicatewithin表示点完全落在面内。howleft保留所有点落在边界外的点code会是空值这些点需要单独处理。统计前先统一坐标系避免因投影不一致导致点落错村。参数说明predicate还可以用intersects区别是边界上的点算不算。做严格统计用within做宽松匹配用intersects。groupby(code).size()统计每个村的点数如果要统计其他指标用agg更灵活。再进一步如果你需要把区域切成规则网格做热力统计可以用渔网# 生成覆盖重庆的渔网每个格子 1km x 1km from shapely.geometry import box import numpy as np minx, miny, maxx, maxy village_proj.total_bounds cell_size 1000 # 单位米 cols np.arange(minx, maxx, cell_size) rows np.arange(miny, maxy, cell_size) cells [box(x, y, x cell_size, y cell_size) for x in cols for y in rows] grid gpd.GeoDataFrame(geometrycells, crsEPSG:4544) # 用渔网和村界做叠加统计每个格子覆盖的村 grid_joined gpd.sjoin(grid, village_proj, howinner, predicateintersects) print(有效格子数:, len(grid_joined))逻辑说明渔网的本质是规则多边形集合total_bounds拿到研究区范围按固定步长生成格子。sjoin把格子和村界关联起来后续可以做格网级的人口、经济密度分析。重庆地形起伏大1km 格子在山区的实际覆盖可能不均匀做密度分析时要考虑这一点。参数说明cell_size决定网格粒度1000 米适合区县级分析500 米适合主城区200 米以下计算量会很大。predicateintersects保证边界上的格子也被纳入避免边缘漏统计。最后说一个我自己的习惯每次拿到新的区划 SHP我都会先建一个体检脚本把几何有效性、代码长度、层级闭合、坐标系这四项跑一遍存成报告。这个脚本花不了半小时但能省掉后面几天的返工。重庆的五级区划数据尤其如此村社一级的坑最多宁可前期多花时间验证也别等到出图了才发现代码对不上。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站