【ArcGIS Pro二次开发】(33):合并文件夹下的所有shp文件

news2024/11/25 4:58:30

在工作中,即使很不喜欢用shp文件,但还是经常会收到shp格式的文件。关于shp文件的吐糟就不多说了,除了文件小、字段名长度限制,不能储存弧线段等问题,还有一种处理方式也让人很是难受。

如上图,有些shp文件是分散在不同的文件夹里的,虽然方便了文件的分散传送,但没法像数据库一样统计管理,用起来很不方便。

这个工具的目的就是处理这一类型的文件,将分散的shp文件合并成一个数据库要素,并且保留文件名,转换成一个标记字段的字段值。


一、要实现的功能

如上图所示,点击【合并 shp文件】按钮,输入shp文件所在的文件夹和输出要保存的要素类的位置(上图中路径显示不全,要保存为数据库的要素类),点击【执行】即可。

生成的结果如下:

生成结果新增了2个字段,【SHP名称】是shp文件的文件名,【SHP路径】是shp文件的相对路径。

这样做是为了尽可能的保留shp文件的信息。尤其是【SHP路径】,可能包含了图斑所在的分区、类型等信息,将路径保留下来,方便后续更多信息的读取。


二、实现流程

1、复制shp文件夹下的所有内容

由于后续需要对shp原文件进行添加字段、计算字段等操作,为了避免对原文件的改动和破坏,这里首先复制了shp文件夹下的所有内容,作为后续处理的数据。

        // 复制文件夹下的所有文件到新的位置
        public static void CopyAllFiles(string sourceDir, string destDir)
        {
            //目标目录不存在则创建
            if (!Directory.Exists(destDir))
            {
                Directory.CreateDirectory(destDir);
            }
            DirectoryInfo sourceDireInfo = new DirectoryInfo(sourceDir);
            List<FileInfo> fileList = new List<FileInfo>();
            GetFileList(sourceDireInfo, fileList); // 获取源文件夹下的所有文件
            List<DirectoryInfo> dirList = new List<DirectoryInfo>();
            GetDirList(sourceDireInfo, dirList); // 获取源文件夹下的所有子文件夹
            // 创建目标文件夹结构
            foreach (DirectoryInfo dir in dirList)
            {
                string sourcePath = dir.FullName;
                string destPath = sourcePath.Replace(sourceDir, destDir); // 替换源文件夹路径为目标文件夹路径
                if (!Directory.Exists(destPath))
                {
                    Directory.CreateDirectory(destPath); // 创建目标文件夹
                }
            }
            // 复制文件到目标文件夹
            foreach (FileInfo fileInfo in fileList)
            {
                string sourceFilePath = fileInfo.FullName;
                string destFilePath = sourceFilePath.Replace(sourceDir, destDir); // 替换源文件夹路径为目标文件夹路径
                File.Copy(sourceFilePath, destFilePath, true); // 复制文件,允许覆盖目标文件
            }
        }

        // 递归获取文件列表
        private static void GetFileList(DirectoryInfo dir, List<FileInfo> fileList)
        {
            fileList.AddRange(dir.GetFiles()); // 添加当前文件夹下的所有文件
            foreach (DirectoryInfo directory in dir.GetDirectories())
            {
                GetFileList(directory, fileList); // 递归获取子文件夹下的文件
            }
        }

        // 递归获取子文件夹列表
        private static void GetDirList(DirectoryInfo dir, List<DirectoryInfo> dirList)
        {
            dirList.AddRange(dir.GetDirectories()); // 添加当前文件夹下的所有子文件夹

            foreach (DirectoryInfo directory in dir.GetDirectories())
            {
                GetDirList(directory, dirList); // 递归获取子文件夹下的子文件夹
            }
        }

这里采用了递归的方式获取文件列表和子文件夹列表。按原文件夹的目录创建了新的文件夹,并且把文件按原位置一个一个复制过去。

这部分代码我也没仔细研究,网上现成的代码很多,抄了一段直接用了。

2、获取文件夹下的所有shp文件

1个shp要素其实包含了很多文件,但我们只需要后缀名为shp的文件即可。

