当前位置: 首页 > news >正文

用 ArcPy 批量拆分并投影 Shapefile:自动分组导出 + 合并输出

用 ArcPy 批量拆分并投影 Shapefile:自动分组导出 + 合并输出

用 ArcPy 批量拆分并投影 Shapefile:自动分组导出 + 合并输出实战教程

背景介绍

在日常 GIS 工作中,我们经常会遇到这样的需求:

  • 一个图层(shp 或 gdb 要素类)里包含很多地块数据;
  • 需要按照某个字段(比如项目名称)分组拆分成多个 shp 文件
  • 每个组里还要再按照另一个字段(比如编号)单独导出;
  • 最后再把每个组内的数据合并成一个总 shp;
  • 同时还要统一投影到指定坐标系

如果手动在 ArcGIS 里一个个“选择 → 导出 → 合并”,数据一多会非常崩溃。

本文这段 Python 代码可以帮你:

✅ 自动投影到 CGCS2000 GK CM 111E(EPSG:4547)
✅ 按字段分组拆分 shp
✅ 每个编号单独生成 shp
✅ 自动生成每组的合并 shp
✅ 自动创建文件夹结构

运行完成后,你会看到:

矿山子项目/
├── 组A/
│   ├── BSM_001.shp
│   ├── BSM_002.shp
├── 组B/
│   ├── BSM_010.shp
├── 合并/
│   ├── 组A.shp
│   ├── 组B.shp

整个流程一键完成,非常适合:

  • 批量地块拆分
  • 矿山项目分区
  • 按行政区分图
  • 大数据批处理

下面我们一步步带你跑起来。


代码功能说明

这段代码主要做 5 件事:

  1. 将输入图层投影到 EPSG:4547
  2. 读取字段 ziname(作为分组字段)
  3. zibianhao(编号字段)拆分为多个 shp
  4. 每组自动生成一个文件夹
  5. 把每组内的 shp 再合并成一个总 shp

简单理解:

它就像一个“自动文件分拣员 + 打包员”。


运行环境准备

1️⃣ 必须安装的软件

  • ArcGIS Pro
  • ✅ 自带 Python(ArcPy)

⚠️ 注意:
arcpy 只能在 ArcGIS 环境中使用,普通 Python 是跑不了的。


详细运行步骤

我们按标准流程来:


第一步:打开 ArcGIS Pro Python 环境

  1. 打开 ArcGIS Pro
  2. 点击右上角 → Python
  3. 打开 Python Command Prompt

或者使用:

C:\Program Files\ArcGIS\Pro\bin\Python\Scripts\proenv.bat

你会看到类似:

(base) C:\Users\【username】>

第二步:创建 Python 文件

  1. 新建一个文本文件
  2. 改名为:
split_shp.py
  1. 把下面代码复制进去

核心代码(已去除私人路径)

