2.2.3 完善代码
IQueryFilter filter = new QueryFilterClass(); filter.WhereClause = ""; IFeatureCursor pFeaturnCuesor = srcFeatureClass.Search(filter, false); IFeature pFeature = pFeaturnCuesor.NextFeature(); IFeatureClassLoad dstFeaLoad = dstFeatureClass as IFeatureClassLoad; dstFeaLoad.LoadOnlyMode = true; while (pFeature != null) { IFeature dstFea = dstFeatureClass.CreateFeature(); dstFea.Shape = pFeature.Shape; dstFea.Store(); pFeature = pFeaturnCuesor.NextFeature(); }
3 GDB目录删除与资源释放
3.1 删除gdb文件
gdb实际上是一个文件夹,所以要使用文件夹删除的方式删除
///dir为要删除的文件夹 public void deleteDir(string dir) { try { Directory.Delete(dir, true); } catch { foreach (string file in Directory.GetFiles(dir)) { FileInfo info = new FileInfo(file); info.Attributes = FileAttributes.Normal; File.Delete(file); } Directory.Delete(dir); } }
代码二:
将IWorkspace转为IDataset,然后使用IDataset.Delete();进行删除。最好不要使用System.IO.File.Delete(path); 根据mdb或FileGDB的路径删除,这种方法可能删除不掉或者删不干净。
IDataset dataset = pWorkspace as IDataset; dataset.Delete();
注意:删除该workspace之前需要将使用到的FeatureClass,Feature,FeatureCursor,Field等AO对象先释放掉,可以使用System.Runtime.InteropServices.Marshal.FinalReleaseComObject();释放。
IWorkspaceFactory pWF = new FileGDBWorkspaceFactoryClass(); IWorkspace pW = pWF.OpenFromFile(gdbPath); IFeatureWorkspace pWorkspace = pW as IFeatureWorkspace; ..... IDataset dataset = pWorkspace as IDataset; dataset.Delete();
3.2 资源解除占用
3.2.1 杀死文件:
Process[] pcs = Process.GetProcesses(); foreach (Process p in pcs) { if (p.MainModule.FileName == "你的文件路径") { p.Kill(); } }
3.2.2 解除资源锁定:
ArcEngine /AO创建IWorkSpaceFactory的两种方式: //第一种使用ae的工厂方法: IWorkspaceFactory pWsFactory = new ShapefileWorkspaceFactoryClass(); IFeatureWorkspace pWorkSpace = pWsFactory.OpenFromFile(path, 0) as IFeatureWorkspace; //第二种使用C#的动态创建类型的方法: Type typeObj=Type .GetTypeFromProgID("esriWorkspaceType.ShapefileWorkspaceFactoryClass" ); IWorkspaceFactory pWsFactory = (IWorkspaceFactory)Activator.CreateInstance(typeObj,null); IFeatureWorkspace pWorkSpace = pWsFactory.OpenFromFile(path, 0) as IFeatureWorkspace; //关闭资源锁定 IWorkspaceFactoryLockControl ipWsFactoryLock = IWorkspaceFactoryLockControl)pWsFactory; //pWsFactory可以是GDB/SHP/MDB if(ipWsFactoryLock.SchemaLockingEnabled) { ipWsFactoryLock.DisableSchemaLocking(); }
3.2.3 资源释放问题
AE中对MDB,SDE等数据库操作时,打开后却往往不能及时释放资源,导致别人操作提示对象被锁定。很多帖子说了很多原理,看的也烦且不实用,比如一句话概括的用System.Runtime.InteropServices.Marshal.ReleaseComObject(object o) 释放,说的很不清楚,很多人试过觉的释放不掉。事实上,的确是用该方法,但释放的技巧在于,新建几个AE对象就要逐步释放几个,例如:
IWorkspaceFactory Fact = new AccessWorkspaceFactoryClass (); IFeatureWorkspace Workspace = Fact.Open(Propset,0) as IFeatureWorkspace; IFeatureClass Fcls = Workspace.OpenFeatureClass ("District"); IFeatureLayer Fly = new FeatureLayerClass(); …… IFeature pf IField pfield ……
再对象运行结束时释放,如:
System.Runtime.InteropServices.Marshal.ReleaseComObject(Fact) System.Runtime.InteropServices.Marshal.ReleaseComObject(Workspace); System.Runtime.InteropServices.Marshal.ReleaseComObject(Fcls); System.Runtime.InteropServices.Marshal.ReleaseComObject(Fly); System.Runtime.InteropServices.Marshal.ReleaseComObject(pf); System.Runtime.InteropServices.Marshal.ReleaseComObject(pfield);
看到吧,千万不要以为你释放了等级最高的 IWorkspaceFactory, IWorkspace就算完事了。没办法,AE有时就这么难以理解的麻烦。
4 从gdb中拷贝图层到mdb中
主要是为了调用 IFeatureDataConverter.ConvertFeatureClass 方法:
public IEnumInvalidObject ConvertFeatureClass ( IFeatureClassNameInputDatasetName, IQueryFilterInputQueryFilter, IFeatureDatasetNameoutputFDatasetName, IFeatureClassNameoutputFClassName, IGeometryDefOutputGeometryDef, IFieldsOutputFields, stringconfigKey, intFlushInterval, intparentHWND);
为了给该函数提供参数,进行如下步骤拆解:
从gdb中获取感兴趣图层
从gdb中获取感兴趣图层的名称
打开mdb文件
判断要拷贝文件是否存在,存在删除
将gdb待拷贝图层字段赋值到mdb目标图层
设置集合定义
设置查询条件
调用转换函数
4.1 从gdb中获取感兴趣图层
- 打开工作空间工厂
- 从文件中打开工作空间,将工作空间跳转为要素工作空间
- 从要素工作空间中打开要素类
IWorkspaceFactory workspaceFactory = new ESRI.ArcGIS.DataSourcesGDB.FileGDBWorkspaceFactoryClass(); IWorkspace iworkspace = iworkspaceFactory.OpenFromFile(inPath, 0); IFeatureWorkspace ifeatureWorkspace = (IFeatureWorkspace)iworkspace; IFeatureClass ipFeaterClass = ifeatureWorkspace.OpenFeatureClass(checkLayerName);
4.2 获取gdb感兴趣图层的图层名
IWorkspaceName inWorkspaceName = (inWorkspace as IDataset).FullName as IWorkspaceName ; IFeatureClassName inFeatureClassName = new FeatureClassNameClass(); IDatasetName inDatasetName = (IDatasetName)inFeatureClassName; inDatasetName.WorkspaceName = inWorkspaceName; inDatasetName.Name = gdbLayerName;
4.3 打开mdb文件
IWorkspaceFactory oworkspaceFactory = new AccessWorkspaceFactory(); IWorkspace oworkspace = oworkspaceFactory.OpenFromFile(inPath, 0); IFeatureWorkspace ofeatureWorkspace = (IFeatureWorkspace)workspace; IFeatureClass poFeaterClass = ofeatureWorkspace.OpenFeatureClass(mdbLayerName);
4.4 判断要拷贝到mdb的文件是否存在
IWorkspace2 oworkspace2 = (IWorkspace2)oworkspace; if (oworkspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, checkLayerName + "_超出图层检查结果")) { IFeatureClass pFC = ofeatureWorkspace.OpenFeatureClass(checkLayerName + "_超出图层检查结果"); IDataset pDS = pFC as IDataset; pDS.Delete(); }
4.5 输出mdb图层名设置
IWorkspaceName ouWorkspaceName = (ouWorkspace as IDataset).FullName as IWorkspaceName ; IFeatureClassName ouFeatureClassName = new FeatureClassNameClass(); IDatasetName ouDatasetName = (IDatasetName)ouFeatureClassName; ouDatasetName.WorkspaceName = ouWorkspaceName; ouDatasetName.Name = mdbLayerName;
4.6 字段赋值
IFieldChecker fieldChecker = new FieldCheckerClass(); fieldChecker.InputWorkspace = iworkspace;//输入数据集工作空间 fieldChecker.ValidateWorkspace = ouWorkpace;//输出工作空间 IFields outFeatureClassFields; IEnumFieldError enumFieldError; fieldChecker.Validate(inFeatureClassFields, out enumFieldError, out outFeatureClassFields);
4.7 设置几何定义
IField geometryField = outFeatureClassFields.get_Field(outFeatureClassFields.FindField(inFeatureClass.ShapeFieldName)); IGeometryDef geometryDef = geometryField.GeometryDef;
4.8 满足条件的数据查询
//Set up the IQueryFilter to convert all the features by leaving a blank WhereClause QueryFilter qf = new QueryFilterClass(); qf.WhereClause = "";
4.9 数据转换
IFeatureDataConverter fctofc = new FeatureDataConverterClass(); IEnumInvalidObject enumErrors = fctofc.ConvertFeatureClass(inFeatureClassName, qf, null, outFeatureClassName, geometryDef, outFeatureClassFields, "", 1000, 0);
参考资料:从FileGDB导出shp
5 其他代码积累
5.1 添加或删除字段
/// <summary> /// 删除属性表字段 /// </summary> /// <param name="layer">需要添加字段的IFeatureLayer</param> /// <param name="fieldName">添加的字段的名称</param> /// <returns></returns> static public bool DeleteField(IFeatureLayer layer, string fieldName) { try { ITable pTable = (ITable)layer; IFields pfields; IField pfield; pfields = pTable.Fields; int fieldIndex = pfields.FindField(fieldName); pfield = pfields.get_Field(fieldIndex); pTable.DeleteField(pfield); return true; } catch (Exception ex) { return false; } } /// <summary> /// 添加字段 /// </summary> /// <param name="layer"></param> /// <param name="fieldName"></param> /// <param name="filedType"></param> /// <param name="fieldLength"></param> /// <returns></returns> static public bool AddField(IFeatureLayer layer, string fieldName, esriFieldType filedType, int fieldLength) { try { IFields pFields = layer.FeatureClass.Fields; // IFieldsEdit pFieldsEdit = pFields as IFieldsEdit; IFieldEdit pFieldEdit; pFieldEdit = new FieldClass(); if (fieldName.Length > 5) pFieldEdit.Name_2 = fieldName.Substring(0, 5); else pFieldEdit.Name_2 = fieldName; pFieldEdit.Type_2 = filedType; pFieldEdit.Editable_2 = true; pFieldEdit.AliasName_2 = fieldName; pFieldEdit.Length_2 = fieldLength; ITable pTable = (ITable)layer; pTable.AddField(pFieldEdit); return true; // pFieldsEdit.AddField((IField)pFieldEdit); } catch (Exception ex) { return false; } }