资讯动态

达州市乡镇街道行政区划shp文件使用指南:从数据检查到空间分析

发布时间:2026/10/26 10:30:36 来源:尧图企业网站定制
简介这份达州市各乡镇街道行政区划shp文件面向GIS从业者、城市规划人员及地理信息相关专业师生提供四川省达州市下辖乡镇与街道的矢量边界数据可用于行政区划制图、空间统计、人口与公共服务分析、交通规划等场景。资源包共11个文件约1.12MB以Shapefile标准组件为主shp存储几何图形dbf保存行政属性字段shx与sbn/sbx负责空间索引prj定义坐标投影cpg指定字符编码xml记录元数据各类型配合可完整还原达州市乡镇街道的空间范围与行政信息。目前已有243人学习下载适合需要快速获取本地行政区划底图、开展GIS实验或专题制图的用户参考使用。1. 达州市乡镇街道行政区划 shp 文件从一份边界数据到能跑的分析底图你拿到一份“达州市各乡镇街道行政区划 shp 文件”第一反应大概率不是感动而是先确认三件事它是不是乡镇级、有没有街道、坐标系对不对。因为同样是“行政区划”省市县三级和乡镇街道两级完全不是一个量级——达州下辖 2 区 4 县 1 市乡镇街道加起来两百多个边界碎、飞地多、村社级缝隙常见直接拿来做空间统计翻车往往就翻在“看着对、算出来不对”上。这篇笔记就围绕这份 shp 文件把字段结构、坐标系、拓扑检查、按区县裁剪、面积汇总和出图这条链路讲透适合做国土空间、民政区划、物流网点、应急指挥底图的从业者也适合第一次接触乡镇级 shp 文件下载后不知道怎么用的新手。目标只有一个让你拿到文件后能自己判断能不能用、怎么修、怎么落到业务图层里。2. 先看清 shp 文件里装了什么字段、几何与坐标系的三角关系2.1 乡镇街道 shp 的三个组成部分与最小字段集shp 文件不是单个文件而是一组同名文件.shp存几何.shx存索引.dbf存属性表.prj存坐标系定义缺一个都可能让 GIS 软件报错或坐标错乱。达州市乡镇街道这份数据属性表里通常至少要有这几类字段行政区代码、行政区名称、上级区县名称或代码、几何类型。乡镇级代码一般是 9 位或 12 位前 6 位对应县级中间 3 位是乡镇街道顺序码街道和镇、乡在代码段上会有区分。拿到文件后第一件事不是画图而是用属性表排序看名称里有没有“街道”“镇”“乡”三类是否齐全再看有没有空名称或重复代码。import geopandas as gpd # 读取达州市乡镇街道 shp 文件注意路径不要带中文空格 gdf gpd.read_file(rD:\data\dazhou_township.shp) # 看前 5 行属性确认字段名和内容 print(gdf.head()) # 看字段类型和空值情况 print(gdf.dtypes) print(gdf.isnull().sum()) # 看几何类型和坐标系 print(gdf.geom_type.unique()) print(gdf.crs)这段代码的逻辑是先建立“数据体检”习惯。head()看字段名是否可读dtypes看代码字段是不是被读成了数字导致前导零丢失isnull()看名称或代码有没有缺失geom_type确认是 Polygon 还是 MultiPolygoncrs确认有没有坐标系定义。参数上唯一要注意的是路径Windows 下用r原始字符串避免反斜杠转义。如果crs输出为 None说明.prj缺失或未被识别后面所有面积计算都不可信。2.2 坐标系怎么选地理坐标与投影坐标的切换时机达州位于东经 106° 到 108° 之间属于 CGCS2000 或 WGS84 地理坐标系下的 3 度带第 35 带、36 带范围。很多乡镇街道 shp 文件下载后默认是 GCS_WGS_1984 或 GCS_China_2000单位是度直接算面积会得到“平方度”这种没有业务意义的数字。正确做法是做展示和叠加时保留地理坐标做面积、长度、缓冲区分析时切换到投影坐标。达州常用 CGCS2000_3_Degree_GK_Zone_35 或 36也可以用 UTM Zone 48N 做临时分析。# 如果原数据是地理坐标先投影到 CGCS2000 3度带 # 达州东部偏 36 带西部偏 35 带按主体区域选带 gdf_proj gdf.to_crs(epsg4544) # CGCS2000 / 3-degree Gauss-Kruger CM 105E 附近 # 计算每个乡镇街道的面积单位平方米 gdf_proj[area_m2] gdf_proj.geometry.area # 转成平方公里方便和统计年鉴对照 gdf_proj[area_km2] gdf_proj[area_m2] / 1e6 print(gdf_proj[[name, area_km2]].sort_values(area_km2, ascendingFalse).head(10))这里用 EPSG:4544 只是示例实际要看你数据覆盖范围。达州跨 105°E 到 108°E如果一份数据同时包含万源和渠县用单一带号会有边缘变形但乡镇级面积汇总通常可以接受。关键是不要在地理坐标系下直接算面积也不要用 Web Mercator 算面积后者在高纬度会明显放大。面积算完后拿几个熟悉乡镇和年鉴数据对一下偏差超过 5% 就要回头查坐标系和几何有效性。2.3 几何有效性检查自相交、缝隙与飞地乡镇街道边界最常见的问题是自相交、重叠和缝隙。自相交会让面积计算出错重叠会让汇总重复计数缝隙会让裁剪时出现空值。用 GeoPandas 的is_valid可以快速筛出问题几何再用buffer(0)或make_valid修复。达州山区乡镇边界沿山脊划分飞地不少修复时要保留 MultiPolygon不要强行合并。# 检查无效几何 invalid gdf_proj[~gdf_proj.geometry.is_valid] print(f无效几何数量: {len(invalid)}) print(invalid[[name, geometry]]) # 修复无效几何buffer(0) 是常用手法 gdf_proj[geometry] gdf_proj.geometry.buffer(0) # 再次检查 print(gdf_proj.geometry.is_valid.all()) # 检查重叠用叠加分析找相交面积大于阈值的要素对 import itertools overlaps [] for i, j in itertools.combinations(range(len(gdf_proj)), 2): if gdf_proj.geometry.iloc[i].intersects(gdf_proj.geometry.iloc[j]): inter_area gdf_proj.geometry.iloc[i].intersection(gdf_proj.geometry.iloc[j]).area if inter_area 1e6: # 超过 1 平方公里才算异常 overlaps.append((gdf_proj.name.iloc[i], gdf_proj.name.iloc[j], inter_area)) print(overlaps[:10])buffer(0)对大多数自相交有效但对复杂拓扑错误可能失败失败时改用shapely.validation.make_valid。重叠检查用两两组合在两百多个要素时计算量约两万次可以接受如果要素上千建议用空间索引sindex先筛候选对。飞地问题不要在这一步处理留到按区县汇总时单独看。3. 把 shp 文件用起来裁剪、汇总与出图的最小工作流3.1 按区县裁剪用通川区做一次完整验证拿到全市乡镇街道 shp 后业务上往往只关心某个区县。用通川区做验证是因为它既有街道又有镇还有飞地能暴露大部分问题。裁剪需要一份区县边界可以从同一份数据里按上级区县字段筛选也可以单独加载区县 shp。推荐用属性字段筛选避免边界不一致。# 假设属性表里有 city 字段值为“通川区” tongchuan gdf_proj[gdf_proj[city] 通川区].copy() # 如果字段名是中文用实际字段名替换 # tongchuan gdf_proj[gdf_proj[区县] 通川区].copy() # 导出为新的 shp注意编码 tongchuan.to_file(rD:\data\tongchuan_township.shp, encodingutf-8) # 统计乡镇街道数量和总面积 print(f通川区乡镇街道数量: {len(tongchuan)}) print(f通川区总面积: {tongchuan[area_km2].sum():.2f} 平方公里)导出时encodingutf-8是为了避免中文属性乱码ArcGIS 对 UTF-8 支持较好QGIS 也正常。如果下游系统只认 GBK改成encodinggbk。面积汇总时注意如果几何有重叠sum()会偏大如果有缝隙会偏小。通川区面积可以和公开年鉴对照偏差大就回到上一步查拓扑。3.2 乡镇街道代码与名称的清洗规则乡镇街道 shp 文件下载来源不同名称写法差异很大“东城街道”可能写成“东城街道办事处”“碑庙镇”可能带空格。做汇总前统一清洗否则分组统计会出现同一乡镇多条记录。清洗规则建议去掉“办事处”“街道办”后缀统一“街道”“镇”“乡”结尾去掉首尾空格和全角空格。import re def clean_name(name): if not isinstance(name, str): return name name name.strip().replace(\u3000, ) name re.sub(r(办事处|街道办)$, 街道, name) name re.sub(r街道$, 街道, name) return name gdf_proj[name_clean] gdf_proj[name].apply(clean_name) # 检查清洗后是否有重复 dup gdf_proj[gdf_proj.duplicated(name_clean, keepFalse)] print(dup[[name, name_clean, city]])重复名称不一定都是错误不同区县可能有同名乡镇比如“太平镇”在达州多个县都有。所以去重要看“区县乡镇”组合不能只看乡镇名。代码字段同理前导零丢失后要补零到 9 位或 12 位补零前先确认原始代码长度。3.3 出图用 Matplotlib 快速检查边界合理性出图不是为了好看是为了用眼睛抓拓扑错误。用 GeoPandas 自带 plot 可以快速画一张全市乡镇街道图重点看有没有明显重叠色块、飞地是否孤立、边界是否沿山脊。import matplotlib.pyplot as plt fig, ax plt.subplots(figsize(12, 10)) gdf_proj.plot(axax, columncity, categoricalTrue, legendTrue, edgecolorwhite, linewidth0.3) ax.set_title(达州市乡镇街道行政区划, fontsize14) ax.set_axis_off() plt.tight_layout() plt.savefig(rD:\data\dazhou_township.png, dpi300) plt.show()columncity按区县着色能快速看出各区县范围是否连续。如果某个区县出现孤立色块可能是飞地也可能是属性错误。linewidth0.3是为了让乡镇边界可见但不糊成一片。出图后对照达州地图重点看万源、宣汉、渠县这些面积大、乡镇多的区域。4. 避坑与排查乡镇级 shp 文件最容易翻车的 5 个地方4.1 现象面积算出来比年鉴大很多 → 原因坐标系没投影 → 解决切到 CGCS2000 3 度带再算这是血泪经验里排第一的坑。地理坐标系下geometry.area返回的是平方度数值看起来很小但一旦有人误以为单位是平方米再换算就会得到离谱结果。更隐蔽的是 Web Mercator面积会随纬度放大达州在北纬 31° 左右放大系数约 1.3 倍。解决方式固定分析前to_crs到投影坐标系算完再转回地理坐标出图。4.2 现象裁剪后乡镇数量对不上 → 原因区县字段有空格或别名 → 解决先做唯一值统计再筛选属性表里“通川区”可能写成“通川区 ”或“达州市通川区”。直接筛选会漏掉。先value_counts()看所有唯一值再用str.contains或映射表统一。如果区县字段缺失可以用空间叠加从区县 shp 里带过来但要注意边界不一致导致的归属错误。4.3 现象导出 shp 后中文乱码 → 原因编码不匹配 → 解决统一 UTF-8 或 GBK 并写 .cpg 文件ArcGIS 和 QGIS 对编码处理不同。导出时指定encoding同时生成.cpg文件声明编码。如果下游是老旧系统用 GBK如果只在 QGIS 和 GeoPandas 之间流转UTF-8 更稳。乱码后不要反复导出先确认原始.dbf编码再决定转换方向。4.4 现象乡镇边界有缝隙汇总面积偏小 → 原因数据采集精度不一致 → 解决用区县边界做掩膜不要强行合并乡镇级边界往往由不同批次数据拼接缝隙难免。强行unary_union会把缝隙吃掉但也会改变边界形状。正确做法是用区县边界做裁剪掩膜汇总时以区县总面积为控制值乡镇面积按比例平差。如果业务允许直接用区县汇总乡镇只做展示。4.5 现象飞地归属错误 → 原因空间关系判断用了 centroid → 解决用 representative_point 或最大面积法判断飞地属于哪个区县时用centroid可能落在飞地外部。改用representative_point()保证点在几何内部或者用intersection面积最大的区县作为归属。达州山区飞地多这一步不做后续按区县汇总一定出错。5. 进阶技巧用空间索引加速两百乡镇的叠加分析并做一次面积平差验证两百多个乡镇街道做两两叠加朴素循环要跑几万次慢且容易内存溢出。用 GeoPandas 的sindex先建空间索引只对可能相交的要素对做精确计算速度能提升一个数量级。下面这段代码同时做两件事找出重叠面积超过阈值的乡镇对并按区县汇总面积做平差验证。# 建立空间索引 sindex gdf_proj.sindex # 用索引找候选重叠对 overlap_pairs [] for i, geom in enumerate(gdf_proj.geometry): # query 返回可能相交的索引 candidates list(sindex.query(geom)) for j in candidates: if j i: continue inter geom.intersection(gdf_proj.geometry.iloc[j]) if not inter.is_empty: area inter.area if area 1e6: overlap_pairs.append((gdf_proj.name.iloc[i], gdf_proj.name.iloc[j], area)) print(f重叠对数量: {len(overlap_pairs)}) for pair in overlap_pairs[:5]: print(pair) # 按区县汇总面积和区县边界面积对照 city_sum gdf_proj.groupby(city)[area_km2].sum().reset_index() city_sum.columns [city, sum_township_km2] # 假设有区县边界 shp读取后算面积 county gpd.read_file(rD:\data\dazhou_county.shp).to_crs(gdf_proj.crs) county[county_km2] county.geometry.area / 1e6 compare county.merge(city_sum, left_onname, right_oncity, howleft) compare[diff_ratio] (compare[sum_township_km2] - compare[county_km2]) / compare[county_km2] print(compare[[name, county_km2, sum_township_km2, diff_ratio]])sindex.query返回的是候选索引不是精确相交结果所以后面还要做一次intersection确认。阈值1e6平方米可以根据数据精度调整乡镇级数据一般 1 平方公里以上的重叠才值得处理。平差验证看diff_ratio如果某个区县偏差超过 3%优先查该区县的乡镇边界是否有缝隙或重叠。我一般会把偏差最大的三个区县单独导出叠加卫星底图肉眼检查。最后说个习惯每次拿到新的乡镇街道 shp 文件先跑一遍字段体检、坐标系确认、几何有效性检查这三步再谈业务分析。这份达州市数据我前后修过三次第一次栽在坐标系第二次栽在飞地归属第三次栽在名称重复。现在我的做法是所有中间结果都保留name_clean和code_clean两个字段出图前必看一遍无效几何数量。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