按关键字获取特定文件的方法如下:

        // 获取输入文件夹下的所有文件
        public static List<string> GetAllFiles(string folder_path, string key_word ="no match")
        {
            List<string> filePaths = new List<string>();

            // 获取当前文件夹下的所有文件
            string[] files = Directory.GetFiles(folder_path);
            // 判断是否包含关键字
            if (key_word == "no match")
            {
                filePaths.AddRange(files);
            }
            else
            {
                foreach (string file in files)
                {
                    // 检查文件名是否包含指定扩展名
                    if (Path.GetExtension(file).Equals(key_word, StringComparison.OrdinalIgnoreCase))
                    {
                        filePaths.Add(file);
                    }
                }
            }

方法引用:

// 获取所有shp文件
var files = ToolManager.GetAllFiles(shp_path, ".shp");

3、分别对单个shp文件单独新建标记字段,并赋值

                    // 获取路径标签
                    string tab = folder_path.Substring(folder_path.LastIndexOf(@"\") + 1);
                    // 分解文件夹目录,获取文件名和路径字段值
                    foreach (var file in files)
                    {
                        // 获取名称和路径
                        string short_path = file.Replace(def_path + @"\", "");
                        int index0 = short_path.IndexOf(@"\");            // 第一个【"\"】的位置
                        int index1 = short_path.LastIndexOf(@"\");      // 最后一个【"\"】的位置
                        int index2 = short_path.LastIndexOf(@".shp");  // 最后一个【".shp"】的位置
                        string name = short_path.Substring(index1 + 1, index2 - index1 - 1);
                        string path = tab + @"\" + short_path.Substring(index0 + 1, index1 - index0 - 1);
                        // 添加2个标记字段
                        Arcpy.AddField(file, @"SHP名称", "TEXT");
                        Arcpy.AddField(file, @"SHP路径", "TEXT");
                        Arcpy.CalculateField(file, @"SHP名称", "\"" + name + "\"");
                        Arcpy.CalculateField(file, @"SHP路径", "\"" + path + "\"");
                    }

这里主要是对字符串的切割,从绝对路径中获取要素名和相对路径。

不得不说,python在这方面比C#方便和灵活得多,有点怀念python。

获取所要的信息后,就可以将值赋给要素了。

PS:这里采用了GP工具来处理,其实挺不好,运行速度比较慢,如果碰上几百上千个要素,可能要等挺久。后面如果想到别的办法再来优化吧。(真的是边学边做,每过一个阶段回头看前面自己写的代码都像屎...)

最后将所有的shp要素合并即可:

// 合并要素
Arcpy.Merge(files, featureClass_path);

最后把复制出来的文件夹删掉:

// 删除复制的shp文件夹
Directory.Delete(shp_path, true);

以上就是工具的核心代码,完整代码请查看后面放出的工程文件。

需要注意的是为了不同工程的调用方便,一些通用方法我放到了几个类文件中。


三、工程文件分享

 最后,放上工程文件的链接:

MergeSHPhttps://pan.baidu.com/s/1huEMRaDnxeVT3zHLonV6bw?pwd=2kgrPS:可以直接点击...bin\Debug\net6.0-windows\下的.esriAddinX文件直接安装。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/613282.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

挂起、激活单个流程实例

类&#xff1a;com.roy.ActivitiBusinessDemo/*** 挂起、激活单个流程实例*/Testpublic void suspendSingleProcessInstance(){ // 1、获取流程引擎ProcessEngine processEngine ProcessEngines.getDefaultProcessEngine(); // 2、RuntimeServiceRuntimeService…

Flowable开始事件-空开始事件

文章目录 空开始事件一、开始事件的定义1、图形标记2、XML内容3、使用示例 总结 空开始事件 利用空开始事件发起流程 一、开始事件的定义 空开始事件意味着没有指定启动流程实例的触发条件。它是最常见的一种开始事件&#xff0c;一般需要人工启动或通过api启动 1、图形标记…

最系统的网络安全自学笔记+学习路线(超详细)

01 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面…

职场工作的前提

职场工作 目录概述需求&#xff1a; 设计思路实现思路分析1.职场工作 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wait for change,challenge Survive.…

自动攻丝机(比例随动控制应用)

比例随动控制的详细介绍,可以参看下面的文章链接: 运动控制比例随动系统_RXXW_Dor的博客-CSDN博客PLC如何测量采集编码器的位置数据,不清楚的可以参看我的另一篇博文:三菱FX3U PLC高速计数器应用(附代码)_RXXW_Dor的博客-CSDN博客本文主要以三菱FX3U系列的高速计数为例来…

数据库期末复习(9.1)故障恢复到检查点之前

故障的分类 事务故障 系统故障 存储介质故障 只能通过故障来实现. 故障恢复 缓冲池策略 STEAL和FORCE策略:具体内容见课件。 为啥要使用steal和force两种策略 原因&#xff1a;如果不用steal策略 缓冲区就会有大量的脏页&#xff0c;如果使用not force策略 由于对同一个对…

R语言多线程提高计算速度,如何使用foreach包加速并行计算

R语言多线程加速 通常情况下&#xff0c;R语言只能使用一个线程来进行计算&#xff0c;因此计算的速度及其感人&#xff01; 最近刚好有一个需求&#xff1a;我有一个参考数据表&#xff0c;里面存放了30万条基因的名称和位置信息&#xff0c;现在我想从里面找到指定的6000个基…

C++程序员的待遇怎么样?我来谈谈学好C++的五个关键点

有个学弟跟我谈到这样一个问题&#xff1a;现在我看到网上很多人都在讲&#xff0c;说这个做C程序员&#xff0c;尤其是本科毕业计算机专业&#xff0c;然后步入社会之后就能拿到月入过万。但是为什么自己找的这个工作啊&#xff0c;普遍在月薪六七千块钱左右&#xff0c;也就是…

一图看懂 werkzeug 模块:是一个全面的WSGI web应用程序库,最先进的WSGI实用程序库之一,资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 werkzeug 模块&#xff1a;是一个全面的WSGI web应用程序库&#xff0c;最先进的WSGI实用程序库之一&#xff0c;资料整理笔记&#xff08;大全&#xff09; &#x1f9ca;…

强连通分量-tarjan算法缩点

一. 什么是强连通分量&#xff1f; 强连通分量&#xff1a;在有向图G中&#xff0c;如果两个顶点u,v间&#xff08;u->v&#xff09;有一条从u到v的有向路径&#xff0c;同时还有一条从v到u的有向路径&#xff0c;则称两个顶点强连通(strongly connected)。如果有向图G的每…

Linux - 第24节 - Linux高级IO(二)

1.I/O多路转接之select 1.1.select初识 select是系统提供的一个多路转接接口。 • select系统调用可以让我们的程序同时监视多个文件描述符的上的事件是否就绪。 • select的核心工作就是等&#xff0c;当监视的多个文件描述符中有一个或多个事件就绪时&#xff0c;select才会…

Selenium Python 自动抓取个股数据

Selenium是广泛使用的开源Web UI&#xff08;用户界面&#xff09;自动化测试套件之一。支持Chrome, Edge, Firfox等常见浏览器&#xff0c;Selenium Python库也是python对web应用进行自动化测试的非常有用的工具。 Selenium 还适合用于抓取Javascript 动态网页数据。 本文演…

Spring Bean、XML方式Bean配置、Bean实例化配置、Bean注入

文章目录 Bean管理一、SpringBoot Bean 初了解1.1 了解1.2 Bean的作用域1.2.1 注意事项 1.3 第三方Bean 二、 基于XML方式Bean的配置2.1 SpringBean配置概览2.2 bean id class 配置2.3 bean name 别名配置2.4 bean scope 作用范围2.5 bean 延迟加载2.6 bean 初始化与销毁方法配…

数据结构中的顺序表的实现

文章目录 前言一、初识数据结构二、顺序表的实现&#xff08;类型一&#xff09;1.顺序表的头文件2.顺序表的实现 三、顺序表的实现&#xff08;类型二&#xff09;1 顺序表头文件2 顺序表的实现 四、线性表&#xff08;顺序表&#xff09;的缺点总结 前言 本期就进入到我们数据…

[前端语法]js原型链有关的继承问题

深夜反而思维更活跃一些 (1)js中的原型链 js中存在一个名为原型链的机制,其特点如下 加入一个方法A,A方法一个属性为prototype,这个属性会指向某个对象,也成为A类对象的原型对象. 当我们根据A这个方法生成一个对象a,那么a的原型(proto)属性即为这个对象 a可以调用一些原型…

【cropperjs】优秀、优雅的前端图片裁剪库

下载 npm i cropperjsnpm官网- https://www.npmjs.com/package/cropperjs cropperjs关键参数 aspectRatio 图片裁剪比例 默认值 &#xff1a;NaN作用&#xff1a;图片裁剪比例值&#xff1a;自定义裁剪比例&#xff0c;例如1 / 1 , 4 / 3 , 16 / 9等 viewMode 裁剪模式 默认…

代码随想录算法训练营第二十七天| 39. 组合总和、 40.组合总和II、 131.分割回文串

组合总数 题目链接&#xff1a;力扣 这题和之前题目的区别在于&#xff0c;本题没有数量要求&#xff0c;可以无限重复的取某一元素&#xff0c;但是对元素的总和有限制&#xff0c;这就说明了递归的限制不在于层数&#xff0c;而是选取元素的总和超过target就返回 终止条件为…

【owt】WebrtcNode, subscirbe-sdp offer 流程(2)

流程图 创建MediaStream&#xff0c; MediaStream一方面作为从VideoFramePacketizer接收到媒体数据&#xff1b; 创建VideoFramePacketizer&#xff0c;MediaStream 把sink 注册到VideoFramePacketizer&#xff0c;这样VideoFramePacketizer&#xff08;继承了MediaSource&…

upload靶场通关(12-21关)

Pass-12&#xff08;白名单校验&#xff08;GET 型 0x00 截断&#xff09;&#xff09; 先看提示&#xff1a; 一头雾水&#xff0c;只知道了上传路径是可控的 查看源码&#xff1a; 能看懂就看看&#xff0c;反正我是看了同学的笔记得知这是白名单&#xff0c;按照文件名进行…

Customizable constraint systems for succinct arguments学习笔记(1)

1. 引言 微软研究中心Srinath Setty、a16z crypto research 和 Georgetown University Justin Thaler、Carnegie Mellon University Riad Wahby 20203年论文《Customizable constraint systems for succinct arguments》。 在该论文中&#xff0c;介绍了Customizable constra…