达州市乡镇街道行政区划shp文件:GIS矢量底图使用与避坑指南
简介:这份达州市各乡镇街道行政区划shp文件面向GIS从业者、城市规划人员及地理信息相关专业师生,提供四川省达州市下辖乡镇与街道的矢量边界数据,可用于行政区划制图、空间统计、人口与公共服务分析等场景。资源包共11个文件,约1.12MB,以Shapefile标准组件为主:shp存储几何图形,shx与sbn/sbx负责空间索引,dbf保存属性字段,prj与cpg定义投影和字符编码,另有xml元数据辅助说明,整体结构完整,可直接在ArcGIS、QGIS等软件中加载使用。目前已有243人学习下载。数据覆盖达州市各乡镇街道的几何形状与行政信息,适合用于区域规划、交通分析、环境保护等研究,也可作为底图与其他专题数据叠加,帮助读者快速获取本地行政区划边界,减少手工数字化成本。
1. 达州市乡镇街道行政区划 shp 文件:一份能直接进 GIS 的矢量底图
做川东北片区项目的人多半遇到过这个场景:领导要一张达州市域乡镇界分布图,手头只有全国省市县三级边界,乡镇一级的 shp 文件翻遍几个数据站都找不到,最后只能拿区县边界硬撑,出图被一眼看穿。这份达州市各乡镇街道行政区划 shp 文件解决的正是这个断层——它把达州下辖的区县进一步拆到乡镇、街道一级,输出标准 Shapefile 矢量格式,属性表里带行政区名称和代码,能直接拖进 ArcGIS、QGIS 或 GeoPandas 里做空间统计、专题制图和边界裁剪。适合做国土空间规划、民政区划核对、物流网点分区、人口数据落图的人,也适合需要一份本地化矢量底图做二次开发的后端和数据分析岗。它不是瓦片地图,不是在线服务,就是一份能离线打开、能改、能算的矢量文件。
2. Shapefile 的组成与坐标系:先搞懂手里这几个文件
2.1 一个 shp 从来不是单个文件
很多人第一次拿到 Shapefile 会懵:解压出来一堆同名不同后缀的文件,删掉几个发现打不开了。Shapefile 是 ESRI 早年定的一套开放格式,本质是多个文件协同工作,缺一不可。常见组成如下:
| 后缀 | 作用 | 缺失后果 |
|---|---|---|
| .shp | 存储几何图形(点/线/面坐标) | 没有图形,直接打不开 |
| .shx | 几何图形的索引 | 部分软件无法定位要素 |
| .dbf | 属性表,存区划名称、代码等字段 | 有图无属性,没法按名称筛选 |
| .prj | 坐标系定义(WKT 文本) | 坐标数值还在,但软件不知道单位 |
| .cpg | 属性表字符编码声明 | 中文属性可能乱码 |
我一般拿到压缩包先看有没有 .prj 和 .cpg。前者决定这份数据能不能和别的图层套准,后者决定属性表里的乡镇名是不是乱码。达州这类区划数据,属性里通常有类似 NAME、CODE、ADCODE 这样的字段,具体字段名以实际 dbf 为准,别照搬别人的字段名去写脚本。
2.2 坐标系选错,图就飘到几百米外
达州位于东经 106° 到 108°、北纬 30° 到 32° 一带,国内区划数据常见两种坐标:地理坐标系 CGCS2000(经纬度,单位度)和投影坐标系 CGCS2000 3 度带高斯克吕格(单位米)。前者适合做全国、全省范围的叠加分析,后者适合做面积量算和工程制图,因为按度算面积会随纬度变形。
判断方法很直接:打开属性表看坐标数值。如果 X 是 106 点几、Y 是 31 点几,那是经纬度;如果 X 是六位数、Y 是七位数,那是投影坐标。达州 3 度带一般落在中央经线 105° 或 108° 的分带里,具体看 .prj 里的中央经线参数。用 QGIS 的话,右下角状态栏会直接显示当前 CRS,比翻文件快。
提示:如果 .prj 缺失或写的是 Unknown,别急着用。先按坐标数值范围判断是经纬度还是投影,再手动指定 CGCS2000 对应 CRS,否则后续裁剪和面积统计全是错的。
2.3 用 ogrinfo 快速体检
命令行党可以用 GDAL 自带的 ogrinfo 先做一次体检,不用打开图形界面就能看清图层名、要素数、坐标系和字段:
# 查看 shp 基本信息:图层名、几何类型、要素数量、坐标系 ogrinfo -so -al dazhou_township.shp # 只看属性表字段定义和前几条记录 ogrinfo -al -where "1=1" dazhou_township.shp | head -50-so表示 summary only,只输出摘要不打印每个要素;-al表示所有图层。输出里重点看 Feature Count(要素数,达州乡镇街道合计通常在几百这个量级)、Geometry(面还是线)、Extent(范围是否覆盖达州全境)和 Layer SRS。如果 Extent 的 X 范围是 106 到 108,说明是经纬度;如果是几十万到上百万,说明是投影坐标。这一步花不了一分钟,能省掉后面大量返工。
3. 把 shp 用起来:加载、筛选、裁剪与落图
3.1 QGIS 里加载并核对区划名称
QGIS 是最省事的验证工具。把 .shp 拖进画布,右键图层打开属性表,先扫一遍 NAME 字段有没有乱码。如果中文显示成问号或方块,说明 .cpg 缺失或编码不对,可以在图层属性里把编码改成 GBK 或 UTF-8 试。确认名称正常后,用表达式筛选出某个区县,比如只看通川区:
-- QGIS 图层筛选表达式:按区县名称过滤 "NAME" LIKE '%通川%'字段名以实际 dbf 为准,可能是 NAME、XZQMC 或其它。筛选出来如果要素数量对得上,说明属性表结构完整。这一步是后面所有统计的前提,属性乱了,按乡镇聚合人口或 POI 就全错位。
3.2 GeoPandas 读取与字段探查
要做批量处理或和业务数据关联,Python 更顺手。GeoPandas 读 shp 一行代码,但有几个参数值得注意:
import geopandas as gpd # 读取 shp,encoding 按实际 cpg 调整,常见 gbk 或 utf-8 gdf = gpd.read_file("dazhou_township.shp", encoding="gbk") # 查看坐标系、字段、要素数 print(gdf.crs) print(gdf.columns.tolist()) print(len(gdf)) # 查看前几行的区划名称字段 name_col = [c for c in gdf.columns if "NAME" in c.upper()][0] print(gdf[name_col].head(10))encoding参数是血泪经验,设错直接抛 UnicodeDecodeError 或者读出乱码。gdf.crs返回的是 pyproj 的 CRS 对象,如果显示 None,说明 .prj 没被读到,需要手动gdf.set_crs("EPSG:4490")之类指定。字段探查那步用列表推导找名称列,是因为不同来源的 shp 字段命名不统一,硬编码容易翻车。
3.3 按区县裁剪与面积量算
拿到全市乡镇数据后,常见需求是只保留某个区县,或者算每个乡镇的面积。裁剪用 GeoPandas 的 clip 或 overlay:
# 假设已有通川区边界 tongchuan_boundary(面要素) tongchuan_towns = gpd.clip(gdf, tongchuan_boundary) # 投影到适合达州的投影坐标系后再算面积,单位平方米 tongchuan_towns_proj = tongchuan_towns.to_crs("EPSG:4544") # CGCS2000 3度带,中央经线105E附近 tongchuan_towns_proj["area_km2"] = tongchuan_towns_proj.geometry.area / 1e6 print(tongchuan_towns_proj[[name_col, "area_km2"]].sort_values("area_km2", ascending=False).head())to_crs那步是关键,直接在地理坐标系上算 area 得到的是平方度,没有物理意义。EPSG:4544 是 CGCS2000 3 度带 105°E 附近的带号,达州西部适用;如果数据偏东,可能要换 108°E 对应的带号。具体带号看 .prj 里的中央经线,别照抄。面积算完可以导出成 Excel 或 CSV,和民政公布的乡镇面积做交叉核对,差得离谱就说明坐标系或裁剪有问题。
3.4 导出 GeoJSON 给前端用
后端或前端要在地图上画乡镇界,shp 不能直接用,转 GeoJSON 最通用:
# 用 ogr2ogr 转 GeoJSON,指定输出坐标系为 WGS84 便于 web 地图 ogr2ogr -f GeoJSON -t_srs EPSG:4326 dazhou_township.geojson dazhou_township.shp-t_srs EPSG:4326把坐标转成 WGS84 经纬度,这是绝大多数 web 地图库(Leaflet、Mapbox、Cesium)默认吃的坐标系。如果原始数据是 CGCS2000 经纬度,和 WGS84 在达州这种尺度上差异很小,但严谨起见还是转一下。转出来的 GeoJSON 体积可能偏大,乡镇级几百个面要素,简化几何能显著减小文件,用 mapshaper 或 GeoPandas 的 simplify 都行,但简化比例别超过 0.01,否则边界会明显变形。
4. 避坑与排查:乡镇区划数据最容易翻车的五处
4.1 属性表中文乱码
现象:QGIS 或 GeoPandas 打开后,乡镇名称显示成????或閫氬窛这类乱码。原因:.dbf 的字符编码和读取时指定的编码不一致,老数据多为 GBK,新数据可能是 UTF-8,而 .cpg 文件缺失或写错。解决:先看有没有 .cpg,没有就手动试 encoding="gbk" 和 "utf-8",哪个读出正常中文用哪个;QGIS 里在图层属性中切换编码预览,确认后重新导出并补上 .cpg。
4.2 坐标系缺失导致图层对不上
现象:把乡镇 shp 和区县边界叠加,发现整体偏移几百米甚至几公里。原因:其中一个图层 .prj 缺失,软件按默认坐标系处理,或者两个图层一个经纬度一个投影。解决:用 ogrinfo 分别查两个图层的 SRS,统一到同一 CRS 再叠加。如果 .prj 丢了,按坐标数值范围判断后手动 set_crs,别用 define projection 硬套,那只是改标签不改数值。
4.3 乡镇名称重复导致关联错位
现象:用乡镇名称去 join 人口或 POI 数据,结果某些乡镇匹配到多条或匹配不上。原因:达州不同区县存在同名乡镇,或者名称里有空格、全半角括号差异。解决:关联时用行政区代码而不是名称,代码唯一;如果只有名称,先做标准化(去空格、统一括号),再按区县加名称做联合键。
4.4 边界自相交与几何无效
现象:做 overlay 或 buffer 时报 TopologyException 或 Geometry is invalid。原因:数字化或格式转换过程中产生自相交、悬挂节点。解决:用 GeoPandas 的gdf.geometry.is_valid检查,对无效几何做buffer(0)修复,或者用 shapely 的 make_valid。修复后再做空间运算,否则结果不可信。
4.5 要素数量与民政区划对不上
现象:统计出来乡镇数量比民政公布的多或少。原因:数据版本旧,区划调整后未更新;或者把街道和乡镇混在一起没区分。解决:拿最新区划名单核对,属性里如果有层级字段(如 LEVEL 或 TYPE),先按层级筛选。数据版本这件事没有后悔药,用之前一定确认时效。
5. 进阶:用乡镇 shp 做空间聚合与专题图
5.1 把 POI 点聚合到乡镇面
手里有一批达州的 POI 点,想统计每个乡镇的网点数量,标准做法是空间连接:
import geopandas as gpd poi = gpd.read_file("dazhou_poi.shp", encoding="gbk") towns = gpd.read_file("dazhou_township.shp", encoding="gbk") # 统一坐标系后再做空间连接 poi = poi.to_crs(towns.crs) joined = gpd.sjoin(poi, towns, how="left", predicate="within") # 按乡镇名称统计 POI 数量 count_by_town = joined.groupby(name_col).size().reset_index(name="poi_count") print(count_by_town.sort_values("poi_count", ascending=False).head(10))predicate="within"表示点落在面内才算,how="left"保留没匹配上的点便于排查。如果发现大量点匹配不上,多半是坐标系没统一,或者点本身落在乡镇边界外(比如水域)。统计结果可以再 join 回乡镇面,用 QGIS 做分级设色,出一张网点密度专题图。
5.2 用 matplotlib 快速出静态图
不想开 QGIS 的时候,GeoPandas 自带的 plot 就能出图:
import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(12, 10)) towns_proj.plot(column="poi_count", cmap="OrRd", legend=True, edgecolor="gray", linewidth=0.3, ax=ax) ax.set_title("达州市乡镇网点密度分布") ax.set_axis_off() plt.savefig("dazhou_township_density.png", dpi=200, bbox_inches="tight")column指定要映射的数值字段,cmap是色带,edgecolor描边让乡镇界清晰。中文标题需要提前设置字体,否则显示方块,matplotlib 里用plt.rcParams["font.sans-serif"] = ["SimHei"]解决。出图后重点看有没有异常高值或空白区,异常往往对应数据问题而不是真实分布。
5.3 一个我常做的校验习惯
每次拿到新的区划 shp,我都会强制走一遍三步:ogrinfo 看要素数和范围,QGIS 看属性表中文和坐标系,GeoPandas 算一遍总面积和官方公布面积对比。三步里任何一步对不上,就先停下来查原因,绝不带着疑问往下做。这套习惯帮我拦下过好几次坐标系错标和版本过期的问题。希望帮到你。
本文还有配套的精品资源,点击获取