基于C#的ArcEngine二次开发44: GDB矢量文件检查结果导出GDB/SHP的思路分析

简介: 基于C#的ArcEngine二次开发44: GDB矢量文件检查结果导出GDB/SHP的思路分析

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

1 导出GDB文件

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

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

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

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

1.1.1 GDB文件整体拷贝

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

//需要引用System.IO命名空间,实现代码如下:
private static bool CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting)  
{  
   bool ret = false;  
   try  
   {  
       if (Directory.Exists(SourcePath))  
       {  
           //不存在则创建
           if (Directory.Exists(DestinationPath) == false)  
               Directory.CreateDirectory(DestinationPath);  
           foreach (string fls in Directory.GetFiles(SourcePath))  
           {  
               FileInfo flinfo = new FileInfo(fls);  
               flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting);  
           }  
           foreach (string drs in Directory.GetDirectories(SourcePath))  
           {  
               DirectoryInfo drinfo = new DirectoryInfo(drs);  
               if (CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting) == false)  
                   ret = false;  
           }  
       }  
       ret = true;  
   }  
   catch (Exception ex)  
   {  
       ret = false;  
   }  
   return ret;  
}
//使用方法:
bool copy = CopyDirectory("c:\\src.gdb", "c:\\temp\\dst.gdb", true);

1.1.2 删除多余图层

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

public void DeleteFeatureClass(IWorkspace workspace, string featueClassName)
{
    //根据名称删除数据库要素
    IFeatureWorkspaceManage featureWorkspaceMange = (workspace as IFeatureWorkspace) as IFeatureWorkspaceManage;
    IEnumDatasetName enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureClass);
    IDatasetName datasetName = enumDatasetName.Next();
    while (datasetName != null)
    {
        if (datasetName.Name.Equals(featueClassName))
        {
            featureWorkspaceMange.DeleteByName(datasetName);//删除指定要素类
            break;
        }
        datasetName = enumDatasetName.Next();
    }
}

1.1.3 拷贝检查

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

private void checkOutput(string srcGDB, string dstGDB) 
{
    //1. GDB拷贝
    if(!System.IO.Exists(dstGDB))
    {
        CopyDirectory(srcGDB, dstGDB);
    }
    //2. 打开文件
    IWorkspaceFactory worFact =new FileGDBWorkspaceFactory();
    IWorkspace workspace = worFact.OpenFromFile(dstGDB, 0);
    //3. 假定移除AANP层
    DeleteFeatureClass("AANP");   
    //4. 假设检查LRDL,需要增加字段进行错误信息记录
    IFeatureClass poFeaterClass = ofeatureWorkspace.OpenFeatureClass("LRDL");
    int checkFieldIndex = poFeaterClass.FindField("检查结果记录");
    if(checkFieldIndex == -1)
    {
        IFields pFields = new FieldClass();
        IFieldEdit pFieldEdit = pFields as IFieldEdit;
        pFieldEdit.Name_2 = "检查结果记录";
        pFieldEdit.Type_2 = filedType;    
        pFieldEdit.Length_2 = fieldLength;
        pTable.AddField(pFieldEdit);    
    }
    checkFieldIndex = poFeaterClass.FindField("检查结果记录");
    //5. 遍历每个要素进行检查
    IFeatureCursor pCursor = poFeaterClass.Update(null, false);
    IFeature pFeature = pCursor.NextFeature();
    while(pFeature != null)
    {
        int nameIndex = pFeature.get_Field("RNN");
        string name = pFeature.get_Value(nameIndex).ToString().Trim();
        if(name == "")
        {
            pFeature.get_Value(checkFieldIndex, "名称为空,错误")
            pCursor.UpdateFeature();
        }
        else
        {
            pCursor.DeleteFeature();
        }
        pFeature = pCursor.NextFeature();
    }
    //6. 注销对象
    Marshal.FinalReleaseComObject(pCursor);
    Marshal.FinalReleaseComObject(poFeaterClass);
    Marshal.FinalReleaseComObject(workspace);
    GC.Collect();
}

1.2 创建GDB+ConvertFeatureClass

1.2.1 创建GDB文件

该内容见系列文章:

使用GP工具创建:

//gdbFolder:    设置存放将要创建GDB文件的目录
//gdbFileName:    设置GDB文件的名称
public void createGDBFile(string gdbFolder, string gdbFileName)
{
    //创建gp工具
    ESRI.ArcGIS.Geoprocessor.Geoprocessor pGeoprocessor = ESRI.ArcGIS.Geoprocessor.Geoprocessor{};
    pGeoprocessor.OverwriteOutput = true;
    pGeoprocessor.AddOutputToMap = false;
    //创建GDB文件
    CreateFileGDB processor = new CreateFileGDB {};
    processor.out_folder_path = gdbFolder;
    processor.out_name = gdbFileName;
    pGeoprocessor.Execute(processor, null);
}

