当前位置:   article > 正文

基于C#的ArcEngine二次开发44: GDB矢量文件检查结果导出GDB/SHP的思路分析_cecmap数据gdb格式怎么导出gdb格式

cecmap数据gdb格式怎么导出gdb格式

在对GDB格式的矢量数据库进行检查时,经常需要将检查结果导出为shp文件,或者GDB格式文件;形成了两个小的处理思路,在这里总结分享。

1 导出GDB文件

介绍了两种方法,主要针对要导出的数据格式为GDB类型的输出文件;两种思路的差异是:

  • 前者将整个GDB以文件形式拷贝,然后在删除不需要的图层;
  • 后者新建GDB文件,然后只拷贝需要的要素类

1.1 整体拷贝+图层删除思路

该思路将整个GDB文件视为一个目录,直接拷贝到结果目录中,然后再删除多余图层的方法

1.1.1 GDB文件整体拷贝

之前博文C#编程学习13:文件及文件夹检索与拷贝已经对文件夹拷贝的代码进行了总结

  1. //需要引用System.IO命名空间,实现代码如下:
  2. private static bool CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting)
  3. {
  4. bool ret = false;
  5. try
  6. {
  7. if (Directory.Exists(SourcePath))
  8. {
  9. //不存在则创建
  10. if (Directory.Exists(DestinationPath) == false)
  11. Directory.CreateDirectory(DestinationPath);
  12. foreach (string fls in Directory.GetFiles(SourcePath))
  13. {
  14. FileInfo flinfo = new FileInfo(fls);
  15. flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting);
  16. }
  17. foreach (string drs in Directory.GetDirectories(SourcePath))
  18. {
  19. DirectoryInfo drinfo = new DirectoryInfo(drs);
  20. if (CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting) == false)
  21. ret = false;
  22. }
  23. }
  24. ret = true;
  25. }
  26. catch (Exception ex)
  27. {
  28. ret = false;
  29. }
  30. return ret;
  31. }
  32. //使用方法:
  33. bool copy = CopyDirectory("c:\\src.gdb", "c:\\temp\\dst.gdb", true);

1.1.2 删除多余图层

之前博文:基于C#的ArcEngine二次开发40:如何删除临时GDB文件;对此做过分析

  1. public void DeleteFeatureClass(IWorkspace workspace, string featueClassName)
  2. {
  3. //根据名称删除数据库要素
  4. IFeatureWorkspaceManage featureWorkspaceMange = (workspace as IFeatureWorkspace) as IFeatureWorkspaceManage;
  5. IEnumDatasetName enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureClass);
  6. IDatasetName datasetName = enumDatasetName.Next();
  7. while (datasetName != null)
  8. {
  9. if (datasetName.Name.Equals(featueClassName))
  10. {
  11. featureWorkspaceMange.DeleteByName(datasetName);//删除指定要素类
  12. break;
  13. }
  14. datasetName = enumDatasetName.Next();
  15. }
  16. }

1.1.3 拷贝检查

检查LRDL的name是否为空的示例

  1. private void checkOutput(string srcGDB, string dstGDB)
  2. {
  3. //1. GDB拷贝
  4. if(!System.IO.Exists(dstGDB))
  5. {
  6. CopyDirectory(srcGDB, dstGDB);
  7. }
  8. //2. 打开文件
  9. IWorkspaceFactory worFact =new FileGDBWorkspaceFactory();
  10. IWorkspace workspace = worFact.OpenFromFile(dstGDB, 0);
  11. //3. 假定移除AANP层
  12. DeleteFeatureClass("AANP");
  13. //4. 假设检查LRDL,需要增加字段进行错误信息记录
  14. IFeatureClass poFeaterClass = ofeatureWorkspace.OpenFeatureClass("LRDL");
  15. int checkFieldIndex = poFeaterClass.FindField("检查结果记录");
  16. if(checkFieldIndex == -1)
  17. {
  18. IFields pFields = new FieldClass();
  19. IFieldEdit pFieldEdit = pFields as IFieldEdit;
  20. pFieldEdit.Name_2 = "检查结果记录";
  21. pFieldEdit.Type_2 = filedType;
  22. pFieldEdit.Length_2 = fieldLength;
  23. pTable.AddField(pFieldEdit);
  24. }
  25. checkFieldIndex = poFeaterClass.FindField("检查结果记录");
  26. //5. 遍历每个要素进行检查
  27. IFeatureCursor pCursor = poFeaterClass.Update(null, false);
  28. IFeature pFeature = pCursor.NextFeature();
  29. while(pFeature != null)
  30. {
  31. int nameIndex = pFeature.get_Field("RNN");
  32. string name = pFeature.get_Value(nameIndex).ToString().Trim();
  33. if(name == "")
  34. {
  35. pFeature.get_Value(checkFieldIndex, "名称为空,错误")
  36. pCursor.UpdateFeature();
  37. }
  38. else
  39. {
  40. pCursor.DeleteFeature();
  41. }
  42. pFeature = pCursor.NextFeature();
  43. }
  44. //6. 注销对象
  45. Marshal.FinalReleaseComObject(pCursor);
  46. Marshal.FinalReleaseComObject(poFeaterClass);
  47. Marshal.FinalReleaseComObject(workspace);
  48. GC.Collect();
  49. }

