当前位置:   article > 正文

【ArcGIS Pro二次开发】(55):给多个要素或表批量添加字段_gis批量添加字段

gis批量添加字段

在工作中可能会遇到这样的场景:有多个GDB要素、表格,或者是SHP文件,需要给这个要素或表添加相同的多个字段。

在这种情况下,手动添加就变得很繁琐,于是就做了这个工具。

需求具体如下图:

左图是待处理数据,有shp文件也有gdb文件

右图是待添加字段的属性结构描述表,有4个参数,【字段名称、字段别名、字段类型、字段长度】。

(文件格式为Excel,文章末尾的下载链接会附上示例Excel)

工具的执行流程为:依次为左图待处理的数据添加右图定义好的字段。


一、要实现的功能

如上图所示,点击【字段处理】组【字段综合】面板下的【添加字段(批量)】工具。

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

1、包含要素或表格的文件夹。这里可以支持SHP文件和GDB文件,但不支持MDB。

2、包含字段属性的Excel表。这个表格的格式是固定的,在后面的工具链接里,我会将其一块共享,可自行下载,在此基础上修改可以少些错误。

E列的说明性文字只是查看用的,不会参与工具的计算(可以删掉)。这里列出6个字段类型格式,除此之外的类型文字是不认的。

3、关键字筛选。这是可选填的,如果你只想处理包含“规划”文字的要素和表,可以在关键字里输入。如果想全部处理,就可以不填任何文字。

最后点击执行即可,生成结果如下(以单个为例):


二、实现流程

第一步,从Excel表中获取字段的参数,返回双层List。

  1. // 获取字段属性结构表
  2. List<List<string>> list_field_attribute = new List<List<string>>();
  3. // 建立 Excel 应用程序对象
  4. Application excelApp = new Application();
  5. // 打开 Excel 文件
  6. Workbook workbook = excelApp.Workbooks.Open(excel_path);
  7. // 获取工作表
  8. var worksheet = workbook.Worksheets[1];
  9. // 获取总行数
  10. int row_count = worksheet.UsedRange.Rows.Count;
  11. // 获取字段属性
  12. for (int i = 3; i < row_count; i++)
  13. {
  14. // 获取字段属性
  15. string mc = worksheet.Cells[i, 1].Value.ToString(); // 字段名称
  16. string bm = worksheet.Cells[i, 2].Value.ToString(); // 字段别名
  17. string field_type = worksheet.Cells[i, 3].Value.ToString(); // 字段类型
  18. string lenth = worksheet.Cells[i, 4].Value.ToString(); // 字段长度
  19. // 加入
  20. list_field_attribute.Add(new List<string> { mc, bm, field_type, lenth });
  21. }

第二步,从输入的文件夹中获取所有要素类和表。

首先是shp文件的情况:

  1. // 获取输入文件夹下的所有文件
  2. public static List<string> GetAllFiles(string folder_path, string key_word ="no match")
  3. {
  4. List<string> filePaths = new List<string>();
  5. // 获取当前文件夹下的所有文件
  6. string[] files = Directory.GetFiles(folder_path);
  7. // 判断是否包含关键字
  8. if (key_word == "no match")
  9. {
  10. filePaths.AddRange(files);
  11. }
  12. else
  13. {
  14. foreach (string file in files)
  15. {
  16. // 检查文件名是否包含指定扩展名
  17. if (System.IO.Path.GetExtension(file).Equals(key_word, StringComparison.OrdinalIgnoreCase))
  18. {
  19. filePaths.Add(file);
  20. }
  21. }
  22. }
  23. // 获取当前文件夹下的所有子文件夹
  24. string[] subDirectories = Directory.GetDirectories(folder_path);
  25. // 递归遍历子文件夹下的文件
  26. foreach (string subDirectory in subDirectories)
  27. {
  28. filePaths.AddRange(GetAllFiles(subDirectory, key_word));
  29. }
  30. return filePaths;
  31. }