1.2.2 ConvertFeatureClass

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

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

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

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

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

        /// <summary>
        /// 将点集导出为shp文件
        /// </summary>
        /// <param name="inPath">输入数据集</param>
        /// <param name="liPts">要导出的点集</param>
        /// <param name="checkLayerName">点集的来源图层</param>
        /// <param name="ouPath">导出的shape文件的结果保存路径</param>
        public void ExportPtsToShapefile(string inPath, List<IPoint> liPts, string checkLayerName, string ouPath)
         {
             //1. 打开工作空间
             string strShapeFolder = System.IO.Path.GetDirectoryName(ouPath);
             const string strShapeFieldName = "shape";
             IWorkspaceFactory pWSF = new ShapefileWorkspaceFactoryClass();
             IFeatureWorkspace pWS = (IFeatureWorkspace)pWSF.OpenFromFile(strShapeFolder,0);
             //2. 设置字段集
             IFields pFields = new FieldsClass();
             IFieldsEdit pFieldsEdit = (IFieldsEdit)pFields;
             //3. 设置字段
             IField pField = new FieldClass();
             IFieldEdit pFieldEdit = (IFieldEdit)pField;
             //4. 创建类型为几何类型的字段
             pFieldEdit.Name_2 = strShapeFieldName;
             pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
             //为esriFieldTypeGeometry类型的字段创建几何定义,包括类型和空间参照
             IGeometryDef pGeoDef = new GeometryDefClass(); //The geometry definition for the field if IsGeometry is TRUE.
             IGeometryDefEdit pGeoDefEdit = (IGeometryDefEdit)pGeoDef;
             //4.1 将原始数据的投影信息赋值给新的检查结果图层
             IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactory();
             IWorkspace workspace = workspaceFactory.OpenFromFile(inPath, 0);
             IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
             IFeatureClass pFeaterClass = featureWorkspace.OpenFeatureClass(checkLayerName);//这个地方可以继续研究如何更简便的获取工作空间的坐标系统
             IGeoDataset geoDatabase = pFeaterClass as IGeoDataset;
             //设置坐标系统
             IProjectedCoordinateSystem tProjectedCoordinateSystem = geoDatabase.SpatialReference as IProjectedCoordinateSystem;
             pGeoDefEdit.SpatialReference_2 = tProjectedCoordinateSystem;   
             pGeoDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;          
             pFieldEdit.GeometryDef_2 = pGeoDef;
             pFieldsEdit.AddField(pField);
             //添加其他的字段
             pField = new FieldClass();
             pFieldEdit = (IFieldEdit)pField;
             pFieldEdit.Name_2 = "X";
             pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
             //pFieldEdit.Precision_2 = 7;//数值精度
             //pFieldEdit.Scale_2 = 6;//小数点位数
             pFieldsEdit.AddField(pField);
             pField = new FieldClass();
             pFieldEdit = (IFieldEdit)pField;
             pFieldEdit.Name_2 = "Y";
             pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
             //pFieldEdit.Precision_2 = 7;//数值精度
             //pFieldEdit.Scale_2 = 6;//小数点位数
             pFieldsEdit.AddField(pField);
             //创建shapefile
             string strShapeName = System.IO.Path.GetFileName(ouPath);           
             IFeatureClass shpFeatureClass = pWS.CreateFeatureClass(strShapeName, pFields, null, null, esriFeatureType.esriFTSimple, strShapeFieldName, "");
             //5. 向shape中添加要素
             IPoint pPoint = new PointClass();
             foreach (IPoint pt in liPts)
             {
                 IFeature pFeature = shpFeatureClass.CreateFeature();
                 //5.1 将点坐标设置到属性表中
                 //获取字段,并对字段值进行属性赋值
                 IFields fields = pFeature.Fields;//获取该对象的字段
                 int xIdx = fields.FindFieldByAliasName("X");
                 pFeature.set_Value(xIdx, pt.X);
                 int yIdx = fields.FindFieldByAliasName("Y");
                 pFeature.set_Value(yIdx, pt.Y);
                 //5.2 将点设置为shp文件的图形要素
                 pFeature.Shape = pt;//这一句十分重要,不然点显示不出来
                 //如果导出的其他类型的元素(IPolygon,IPolyline)
                 pFeature.Store();
             }                               
         }
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
4月前
|
数据采集 存储 C#
C# 爬虫技术:京东视频内容抓取的实战案例分析
C# 爬虫技术:京东视频内容抓取的实战案例分析
|
3月前
|
SQL C# 数据库
EPPlus库的安装和使用 C# 中 Excel的导入和导出
本文介绍了如何使用EPPlus库在C#中实现Excel的导入和导出功能。首先,通过NuGet包管理器安装EPPlus库,然后提供了将DataGridView数据导出到Excel的步骤和代码示例,包括将DataGridView转换为DataTable和使用EPPlus将DataTable导出为Excel文件。接着,介绍了如何将Excel数据导入到数据库中,包括读取Excel文件、解析数据、执行SQL插入操作。
EPPlus库的安装和使用 C# 中 Excel的导入和导出
|
2月前
|
存储 C#
【C#】大批量判断文件是否存在的两种方法效率对比
【C#】大批量判断文件是否存在的两种方法效率对比
51 1
|
2月前
|
XML 存储 缓存
C#使用XML文件的详解及示例
C#使用XML文件的详解及示例
116 0
|
4月前
|
NoSQL 数据挖掘 定位技术
如何让geopandas支持写出gdb文件
如何让geopandas支持写出gdb文件
|
4月前
|
NoSQL Linux Windows
geopandas直接支持gdb文件写出与追加
geopandas直接支持gdb文件写出与追加
|
4月前
|
编译器 C# Windows
C#基础:手动编译一个.cs源代码文件并生成.exe可执行文件
通过上述步骤,应该能够高效准确地编译C#源代码并生成相应的可执行文件。此外,这一过程强调了对命令行编译器的理解,这在调试和自动化编译流程中是非常重要的。
358 2
|
4月前
|
C# 图形学 数据安全/隐私保护
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
Unity数据加密☀️ 二、使用Rider将C#代码生成DLL文件
|
4月前
|
C#
C# 写日志文件
C# 写日志文件
51 0
|
22天前
|
NoSQL 编译器 C语言
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。高级技巧包括内存检查、性能分析和符号调试。通过实践案例学习如何有效定位和解决问题,同时注意保持耐心、合理利用工具、记录过程并避免过度调试,以提高编程能力和开发效率。
37 1