1.2 创建GDB+ConvertFeatureClass

1.2.1 创建GDB文件

该内容见系列文章:

使用GP工具创建:

  1. //gdbFolder: 设置存放将要创建GDB文件的目录
  2. //gdbFileName: 设置GDB文件的名称
  3. public void createGDBFile(string gdbFolder, string gdbFileName)
  4. {
  5. //创建gp工具
  6. ESRI.ArcGIS.Geoprocessor.Geoprocessor pGeoprocessor = ESRI.ArcGIS.Geoprocessor.Geoprocessor{};
  7. pGeoprocessor.OverwriteOutput = true;
  8. pGeoprocessor.AddOutputToMap = false;
  9. //创建GDB文件
  10. CreateFileGDB processor = new CreateFileGDB {};
  11. processor.out_folder_path = gdbFolder;
  12. processor.out_name = gdbFileName;
  13. pGeoprocessor.Execute(processor, null);
  14. }

1.2.2 ConvertFeatureClass

此部分参见之前的文章:基于C#的ArcEngine二次开发29:GDB文件操作及异常处理

  1. public void CopyLayerFromGDB(string inPath, string gdbLayerName, string ouPath, string ouGdbLayerName)
  2. {
  3. //1. 指定输入要素
  4. IWorkspaceFactory workspaceFactory = new ESRI.ArcGIS.DataSourcesGDB.FileGDBWorkspaceFactoryClass();
  5. IWorkspace iworkspace = iworkspaceFactory.OpenFromFile(inPath, 0);
  6. IFeatureWorkspace ifeatureWorkspace = (IFeatureWorkspace)iworkspace;
  7. IFeatureClass ipFeaterClass = ifeatureWorkspace.OpenFeatureClass(checkLayerName);
  8. //2. 设置输入图层名
  9. IWorkspaceName inWorkspaceName = (inWorkspace as IDataset).FullName as IWorkspaceName ;
  10. IFeatureClassName inFeatureClassName = new FeatureClassNameClass();
  11. IDatasetName inDatasetName = (IDatasetName)inFeatureClassName;
  12. inDatasetName.WorkspaceName = inWorkspaceName;
  13. inDatasetName.Name = gdbLayerName;
  14. //3. 在目标GDB中创建导出图层
  15. IWorkspaceFactory oworkspaceFactory = new AccessWorkspaceFactory();
  16. IWorkspace oworkspace = oworkspaceFactory.OpenFromFile(ouPath, 0);
  17. IFeatureWorkspace ofeatureWorkspace = (IFeatureWorkspace)workspace;
  18. IFeatureClass poFeaterClass = ofeatureWorkspace.OpenFeatureClass(mdbLayerName);
  19. IWorkspace2 oworkspace2 = (IWorkspace2)oworkspace;
  20. if (oworkspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, checkLayerName))
  21. {
  22. IFeatureClass pFC = ofeatureWorkspace.OpenFeatureClass(checkLayerName);
  23. IDataset pDS = pFC as IDataset;
  24. pDS.Delete();
  25. }
  26. //4. 创建输出要素类
  27. IWorkspaceName ouWorkspaceName = (ouWorkspace as IDataset).FullName as IWorkspaceName ;
  28. IFeatureClassName ouFeatureClassName = new FeatureClassNameClass();
  29. IDatasetName ouDatasetName = (IDatasetName)ouFeatureClassName;
  30. ouDatasetName.WorkspaceName = ouWorkspaceName;
  31. ouDatasetName.Name = ouGdbLayerName;
  32. //5. 字段赋值
  33. IFieldChecker fieldChecker = new FieldCheckerClass();
  34. fieldChecker.InputWorkspace = iworkspace;//输入数据集工作空间
  35. fieldChecker.ValidateWorkspace = ouWorkpace;//输出工作空间
  36. IFields outFeatureClassFields;
  37. IEnumFieldError enumFieldError;
  38. fieldChecker.Validate(inFeatureClassFields, out enumFieldError, out outFeatureClassFields);
  39. //6. 几何定义
  40. IField geometryField = outFeatureClassFields.get_Field(outFeatureClassFields.FindField(inFeatureClass.ShapeFieldName));
  41. IGeometryDef geometryDef = geometryField.GeometryDef;
  42. //7. 查询语句 -- 如果还要进行上述的LRDL层的空值监测,直接写到sql语句中就可以了
  43. QueryFilter qf = new QueryFilterClass();
  44. qf.WhereClause = "";
  45. //8. 调用转换函数
  46. IFeatureDataConverter fctofc = new FeatureDataConverterClass();
  47. IEnumInvalidObject enumErrors = fctofc.ConvertFeatureClass(inFeatureClassName, qf, null, outFeatureClassName, geometryDef, outFeatureClassFields, "", 1000, 0);
  48. }

