【ArcGIS Pro二次开发】(65):进出平衡SHP转TXT、TXT转SHP

news2025/1/10 17:12:30

最近一个小伙伴提了这么一个需求,需要把TXT和SHP进行互转。

这种TXT文件其实遇到了好几个版本,都有一点小差异。之前已经做过一个TXT转SHP的工具,但好像不适用。于是针对这个版本,做了互转的2个工具。


【SHP转TXT】

一、要实现的功能

 

如上图所示,在【数据处理】组—【TXT相关】面板下,点击【进出平衡@SHP转TXT】工具。

在弹出的工具框中,分别输入参数:

1、输入SHP文件所在的文件夹。

2、输入TXT文件所在的文件夹。

3、这里不用填写,会自动列出【1】中所有的shp要素,不想转换的可以点复选框取消。

4、选择地块名称和地块用途,对应的字段值会写入TXT文件中。

生成结果如下:


二、实现流程

核心代码直接贴上,注释已经写得比较清楚了。

需要注意的是,这里获取要素的点集信息,我采取了通过要素的JSON文本来截取的做法,原因是不知道怎么用API来获取,所以用了这么个取巧的方法,以后要是学会了再改吧。这也是无奈之举,要学的东西还很多。

foreach (string fullPath in list_shpPath)
{
    // 初始化写入txt的内容
    string txt_all = "[地块坐标]" + "\r";

    string shp_name = fullPath[(fullPath.LastIndexOf(@"\") + 1)..];  // 获取要素名
    string shp_path = fullPath[..(fullPath.LastIndexOf(@"\"))];  // 获取shp名

    // 打开shp
    FileSystemConnectionPath fileConnection = new FileSystemConnectionPath(new Uri(shp_path), FileSystemDatastoreType.Shapefile);
    using FileSystemDatastore shapefile = new FileSystemDatastore(fileConnection);
    // 获取FeatureClass
    FeatureClass featureClass = shapefile.OpenDataset<FeatureClass>(shp_name);

    using (RowCursor rowCursor = featureClass.Search())
    {
        int featureIndex = 1;
        while (rowCursor.MoveNext())
        {
            using (Feature feature = rowCursor.Current as Feature)
            {
                // 获取地块名称,地块性质
                Row row = feature as Row;
                string ft_name = "";
                string ft_type = "";
                var areaName = row[field_mc];
                var areaType = row[field_yt];
                if (areaName != null) { ft_name = areaName.ToString(); }
                if (areaType != null) { ft_type = areaType.ToString(); }

                // 获取面要素的JSON文字
                Geometry polygon = feature.GetShape();
                string js = polygon.ToJson().ToString();

                // 解析JSON文字
                // 取坐标点文字
                string cod = js[(js.IndexOf("[[[") + 3)..js.IndexOf("]]]")];
                // 坐标点列表
                List<string> list_xy = cod.Split("]]").ToList();
                for (int i = 0; i < list_xy.Count; i++)
                {
                    // 坐标行
                    List<string> xy_detils = list_xy[i].Replace(",[[", "").Split("],[").ToList();

                    // 加一行title
                    int count = xy_detils.Count;    // 点的个数
                    string title = $"{count},{ft_name},面,{ft_type},@ " + "\r";
                    txt_all += title;

                    for (int j = 0; j < xy_detils.Count; j++)
                    {
                        // 点序号
                        int index = j + 1;
                        if (index == xy_detils.Count) { index = 1; }
                        // XY坐标点
                        string x = Math.Round(double.Parse(xy_detils[j].Split(",")[0]), 4).ToString();
                        string y = Math.Round(double.Parse(xy_detils[j].Split(",")[1]), 4).ToString();
                        // 加入文本
                        txt_all += $"J{index},{featureIndex},{x},{y}\r";
                    }
                }

            }
            featureIndex++;
        }
    }
    // 写入txt文件
    string txtPath = @$"{folder_txt}\{shp_name.Replace(".shp", "")}.txt";
    if (File.Exists(txtPath))
    {
        File.Delete(txtPath);
    }
    File.WriteAllText(txtPath, txt_all);
}

【TXT转SHP】

一、要实现的功能

 

如上图所示,在【数据处理】组—【TXT相关】面板下,点击【进出平衡@TXT转SHP】工具。

在弹出的工具框中,分别输入参数:

1、输入TXT文件所在的文件夹。

2、输入SHP文件所在的文件夹。

3、选择正确的坐标系。

4、这里不用填写,会自动列出【1】中所有的TXT文件,不想转换的可以点复选框取消。

生成结果如下:


二、实现流程

TXT转SHP之前已经已经写过一篇文章,可以参看:

【ArcGIS Pro二次开发】(41):勘测定界txt文件转数据库(批量)icon-default.png?t=N7T8https://blog.csdn.net/xcc34452366/article/details/131309938不过文章中用的TXT文件和今天这个有些不同,代码也就不一样,但思路是一致的。

这里只放核心代码,代码中用到一些自定义方法和之前是一样的引用,就不再一一放上:

foreach (string txtPath in list_txtPath)
{
    string shp_name = txtPath[(txtPath.LastIndexOf(@"\") + 1)..].Replace(".txt", "");  // 获取要素名

    pw.AddProcessMessage(@$"创建要素:{shp_name}", 10, time_base, Brushes.Black);

    // 创建一个空要素
    Arcpy.CreateFeatureclass(shpPath, shp_name, "POLYGON", spatial_reference);
    // 新建字段
    Arcpy.AddField(@$"{shpPath}\{shp_name}.shp", "地块名称", "TEXT");
    Arcpy.AddField(@$"{shpPath}\{shp_name}.shp", "地块性质", "TEXT");

    // 打开shp
    FileSystemConnectionPath fileConnection = new FileSystemConnectionPath(new Uri(shpPath), FileSystemDatastoreType.Shapefile);
    using FileSystemDatastore shapefile = new FileSystemDatastore(fileConnection);
    // 获取FeatureClass
    FeatureClass featureClass = shapefile.OpenDataset<FeatureClass>(shp_name);

    // 预设文本内容
    string text = "";
    // 获取txt文件的编码方式
    Encoding encoding = ToolManager.GetEncodingType(txtPath);
    // 读取【ANSI和UTF-8】的不同+++++++(ANSI为0,UTF-8为3)
    // 我也不知道具体原理,只是找出差异点作个判断,以后再来解决这个问题------
    int encoding_index = int.Parse(encoding.Preamble.ToString().Substring(encoding.Preamble.ToString().Length - 2, 1));

    if (encoding_index == 0)        // ANSI编码的情况
    {
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        using (StreamReader sr = new StreamReader(txtPath, Encoding.GetEncoding("GBK"))) { text = sr.ReadToEnd(); }
    }
    else if (encoding_index == 3)               // UTF8编码的情况
    {
        using (StreamReader sr = new StreamReader(txtPath, Encoding.UTF8)) { text = sr.ReadToEnd(); }
    }

    // 文本中的【@】符号放前
    string updata_text = ChangeSymbol(text);

    // 获取要素txt列表的地块标记
    List<string> Parts = GetParts(updata_text);

    for (int i = 0; i < Parts.Count; i++)
    {
        // 地块编号、地块性质
        string dkmc = "";
        string dkxz = "";

        // 根据换行符分解坐标点文本
        List<string> lines = Parts[i].Split("@").ToList();
        // 创建空坐标点集合
        var vertices_list = new List<List<Coordinate2D>>();

        for (int j = 1; j < lines.Count; j++)
        {
            var vertices = new List<Coordinate2D>();
            vertices_list.Add(vertices);
        }
        // 构建坐标点集合
        for (int k = 1; k < lines.Count; k++)
        {
            List<string> list_point = lines[k].Split("\r").ToList();
            foreach (var point in list_point)
            {
                if (!point.Contains(","))     // 跳过无坐标部份的文本
                {
                    continue;
                }
                else if (!point.StartsWith("J"))     // 名称、地块编号、功能文本
                {
                    dkmc = point.Split(",")[1];
                    dkxz = point.Split(",")[3];
                }
                else           // 点坐标文本
                {
                    double lat = double.Parse(point.Split(",")[2]);         // 经度
                    double lng = double.Parse(point.Split(",")[3]);         // 纬度
                    vertices_list[k - 1].Add(new Coordinate2D(lat, lng));    // 加入坐标点集合
                }
            }

        }

        /// 构建面要素
        // 创建编辑操作对象
        EditOperation editOperation = new EditOperation();
        editOperation.Callback(context =>
        {
            // 获取要素定义
            FeatureClassDefinition featureClassDefinition = featureClass.GetDefinition();
            // 创建RowBuffer
            using RowBuffer rowBuffer = featureClass.CreateRowBuffer();
            // 写入字段值
            rowBuffer["地块名称"] = dkmc;
            rowBuffer["地块性质"] = dkxz;

            PolygonBuilderEx pb = new PolygonBuilderEx(vertices_list[0]);
            // 如果有空洞,则添加内部Polygon
            if (vertices_list.Count > 1)
            {
                for (int i = 0; i < vertices_list.Count - 1; i++)
                {
                    pb.AddPart(vertices_list[i + 1]);
                }
            }
            // 给新添加的行设置形状
            rowBuffer[featureClassDefinition.GetShapeField()] = pb.ToGeometry();

            // 在表中创建新行
            using Feature feature = featureClass.CreateRow(rowBuffer);
            context.Invalidate(feature);      // 标记行为无效状态
        }, featureClass);

        // 执行编辑操作
        editOperation.Execute();
    }
    // 保存编辑
    Project.Current.SaveEditsAsync();
}

三、工具文件分享

我把工具都集合成工具箱,不再单独放单个工具,可以到这里下载完整工具箱,会不断更新:

【ArcGIS Pro二次开发】:CC工具箱icon-default.png?t=N7T8https://blog.csdn.net/xcc34452366/article/details/131506345PS:可以直接点击...bin\Debug\net6.0-windows\下的.esriAddinX文件直接安装。

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

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

相关文章

Nginx从入门到精通之Nginx应用场景和配置参数最佳实践

高级Nginx应用场景和配置技巧 文章目录 高级Nginx应用场景和配置技巧1. 配置参数最佳实践2. Nginx配置示例3. 常见场景1. 静态文件服务2. 动态内容代理3. SSL加密4. URL重写5. 访问控制6. 请求限制7. 日志记录8. 压缩9. 定向与错误页面10. 跨域配置11. 长连接处理12. 代理WebSo…

【文心一言大模型插件制作初体验】制作面试错题本大模型插件

文心一言插件开发初体验 效果图 注意&#xff1a;目前插件仅支持在本地运行&#xff0c;虽然只能自用&#xff0c;但仍然是一个不错的选择。&#xff08;什么&#xff1f;你说没有用&#xff1f;这不可能&#xff01;文心一言app可以支持语音&#xff0c;网页端结合手机端就可…

【算法与数据结构】654、LeetCode最大二叉树

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;【算法与数据结构】106、LeetCode从中序与后序遍历序列构造二叉树这两道题有些类似&#xff0c;相关代…

Anaconda虚拟环境下导入opencv

文章目录 解决方法测试 解决方法 1、根据自己虚拟环境对于的python版本与电脑对应的位长选择具体的版本&#xff0c;例如python3.9选择cp39&#xff0c;64位电脑选择64 下载地址&#xff1a;资源地址 若是不确定自己虚拟环境对应的python版本&#xff0c;可以输入下列命令&…

【启扬方案】启扬多尺寸安卓屏一体机,助力仓储物料管理系统智能化管理

随着企业供应链管理的不断发展&#xff0c;对仓储物料管理的要求日益提高。企业需要实时追踪和管理物料的流动&#xff0c;提高物流效率、降低库存成本和减少库存的风险。因此&#xff0c;仓储物料管理系统的实现成为必要的手段。 仓储物料管理系统一体机作为一种新型的物料管理…

Java中网络的基本介绍。网络通信,网络,ip地址,域名,端口,网络通信协议,TCP/IP传输过程,网络通信协议模型,TCP协议,UDP协议

- 网络通信 概念&#xff1a;网络通信是指通过计算机网络进行信息传输的过程&#xff0c;包括数据传输、语音通话、视频会议等。在网络通信中&#xff0c;数据被分成一系列的数据包&#xff0c;并通过网络传输到目的地。在数据传输过程中&#xff0c;需要确保数据的完整性、准…

【STM32】SPI初步使用 读写FLASH W25Q64

硬件连接 (1) SS( Slave Select)&#xff1a;从设备选择信号线&#xff0c;常称为片选信号线&#xff0c;每个从设备都有独立的这一条 NSS 信号线&#xff0c;当主机要选择从设备时&#xff0c;把该从设备的 NSS 信号线设置为低电平&#xff0c;该从设备即被选中&#xff0c;即…

0.96寸IIC-OLED屏幕

文章目录 一、硬件介绍1.1 0.96寸IIC-OLED屏幕1.2 主控1.3 取模工具 二、软件程序2.1 oled.c2.2 oled.h2.3 font.c2.4 font.h 一、硬件介绍 1.1 0.96寸IIC-OLED屏幕 1.2 主控 使用stm32f103c8t6单片机进行控制, IIC驱动使用软件模拟的方式。 1.3 取模工具 文字取模工具&…

算法通关村第10关【青铜】| 快速排序各种写法

思路&#xff1a; 指定一个数字&#xff0c;将数组比他小的放到左边&#xff0c;比他大的放到右边&#xff0c;实现归位 然后再指定一个数字递归&#xff0c;一直遍历完数组 最好的情况每次指定的都是中间位置的数字&#xff0c;划分完后两边长度相等&#xff0c;2T(n/2) O…

解决crosstalk的方法及原理分析

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 crosstalk是干扰线与受绕线之间由于信号跳变产生的耦合电容引起的。 解决crosstalk的方法从两方面入手,一方面降低耦合电容,一方面降低timing window的overlap。 静态时序分析: 串扰延迟分析 以…

Ubuntu入门05——磁盘管理与备份压缩

1.检查磁盘空间占用情况 2.统计目录或文件所占磁盘空间大小 3.压缩 3.1 zip、unzip和zipinfo 运行时发现上面命令不成功&#xff0c;换成&#xff1a; &#xff08;将文件lkw放入压缩文件lkw01.zip中&#xff09; sudo zip -m lkw01.zip lkw 解压文件&#xff1a; 实操&…

从RESP的角度理解事务和管道

1. RESP 是什么&#xff1f; 16 进制 0d 0a 就是 \r\n。 RESP 就是 Redis 服务端和客户端之间进行通信的协议&#xff0c;它是建立在 TCP 之上的一种简单的应用层协议。你可以把它理解成 HTTP 协议&#xff0c;不过它更加的简单。 它支持很多数据类型&#xff0c;这里列举几…

企业数字化转型的关键技术有哪些?_光点科技

随着科技的不断进步和信息技术的快速发展&#xff0c;企业数字化转型已经成为保持竞争力和适应市场变化的关键举措。在这个数字化时代&#xff0c;企业需要借助先进的技术来优化业务流程、提升效率&#xff0c;以及更好地满足客户需求。以下是企业数字化转型过程中的关键技术。…

4V-28V Vin,6A同步降压DCDC变换器,集成3.3V和150mA LDO——SCT2361FPBR

SCT2361是一种高效率的同步降压型DC-DC变换器&#xff0c;集成3.3V和150mA LDO。输入电压范围为4V-28V&#xff0c;输出电压可调为0.6V&#xff0c;具有3mmx3mm的小QFN封装&#xff0c;可提供连续6A的输出电流。该器件将高、低压侧功率mosfet集成&#xff0c;使导通损耗降到最低…

某次护网红队getshell的经历

信息收集 某企业提供信息&#xff1a;企业官网的真实外网ip&#xff0c;内网ip 企业官网比较硬&#xff0c;从控股超过51%的子公司入手 通过企查查找到一堆控股高的子公司&#xff0c;通过ICP/IP地址/域名信息备案管理系统查找子公司官网&#xff0c;收集二级域名。通过google…

Linux 调试技术 Kprobe

目录 用途&#xff1a;一、技术背景1.1 kprobes的特点与使用限制1.2 kprobe原理 二、 基于kprobe探测模块的探测方式2.1、struct kprobe结构体2.2 kprobe API函数2.3 示例代码参考资料&#xff1a; 用途&#xff1a; 判断内核函数是否被调用&#xff0c;获取调用上下文、入参以…

『SpringBoot 源码分析』run() 方法执行流程:(2)刷新应用上下文-准备阶段

『SpringBoot 源码分析』run() 方法执行流程&#xff1a;&#xff08;2&#xff09;刷新应用上下文-准备阶段 基于 2.2.9.RELEASE问题&#xff1a;当方法进行了注释标记之后&#xff0c;springboot 又是怎么注入到容器中并创建类呢&#xff1f; 首先创建测试主程序 package …

第49节:cesium 倾斜模型osgb转3dtiles,并加载(含源码+视频)

结果示例: 完整步骤: 1、启动并登陆cesiumlab 2、准备OSGB模型数据(含下载地址) 链接:https://pan.quark.cn/s/46ac7b0b2bed 提取码:TvWL3、倾斜模型切片 选择倾斜模型data文件夹 空间参考、零点坐标 默认 强制双面关闭、无光照 打开

天津和则百顺国际贸易有限公司被选为中国自主创新企业

在2023年4月,天津和则百顺国际贸易有限公司凭借在全国自主创新企业宣传推广活动中的出色表现,经过相关单位审核,正式被评选为中国自主创新企业,并荣获《中国自主创新企业》荣誉证书。 作为始终走在中国自主创新前沿的企业,天津和则百顺国际贸易有限公司,以下简称和则百顺,对于获…

console.log封装,显示调用的位置

背景 一般我们都哦说直接调用console.log&#xff0c;但是有时候console.log太多了&#xff0c;非常影响效率&#xff0c;我们想统一开启console.log&#xff08;不是生产环境移除console.log&#xff09; 可能封装的代码是这样 window.mylog()>conosle.log但是控制面板哪…