【ArcGIS Pro二次开发】(25):属性映射

news/2024/11/29 2:50:08/

属性映射经常用于属性表或Excel表的赋值,比如按用地用海表对规划用地的用地编码或用地名称赋值,将汇总好的用地指标表赋值给已经制好的Excel模板等。

下面试着在ArcGIS Pro SDK中实现功能上述这两个功能。


一、Excel表格映射到属性表Table

1、要实现的效果

如上图所示,打开【Excel表格映射到Table】工具框,选择输入的要素图层,如【规划用地】,接着输入参照字段和映射字段,最后打开用来映射的Excel表,注意这里打开的Excel表是到【sheet】级的。

点击执行,效果如下:

生成结果中,映射字段会按照映射表的对应键值一一赋值,如果参照字段不在映射表中,则不赋值。

2、实现流程

这里主要是采用几个GP工具【连接字段、计算字段】来实现的,核心步骤和代码如下:

首先需要获取Excel表中的2个表头,即字段名:

            // 参数获取string map_tabel = textExcelPath.Text;string in_data = combox_fc.Text;string in_field = combox_bmField.Text;string map_field = combox_bmField_Copy.Text;// 获取连接表的2个字段名string exl_field01 = GetCellFromExcel(map_tabel, "A1");string exl_field02 = GetCellFromExcel(map_tabel, "B1");List<string> fields = new List<string>() { exl_field02 };// 从Excel文件中获取Cellvaluepublic static string GetCellFromExcel(string excelPath, string range){// 建立 Excel 应用程序对象Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();// 获取Excel文件名和表名List<string> files = DecomposeExcel(excelPath);string excel_name = files[0];string sheet_name = files[1];// 打开 Excel 文件Workbook workbook = excelApp.Workbooks.Open(excel_name);// 获取工作表Worksheet worksheet = workbook.Worksheets[sheet_name];// 获取单元格string Cellvalue = worksheet.Range[range].Value.ToString();//  保存并关闭 Excel 文件和应用程序对象workbook.Close(true);excelApp.Quit();// 返回valuereturn Cellvalue;}

这里还调用了一个方法【DecomposeExcel】,用于把输入的Excel文件分解为文件名和表名,代码如下:

        // 分解Excel的文件名和表名public static List<string> DecomposeExcel(string excelPath){// 设置空列表List<string> list = new List<string>();// 获取最后一个"\"的位置int index = excelPath.LastIndexOf("\\");// 获取exl文件名string excel_name = excelPath.Substring(0, index);// 获取表名string sheet_name = excelPath.Substring(index + 1, excelPath.Length - index - 2);// 将exl文件名和表名加入列表list.Add(excel_name);list.Add(sheet_name);// 返回列表return list;}

然后调用GP工具【连接字段】,以参照字段为连接字段,将Excel表连接至属性表中:

        // 连接字段JoinField(in_data, in_field, map_tabel, exl_field01, fields);// 连接字段public static async void JoinField(string in_data, string in_field, string join_table, string join_field, List<string> fields, bool isOutput = false){// 设置默认GPExecuteToolFlagsGPExecuteToolFlags executeFlags = GPExecuteToolFlags.AddToHistory;if (isOutput){executeFlags = GPExecuteToolFlags.AddToHistory | GPExecuteToolFlags.AddOutputsToMap;}// 执行GP工具var par_JoinField = Geoprocessing.MakeValueArray(in_data, in_field, join_table, join_field, fields, "NOT_USE_FM", "");await QueuedTask.Run(() => Geoprocessing.ExecuteToolAsync("management.JoinField", par_JoinField, null, null, null, executeFlags));}

调用GP工具【计算字段】,将连接到属性表里的目标字段赋值给属性表里的映射字段:

        // 计算字段CalculateField(in_data, map_field, "!" + exl_field02 + "!");// 计算字段public static async void CalculateField(string in_data, string field, string expression, bool isOutput = false){// 设置默认GPExecuteToolFlagsGPExecuteToolFlags executeFlags = GPExecuteToolFlags.AddToHistory;if (isOutput){executeFlags = GPExecuteToolFlags.AddToHistory | GPExecuteToolFlags.AddOutputsToMap;}// 执行GP工具var par_CalculateField = Geoprocessing.MakeValueArray(in_data, field, expression, "PYTHON3", "", "", "NO_ENFORCE_DOMAINS");await QueuedTask.Run(() => Geoprocessing.ExecuteToolAsync("management.CalculateField", par_CalculateField, null, null, null, executeFlags));}

赋完值,顺便还可以删掉连接进来的字段。

以上便实现了将Excel表格映射到Table的功能。


二、属性表Table映射到Excel表格

1、要实现的效果

如上图所示,打开【Table映射到Excel表格】工具框,选择要赋值的Excel表,输入参照列和映射列(例子中是第1列和第2例),然后输入表格Table(例子里是一个汇总统计表),再输入参照字段和映射字段。

点击执行,效果如下:

生成结果中,Excel表格会根据汇总表的值进行填写,如果汇总表中没有相应的参照字段,则不会填写。

这个工具用处是很多的,例如生成【用地用海表,村庄结构功能表……】等一系列表格。

2、实现流程

