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

属性映射经常用于属性表或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文件中获取Cellvalue
        public 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();
            // 返回value
            return 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)
        {
            // 设置默认GPExecuteToolFlags
            GPExecuteToolFlags 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)
        {
            // 设置默认GPExecuteToolFlags
            GPExecuteToolFlags 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);

                // 将映射属性表中获取字典Dictionary
                Dictionary<string, string> dict = await QueuedTask.Run(() => GetDictFromTable(map_tabel, in_field, map_field));

        // 从Table中获取Dictionary
        public 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)
                            {
                                // 获取value
                                var key = row[in_field_01].ToString();
                                var value = row[in_field_02].ToString();
                                // 如果没有重复key值,则纳入dict
                                if (!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文件直接安装。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
ArcGIS Pro二次开发是指使用ArcGIS Pro软件进行自定义功能开发的过程。对于初学者而言,开始二次开发可能感到无从入手,因为中文资料较少,官方文档对于英文不熟悉的人来说可能不太友好。 要开始ArcGIS Pro二次开发,你可以按照以下步骤进行操作: 1. 首先,以管理员身份运行Visual Studio 2019。如果没有安装Visual Studio 2019,你需要先下载并安装它。 2. 在Visual Studio中,右键项目名称,选择"添加",然后选择"新建项"。 3. 在"新建项"下拉菜单中,选择"ArcGIS",然后选择"ArcGIS Pro Add-ins",再选择"ArcGIS Pro按钮",最后点击"添加"。 4. 接下来,配置新项目。在Visual Studio中,点击"文件",选择"新建",然后选择"项目"。 5. 在"新建项目"对话框中,选择"C#"作为语言,选择"Windows"作为平台,然后选择"ArcGIS Pro SDK"。在项目类型中选择"ArcGIS Pro模块加载项",然后点击"下一步"。 6. 设置新项目的配置,然后点击"创建"。等待项目创建完成。 通过以上步骤,你就可以开始进行ArcGIS Pro二次开发了。你可以根据你的需求,使用C#编程语言进行开发,并且利用ArcGIS Pro SDK提供的功能来扩展ArcGIS Pro软件的功能。 希望这些步骤能够帮助你入门ArcGIS Pro二次开发。如果你遇到了其他问题或需要更多详细的指导,请随时提问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [【ArcGIS Pro二次开发】系列学习笔记,持续更新,记得收藏](https://blog.csdn.net/xcc34452366/article/details/129223703)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ArcGIS Pro二次开发环境配置及项目创建示例](https://blog.csdn.net/wsywsy00/article/details/128550006)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

规划GIS会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值