【ArcGIS Pro二次开发】(23):用地编码和用地名称的规范性检查

在国空或村庄规划的编制过程中,随着规划用地的调整,经常会手动修改用地编码和用地名称,不可避免的会出现错误,如果单靠人工校对,累人又不能保证准确性。这个工具的目的就是检查用地编码和用地名称是否规范,二者是否一一对应。

【ArcGIS Pro二次开发】(23):用地编码和用地名称的规范性检查_第1张图片


一、要实现的功能

【ArcGIS Pro二次开发】(23):用地编码和用地名称的规范性检查_第2张图片

如上图所示,右键点击地图中的要素图层,点击【检查用地用海字段】按钮,打开工具框,选择图层的用地编码字段和用地名称字段,点击运行即可。

运行结果如下图:

【ArcGIS Pro二次开发】(23):用地编码和用地名称的规范性检查_第3张图片

要素会新增一个【用地用海检查】字段,用地编码和用地名称的规范性错误会列在字段里。


二、实现流程

创建ProWindow工具框等基础功能可以参看往期文章,这里只把实现核心功能的流程列举出来。

1、通过嵌入的Excel资源文件获取用地用海分类

在往期的文章用到一种方法,使用【字典(Dictionary)创建表格(Table)】来获取用地用海分类。这个方法有点麻烦,需要编辑字典,遇上复杂的表格不好操作。

这里采用另一个方法,使用嵌入式的文件的方式,直接从Excel文件中读取。

首先需要将Excel文件的生成操作设置为【嵌入的资源】,然后从资源中读取。

【ArcGIS Pro二次开发】(23):用地编码和用地名称的规范性检查_第4张图片

我这里不采用直接读取的方式,为了保险一点(可能没有必要),先把资源里的文件复制到本地,再从本地读取,代码如下:

            // 复制资源文件
            string folder = Project.Current.HomeFolderPath;
            string excelPath = @"用地用海_DM_to_MC.xlsx";
            string outputPath = System.IO.Path.Combine(folder, excelPath);  
            string resourceName = @"CheckFieldYDYH." + excelPath;    

            // 获取当前程序集的实例
            Assembly assembly = Assembly.GetExecutingAssembly();
            // 从嵌入资源中读取文件
            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
            {
                // 创建目标文件
                using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
                {
                    // 将文件从嵌入资源复制到目标文件
                    stream.CopyTo(outputPath );
                }
            }

在这个案例中,我们要读取Excel文件的内容是第一列和第二列的值,并将其输出成一个字典(Dictionary)即可。

【ArcGIS Pro二次开发】(23):用地编码和用地名称的规范性检查_第5张图片

代码如下:

            // 建立 Excel 应用程序对象
            Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
            // 打开 Excel 文件
            Workbook workbook = excelApp.Workbooks.Open(excelPath);
            // 获取工作表
            Worksheet worksheet = workbook.Worksheets[1];
            // 定义字典
            Dictionary dict = new Dictionary();
            // 获取Excel表格中的数据
            for (int row = 1; row <= worksheet.UsedRange.Rows.Count; row++)
            {
                string key = worksheet.Cells[row, col1].Value.ToString();
                string value = worksheet.Cells[row, col2].Value.ToString();
                dict.Add(key, value);
            }
            //  保存并关闭 Excel 文件和应用程序对象
            workbook.Close(true);
            excelApp.Quit();

至此,就实现了从Excel资源文件中读取数据并输出为字典(Dictionary)。

2、将目标字段值中的空值【null】转换为【空字符串】

下一步正常就该开始编辑属性表,但为了保证数据计算安全,这里再做了一件事,将2个目标字段值中的空值【null】转换为【空字符串】,这也是被空值坑过多次之后,我现在几乎都会做这个预处理。代码如下:

            // 获取所选图层的所有字段
            var fields = await QueuedTask.Run(() =>
            {
                return initlayer.GetFieldDescriptions();
            });

            // 使用异步任务在后台进行编辑操作
            await QueuedTask.Run(() =>
            {
                // 打开要素图层的表格
                var table = initlayer.GetTable();
                // 定位到属性表的游标
                using (var tableCursor = table.Search(null, false))
                {
                    while (tableCursor.MoveNext())
                    {
                        // 获取当前记录的值
                        var row = tableCursor.Current;
                        // 历数所有字段
                        foreach (var field in fields)
                        {
                            // 排除不可编辑的字段
                            if (field.IsReadOnly == false)
                            {
                                // 如果是字符串类型,则进行下一步
                                if (field.Type == FieldType.String)
                                {
                                    var currentValue = row[field.Name];
                                    if (currentValue is null)
                                    {
                                        currentValue = "";
                                    }
                                    // 更新该字段的值
                                    row[field.Name] = currentValue;
                                    row.Store(); // 保存修改
                                }
                            }
                        }
                    }
                }
            });

3、新建检查字段,并通过属性表编辑计算字段值

新建一个【用地用海检查】字段,打开当前选择的的要素图层的属性表进行编辑。

计算逻辑如下:

1)分别针对2个字段,通过【new List(dict.Keys).Contains(bm)】判断该字段值是否在用地用海分类的规范命名范围内,如果不在范围内,刚输出错误信息。

2)如果2个字段都满足规范,则通过【dict[bm.ToString()] != mc.ToString()】判断用地编码和用地名称是否一一对应,如果有误,则输出错误信息。

3)最后给【用地用海检查】字段赋值即可。


三、工程文件分享

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

CheckFieldYDYHicon-default.png?t=N3I4https://pan.baidu.com/s/1aumM78dtntI5an6HVl3owg?pwd=i3qd

PS:可以直接点击...bin\Debug\net6.0-windows\下的.esriAddinX文件直接安装。

你可能感兴趣的:(ArcGIS,ArcGIS,Pro,SDK,arcgis,c#,二次开发,arcgis,pro,sdk,用地用海字段检查)