import arcpy
import os
import re# ------------------- 文件名合法化函数 -------------------
def clean_filename_for_shp(name, prefix="m_"):"""为合并文件生成合法 shp 名称,保留中文、数字、字母"""name = re.sub(r'[\\/:*?"<>|]', "_", str(name))name = re.sub(r"\s+", "_", name)name = re.sub(r"_+", "_", name).strip("_")if len(name) == 0:name = prefix + "unknown"return name[:50]def clean_name(name, prefix="fc_"):"""生成 ArcGIS 合法 shp 名称(仅 ASCII)"""name = re.sub(r'[^A-Za-z0-9_]+', "_", str(name))if re.match(r'^[0-9]', name):name = prefix + namename = re.sub(r'_+', "_", name).strip("_")if len(name) == 0:name = prefix + "unknown"return name[:50]def clean_group_name(name):"""为组文件夹生成合法名称"""name = re.sub(r'[\\/:*?"<>|]', "_", str(name))name = re.sub(r"\s+", "_", name)name = re.sub(r"_+", "_", name).strip("_")if len(name) == 0:name = "unknown_group"return name[:50]# ------------------- 主函数 -------------------
def split_and_project_shp(input_fc, output_root):arcpy.env.overwriteOutput = Truetarget_sr = arcpy.SpatialReference(4547)ZXMMC_field = "ziname"BSM_field = "zibianhao"temp_folder = os.path.join(output_root, "temp")os.makedirs(temp_folder, exist_ok=True)projected_fc = os.path.join(temp_folder, "projected.shp")print("正在投影...")arcpy.Project_management(input_fc, projected_fc, target_sr)ZXMMC_values = sorted(set(r[0] for r in arcpy.da.SearchCursor(projected_fc, [ZXMMC_field])))oid_field = arcpy.Describe(projected_fc).OIDFieldNamemerge_root = os.path.join(output_root, "合并")os.makedirs(merge_root, exist_ok=True)for value in ZXMMC_values:safe_value = clean_group_name(str(value))group_folder = os.path.join(output_root, safe_value)os.makedirs(group_folder, exist_ok=True)where = f"{ZXMMC_field} = '{value}'"bsm_to_oids = {}with arcpy.da.SearchCursor(projected_fc, [oid_field, BSM_field], where_clause=where) as cursor:for oid, bsm in cursor:bsm_to_oids.setdefault(str(bsm), []).append(oid)shp_list = []for bsm, oid_list in bsm_to_oids.items():safe_bsm = clean_name(str(bsm), prefix="BSM_")out_shp = os.path.join(group_folder, f"{safe_bsm}.shp")if len(oid_list) == 1:where_clause = f"{oid_field} = {oid_list[0]}"else:where_clause = " OR ".join([f"{oid_field} = {oid}" for oid in oid_list])arcpy.Select_analysis(projected_fc, out_shp, where_clause)shp_list.append(out_shp)merge_shp_name = clean_filename_for_shp(str(value)) + ".shp"merge_shp_path = os.path.join(merge_root, merge_shp_name)if len(shp_list) > 1:arcpy.Merge_management(shp_list, merge_shp_path)elif len(shp_list) == 1:arcpy.CopyFeatures_management(shp_list[0], merge_shp_path)print("全部完成!")# ------------------- 执行 -------------------
input_fc = r"D:\【your_folder】\shp.gdb\patch2"
output_root = r"D:\【your_folder】\output"split_and_project_shp(input_fc, output_root)

第三步:修改输入路径(非常重要)

修改这里:

input_fc = r"D:\【your_folder】\shp.gdb\patch2"
output_root = r"D:\【your_folder】\output"

说明:

  • input_fc → 你的 gdb 要素类路径
  • output_root → 输出文件夹路径

⚠️ 注意:必须使用 原始字符串 r"路径"


第四步:运行脚本

进入脚本所在目录:

cd D:\【your_folder】

执行:

python split_shp.py

如果看到:

正在投影...
全部完成!

说明成功。


第五步:验证结果

打开输出文件夹,你会看到:

  • 每个组一个文件夹
  • 每个编号一个 shp
  • 合并文件在 “合并” 文件夹里

核心代码解析(大白话版本)

① 投影

arcpy.Project_management(input_fc, projected_fc, target_sr)

👉 就像“给地图换一个坐标系统”。


② 读取分组字段

SearchCursor(projected_fc, [ZXMMC_field])

👉 就像逐行翻表格,找出所有项目名称。


③ 按编号拆分

Select_analysis(...)

👉 相当于在 ArcGIS 里手动“选择 → 导出”。


④ 合并

Merge_management(...)

👉 把一堆小 shp 打包成一个大 shp。


⑤ 文件名清洗

re.sub(...)

👉 防止文件名包含非法字符导致报错。


常见问题解决

❌ 1. ModuleNotFoundError: No module named 'arcpy'

原因:

  • 没在 ArcGIS Python 环境运行

解决:

  • 使用 ArcGIS Pro 自带 Python