调用与第一种类似,打开拷贝出的GDB文件的兴趣图层,然后直接进行处理就行了

2 导出shp文件(以点要素为例)

这个函数是针对对数据进行处理后,结果以数据点的形式存储在shp中,自定义属性字段并输出要素

  1. /// <summary>
  2. /// 将点集导出为shp文件
  3. /// </summary>
  4. /// <param name="inPath">输入数据集</param>
  5. /// <param name="liPts">要导出的点集</param>
  6. /// <param name="checkLayerName">点集的来源图层</param>
  7. /// <param name="ouPath">导出的shape文件的结果保存路径</param>
  8. public void ExportPtsToShapefile(string inPath, List<IPoint> liPts, string checkLayerName, string ouPath)
  9. {
  10. //1. 打开工作空间
  11. string strShapeFolder = System.IO.Path.GetDirectoryName(ouPath);
  12. const string strShapeFieldName = "shape";
  13. IWorkspaceFactory pWSF = new ShapefileWorkspaceFactoryClass();
  14. IFeatureWorkspace pWS = (IFeatureWorkspace)pWSF.OpenFromFile(strShapeFolder,0);
  15. //2. 设置字段集
  16. IFields pFields = new FieldsClass();
  17. IFieldsEdit pFieldsEdit = (IFieldsEdit)pFields;
  18. //3. 设置字段
  19. IField pField = new FieldClass();
  20. IFieldEdit pFieldEdit = (IFieldEdit)pField;
  21. //4. 创建类型为几何类型的字段
  22. pFieldEdit.Name_2 = strShapeFieldName;
  23. pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
  24. //为esriFieldTypeGeometry类型的字段创建几何定义,包括类型和空间参照
  25. IGeometryDef pGeoDef = new GeometryDefClass(); //The geometry definition for the field if IsGeometry is TRUE.
  26. IGeometryDefEdit pGeoDefEdit = (IGeometryDefEdit)pGeoDef;
  27. //4.1 将原始数据的投影信息赋值给新的检查结果图层
  28. IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
  29. IWorkspace workspace = workspaceFactory.OpenFromFile(inPath, 0);
  30. IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
  31. IFeatureClass pFeaterClass = featureWorkspace.OpenFeatureClass(checkLayerName);//这个地方可以继续研究如何更简便的获取工作空间的坐标系统
  32. IGeoDataset geoDatabase = pFeaterClass as IGeoDataset;
  33. //设置坐标系统
  34. IProjectedCoordinateSystem tProjectedCoordinateSystem = geoDatabase.SpatialReference as IProjectedCoordinateSystem;
  35. pGeoDefEdit.SpatialReference_2 = tProjectedCoordinateSystem;
  36. pGeoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
  37. pFieldEdit.GeometryDef_2 = pGeoDef;
  38. pFieldsEdit.AddField(pField);
  39. //添加其他的字段
  40. pField = new FieldClass();
  41. pFieldEdit = (IFieldEdit)pField;
  42. pFieldEdit.Name_2 = "X";
  43. pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
  44. //pFieldEdit.Precision_2 = 7;//数值精度
  45. //pFieldEdit.Scale_2 = 6;//小数点位数
  46. pFieldsEdit.AddField(pField);
  47. pField = new FieldClass();
  48. pFieldEdit = (IFieldEdit)pField;
  49. pFieldEdit.Name_2 = "Y";
  50. pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
  51. //pFieldEdit.Precision_2 = 7;//数值精度
  52. //pFieldEdit.Scale_2 = 6;//小数点位数
  53. pFieldsEdit.AddField(pField);
  54. //创建shapefile
  55. string strShapeName = System.IO.Path.GetFileName(ouPath);
  56. IFeatureClass shpFeatureClass = pWS.CreateFeatureClass(strShapeName, pFields, null, null, esriFeatureType.esriFTSimple, strShapeFieldName, "");
  57. //5. 向shape中添加要素
  58. IPoint pPoint = new PointClass();
  59. foreach (IPoint pt in liPts)
  60. {
  61. IFeature pFeature = shpFeatureClass.CreateFeature();
  62. //5.1 将点坐标设置到属性表中
  63. //获取字段,并对字段值进行属性赋值
  64. IFields fields = pFeature.Fields;//获取该对象的字段
  65. int xIdx = fields.FindFieldByAliasName("X");
  66. pFeature.set_Value(xIdx, pt.X);
  67. int yIdx = fields.FindFieldByAliasName("Y");
  68. pFeature.set_Value(yIdx, pt.Y);
  69. //5.2 将点设置为shp文件的图形要素
  70. pFeature.Shape = pt;//这一句十分重要,不然点显示不出来
  71. //如果导出的其他类型的元素(IPolygon,IPolyline)
  72. pFeature.Store();
  73. }
  74. }

支持作者,欢迎关注个人公众账号:

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

闽ICP备14008679号