赞
踩
在对GDB格式的矢量数据库进行检查时,经常需要将检查结果导出为shp文件,或者GDB格式文件;形成了两个小的处理思路,在这里总结分享。
介绍了两种方法,主要针对要导出的数据格式为GDB类型的输出文件;两种思路的差异是:
该思路将整个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);
之前博文:基于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();
- }
- }
检查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();
- }
该内容见系列文章:
使用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);
- }
此部分参见之前的文章:基于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文件的兴趣图层,然后直接进行处理就行了
这个函数是针对对数据进行处理后,结果以数据点的形式存储在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();
- }
- }
支持作者,欢迎关注个人公众账号:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。