要获取gdb文件下要素和表,首先要获取gdb文件:

  1. public static List<string> GetAllGDBFilePaths(string folderPath)
  2. {
  3. List<string> gdbFilePaths = new List<string>();
  4. DirectoryInfo directoryInfo = new DirectoryInfo(folderPath);
  5. // 检查文件夹是否存在
  6. if (!directoryInfo.Exists)
  7. {
  8. throw new DirectoryNotFoundException("指定的文件夹路径不存在!");
  9. }
  10. // 查找所有GDB数据库文件(.gdb文件夹)
  11. DirectoryInfo[] gdbDirectories = directoryInfo.GetDirectories("*.gdb", SearchOption.AllDirectories);
  12. foreach (DirectoryInfo gdbDirectory in gdbDirectories)
  13. {
  14. // 获取GDB数据库的路径
  15. string gdbPath = gdbDirectory.FullName.Replace(@"/", @"\");
  16. // 添加到列表中
  17. gdbFilePaths.Add(gdbPath);
  18. }
  19. return gdbFilePaths;
  20. }

再从GDB文件下获取所有要素类和表:

  1. // 获取数据库下的所有要素类的完整路径
  2. public static List<string> GetFeatureClassPath(string gdb_path)
  3. {
  4. List<string> result = new List<string>();
  5. // 打开GDB数据库
  6. using Geodatabase gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(gdb_path)));
  7. // 获取所有要素类
  8. IReadOnlyList<FeatureClassDefinition> featureClasses = gdb.GetDefinitions<FeatureClassDefinition>();
  9. foreach (FeatureClassDefinition featureClass in featureClasses)
  10. {
  11. using (FeatureClass fc = gdb.OpenDataset<FeatureClass>(featureClass.GetName()))
  12. {
  13. // 获取要素类路径
  14. string fc_path = fc.GetPath().ToString().Replace("file:///", "").Replace("/", @"\");
  15. result.Add(fc_path);
  16. }
  17. }
  18. return result;
  19. }
  20. // 获取数据库下的所有独立表的完整路径
  21. public static List<string> GetTablePath(string gdb_path)
  22. {
  23. List<string> result = new List<string>();
  24. // 打开GDB数据库
  25. using Geodatabase gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(gdb_path)));
  26. // 获取所有独立表
  27. IReadOnlyList<TableDefinition> tables = gdb.GetDefinitions<TableDefinition>();
  28. foreach (TableDefinition tableDef in tables)
  29. {
  30. using (Table table = gdb.OpenDataset<Table>(tableDef.GetName()))
  31. {
  32. // 获取要素类路径
  33. string fc_path = table.GetPath().ToString().Replace("file:///", "").Replace("/", @"\");
  34. result.Add(fc_path);
  35. }
  36. }
  37. return result;
  38. }

获取所有输入要素和表后,即可添加字段:

【obj_all】为获取的所有要素和表的路径,【list_field_attribute】为获取的字段属性结构列表。

  1. // 添加字段
  2. foreach (var ob in obj_all)
  3. {
  4. string target_name = ob[ob.LastIndexOf(@"\")..];
  5. // 如果不含关键字,直接添加字段
  6. if (key_word != "")
  7. {
  8. foreach (var fa in list_field_attribute)
  9. {
  10. Arcpy.AddField(ob, fa[0], fa[2], fa[1], int.Parse(fa[3]));
  11. }
  12. }
  13. else
  14. {
  15. // 如果含有关键字,筛选出含关键字的部分,再添加字段
  16. if (target_name.Contains(key_word))
  17. {
  18. foreach (var fa in list_field_attribute)
  19. {
  20. Arcpy.AddField(ob, fa[0], fa[2], fa[1], int.Parse(fa[3]));
  21. }
  22. }
  23. }
  24. }

以上便是工具实现的核心代码。


三、工具文件分享

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/228113
推荐阅读
相关标签
  

闽ICP备14008679号