❌ 2. ERROR 000732: Dataset does not exist

原因:

  • 路径写错

解决:

  • 右键要素类 → 属性 → 复制完整路径

❌ 3. 字段不存在

原因:

ZXMMC_field = "ziname"

字段名写错。

解决:

  • 打开属性表 → 核对字段名

❌ 4. 输出文件夹没有生成

原因:

  • 磁盘没有写入权限

解决:

  • 改到 D 盘或桌面目录

总结

这段代码帮你完成了:

✔ 自动投影
✔ 按字段分组
✔ 批量拆分 shp
✔ 自动合并
✔ 自动创建目录

如果数据量很大,它能帮你节省几个小时甚至几天的重复劳动。

对于 GIS 批处理来说,这已经是一个非常实用的自动化脚本。

你现在可以:

  1. 修改字段名
  2. 修改坐标系
  3. 批量处理更多数据

慢慢你就会发现:

Python 是 GIS 工作者真正的效率工具。

http://www.jsqmd.com/news/387406/

相关文章:

  • jar 包又冲突了?如何快速确定与哪个 jar 包冲突?
  • 因为 BitMap,白白搭进去 8 台服务器
  • 受聘为2026年度中国知网评审专家库专家
  • 三、Claude Opus 4.6 三体银河纪元 -1
  • 一文搞懂告别繁琐命令行:自研多线程 SSH 极速文件传输助手(附 GitHub 源码):核心原理+实战案例
  • 彻底干掉恶心的 SQL 注入漏洞,一网打尽!
  • 题解:洛谷 P2669 [NOIP 2015 普及组] 金币
  • 一个小小的签到功能,到底用 MySQL 还是 Redis?
  • 题解:洛谷 P1035 [NOIP 2002 普及组] 级数求和
  • 求求你,别在 MySQL 中使用 UTF-8了!
  • 吐血推荐!更贴合专科生的AI论文网站,千笔·专业学术智能体 VS 灵感ai
  • 面试官:什么是 NIO?NIO 的原理是什么机制?
  • 赶deadline必备AI论文网站 千笔AI VS 学术猹 研究生专属神器
  • 高级玩家必备:深度剖析 MySQL 事务隔离!
  • 题解:洛谷 P1980 [NOIP 2013 普及组] 计数问题
  • 题解:洛谷 P1009 [NOIP 1998 普及组] 阶乘之和
  • 少走弯路:专科生专属降AIGC工具 千笔·专业降AI率智能体 VS 万方智搜AI
  • 基于FPGA的视频缩放算法:4K2K输入与输出,缩放参数可控
  • 闭眼入!9个AI论文工具测评:本科生毕业论文写作全攻略
  • 好用还专业! 降AIGC平台 千笔·降AI率助手 VS 学术猹 MBA首选
  • 交稿前一晚!9个AI论文工具测评:研究生毕业论文+学术写作全攻略
  • 摆脱论文困扰! AI论文网站 千笔写作工具 VS 学术猹,自考首选!
  • 题解:洛谷 P5721 【深基4.例6】数字直角三角形
  • 光伏mppt电导增量法mppt模型,可以实现最大功率电的追踪,模型可以正常运行,可拓展性强
  • 最近在搞综合能源系统规划,发现双层优化建模挺有意思。今天咱们就来聊聊怎么用双层模型搞定微电网的多电源容量配置,手把手带你撸一遍代码实现
  • 快递小车自动避人配送,识别行人优先避让,小区配送,输出平稳送达。
  • SpringBoot 的启动引导类真的是 XXApplication 吗?
  • RISC(Reduced Instruction Set Computing,精简指令集计算机)和CISC(Complex Instruction Set Computing,复杂指令集计算机)
  • 面试官:给我说一下 Spring MVC 拦截器的原理?
  • 流量思维向长效思维转型:开源链动2+1模式AI智能名片小程序赋能私域电商品牌建设