第一步要从属性表Table中将对应的键值提取出来,输出一个字典,方便后面使用:

                // 参数获取string map_tabel = combox_table.Text;string in_field = combox_bmField_in.Text;string map_field = combox_bmField_map.Text;string excelPath = textExcelPath.Text;int sheet_in_col = int.Parse(txtbox01.Text);int sheet_map_col = int.Parse(txtbox02.Text);// 将映射属性表中获取字典DictionaryDictionary<string, string> dict = await QueuedTask.Run(() => GetDictFromTable(map_tabel, in_field, map_field));// 从Table中获取Dictionarypublic static async Task<Dictionary<string, string>> GetDictFromTable(string in_table, string in_field_01, string in_field_02){Dictionary<string, string> dict = new();// 根据图层名找到当前图层var map = MapView.Active.Map;StandaloneTable initlayer = map.FindStandaloneTables(in_table)[0];await QueuedTask.Run(() =>{using (ArcGIS.Core.Data.Table table = initlayer.GetTable()){using (RowCursor rowCursor = table.Search(null, false)){TableDefinition tableDefinition = table.GetDefinition();while (rowCursor.MoveNext()){using (Row row = rowCursor.Current){// 获取valuevar key = row[in_field_01].ToString();var value = row[in_field_02].ToString();// 如果没有重复key值,则纳入dictif (!dict.Keys.Contains(key)){dict.Add(key, value);}}}}}});return dict;}

获取用来映射的字典后,就可以打开Excel文件进行赋值了。同样的,这里还是要先把Excel文件名进行一个分解:

                // 建立 Excel 应用程序对象Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();// 获取Excel文件名和表名List<string> files = DecomposeExcel(excelPath);string excel_name = files[0];string sheet_name = files[1];// 打开 Excel 文件Workbook workbook = excelApp.Workbooks.Open(excel_name);// 获取工作表Worksheet worksheet = workbook.Worksheets[sheet_name];// 获取Excel表格中的数据,将特定列作为值for (int row = 1; row <= worksheet.UsedRange.Rows.Count; row++){// 获取对照值string in_value = worksheet.Cells[row, sheet_in_col].Value.ToString();// 赋值if (dict.Keys.Contains(in_value)){worksheet.Cells[row, sheet_map_col].Value = dict[in_value];}}//  保存并关闭 Excel 文件和应用程序对象workbook.Close(true);excelApp.Quit();

以上便实现了将Table映射到Excel表格的功能。

完整代码可以查看文章末尾放出的工程文件。


三、工程文件分享

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

AttributeMappericon-default.png?t=N3I4https://pan.baidu.com/s/1J79C5Qr7ClEyq5mrf12I9g?pwd=dqpjPS:可以直接点击...bin\Debug\net6.0-windows\下的.esriAddinX文件直接安装。


http://www.ppmy.cn/news/62197.html

相关文章

JavaScript:字符串

文章目录 字符串344. 反转字符串reverse() 方法&#xff08;打基础的时候&#xff0c;不要太迷恋库函数&#xff09;代码及思路 541. 反转字符串 IIJavaScript String split() 方法JavaScript Array join() 方法代码分析见注释 剑指 Offer 05. 替换空格思路注意&#xff1a;上面…

k8s搭建教程

1、简介 这里就不赘述&#xff0c;想要了解的朋友直接去这里深入了解什么是K8S。 2、环境要求 2台以上机器&#xff0c;操作系统 CentOS7.7-64位系统 硬件配置&#xff1a;2GB或更多RAM&#xff0c;2个CPU或更多CPU&#xff0c;硬盘30GB或更多 集群中所有机器之间网络互通 可以…

系统分析师论文---论软件需求获取技术以及应用

前言&#xff1a; 按照论文题目写相关内容。这一块是自己要提前准备的重点&#xff0c;并且一定要针对自己的项目构造几个真实的例子&#xff0c;不能只列举理论。回应子题目。这一块一般是写过程&#xff0c;有可能会问其他的&#xff0c;需要针对性点题 &#xff0c;但是不会…

7-2 哈利·波特的考试

哈利波特要考试了&#xff0c;他需要你的帮助。这门课学的是用魔咒将一种动物变成另一种动物的本事。例如将猫变成老鼠的魔咒是haha&#xff0c;将老鼠变成鱼的魔咒是hehe等等。反方向变化的魔咒就是简单地将原来的魔咒倒过来念&#xff0c;例如ahah可以将老鼠变成猫。另外&…

在Linux中进行Jenkins部署(maven-3.9.1+jdk11)

Jenkins部署在公网IP为x.x.x.x的服务器上 maven-3.9.1要安装在jdk11环境中 环境准备 第一步&#xff0c;下载jdk-11.0.19_linux-x64_bin.tar.gz安装包。 登录地址&#xff1a;Java Downloads | Oracle 下载jdk-11.0.19_linux-x64_bin.tar.gz安装包&#xff0c;然后使用Win…

【每日一题Day197】LC2432处理用时最长的那个任务的员工 | 枚举

处理用时最长的那个任务的员工【LC2432】 共有 n 位员工&#xff0c;每位员工都有一个从 0 到 n - 1 的唯一 id 。 给你一个二维整数数组 logs &#xff0c;其中 logs[i] [idi, leaveTimei] &#xff1a; idi 是处理第 i 个任务的员工的 id &#xff0c;且leaveTimei 是员工完…

树形结构的三级分类如何实现?

概述&#xff1a; 本三级联动分类服务端使用的是: Springboot MyBatis-plus&#xff0c;前端使用的是&#xff1a;VueElementUI&#xff0c;树形控件使用的是el-tree。本三级联动分类可以把任一子项拖拽到其它目录&#xff0c;可以添加、编辑、删除分类。 效果图&#xff1a…

ES的概述

一、ECMASript 相关介绍 1.1什么是 ECMA ECMA &#xff08; European Computer Manufacturers Association &#xff09;中文名称为欧洲计算机制 造商协会&#xff0c;这个组织的目标是评估、开发和认可电信和计算机标准。 1994 年后该 组织改名为 Ecma 国际。 1.2.什么…