DataSet(数据集对象)可以分为两大类,一种是Table,我们无法将Table存储在要素数据集中(可以尝试下),一种是Geodataset,这个是要素类的容器。
DataSet有一个很重要的属性,就是这个Fullname,用这个可以返回和数据集相关的IName(名称对象),而这个名称对象有一个很重要的方法Open(),这个可以获取和这个名称对象相关的对象(内存中的),Open()方法的返回值是object,所以用Open方法的时候,我们必须心里清楚,自己到底是要得到那个对象,然后QI到我们要的对象上。
IName对象是一个代表性对象。通过使用IName对象,可以访问它所代表的对象的一些基本属性,而不用将整个对象调入内存。我们用IWorkspace获得一个Workspace,那可是会调入内存的,而IWorkspaceName则不会,除非你用了IWorkspaceName.open.在我看来,那些继承IName的接口,在数据转换和叠加分析的时候经常要用到这个。
IName 是一个抽象类,拥有很多子类,借助它的子类IWorkspaceName也可以打开数据库。打开一个数据库,我们要指定它的类型,是个人数据库,还是文件数据库。IWorkspaceName的IWorkspaceName.WorkspaceFactoryProgID 属性用于完成这一操作,这个属性是一个枚举的常量类型
• esriDataSourcesGDB.AccessWorkspaceFactory
• esriDataSourcesFile.ArcInfoWorkspaceFactory
• esriDataSourcesFile.CadWorkspaceFactory
• esriDataSourcesGDB.FileGDBWorkspaceFactory
• esriDataSourcesOleDB.OLEDBWorkspaceFactory
• esriDataSourcesFile.PCCoverageWorkspaceFactory
• esriDataSourcesRaster.RasterWorkspaceFactory
• esriDataSourcesGDB.SdeWorkspaceFactory
• esriDataSourcesFile.ShapefileWorkspaceFactory
• esriDataSourcesOleDB.TextFileWorkspaceFactory
• esriDataSourcesFile.TinWorkspaceFactory• esriDataSourcesFile.VpfWorkspaceFactory
示例一:(正用)
public IWorkspace Get_Workspace(string _pWorkspacePath) { IWorkspaceName pWorkspaceName = new WorkspaceNameClass(); pWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.AccessWorkspaceFactory"; pWorkspaceName.PathName = _pWorkspacePath; IName pName = pWorkspaceName as IName; IWorkspace pWorkspace = pName.Open() as IWorkspace; return pWorkspace; }
示例二: 当图层不能正常访问,需要修复数据源时,上面方法获取的IFeatureClass为空,这时可以通过如下方式得到图层的数据源路径(反用)public static string LayerToShapefilePath(ILayer pLayer) { string filename = ""; IDataLayer2 pDLayer = (IDataLayer2)pLayer; IDatasetName pDsName = (IDatasetName)(pDLayer.DataSourceName); string dsname = pDsName.Name; IWorkspaceName ws = pDsName.WorkspaceName; filename = ws.PathName+"\\"+dsname+".shp"; return filename; }
应用示例:若进行叠加求交分析时,如果要进行多个图层的叠加,而此时输入的参数是图层,那么我们可以利用示例二,通过图层对象获取其数据源的路径。
实际上在ArcMap中的 Table of Contents(如下图)应该就是这样实现的:(左:图层)(右:数据源)
数据转换:IFeatureDataConverter 接口
例子:
IFeatureLayer featureLayer=pLayer as IFeatureLayer; IFeatureClass inputFeatureClass = featureLayer.FeatureClass; IDataset inputDataset = (IDataset)inputFeatureClass; // IDatasetName inputDatasetName = (IDatasetName)inputDataset.FullName; IFeatureClassName inputclassName = (IFeatureClassName)inputDataset.FullName ; // Get the layer's selection set. //利用属性打开 IPropertySet ps = new PropertySetClass(); ps.SetProperty("DATABASE", fd.SelectedPath); IWorkspaceFactory wsf = new FileGDBWorkspaceFactoryClass(); IWorkspace ws = null; try { ws = wsf.Open(ps, 0); } catch (Exception e) { } //设置输出要素属性 IDataset ds = (IDataset)ws; IWorkspaceName wsName = (IWorkspaceName)ds.FullName; IFeatureClassName featClsName = new FeatureClassNameClass(); IDatasetName dsName = (IDatasetName)featClsName; dsName.WorkspaceName = wsName; dsName.Name = pLayer.Name; Use the IFieldChecker interface to make sure all of the field names are valid for a shapefile. IFieldChecker fieldChecker = new FieldCheckerClass(); IFields shapefileFields = null; IEnumFieldError enumFieldError = null; fieldChecker.InputWorkspace = inputDataset.Workspace; fieldChecker.ValidateWorkspace = ws; //out and ref //用Ref型参数时,传入的参数必须先被初始化。而Out则不要要,对Out而言,就必须在方法中对其完成初始化。 // ///用Ref和Out时都必须注意,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。 /// Out更适合用在要要Return多个返回值的地方,而Ref则用在要要被调出使用的方法修改调出使用者的引用的时候。 fieldChecker.Validate(inputFeatureClass.Fields, out enumFieldError, out shapefileFields); // At this point, reporting/inspecting invalid fields would be useful, but for this example it's omitted. // We also need to retrieve the GeometryDef from the input feature class. int shapeFieldPosition = inputFeatureClass.FindField(inputFeatureClass.ShapeFieldName); IFields inputFields = inputFeatureClass.Fields; IField shapeField = inputFields.get_Field(shapeFieldPosition); IGeometryDef geometryDef = shapeField.GeometryDef; IGeometryDef pGeometryDef = new GeometryDef(); IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit; pGeometryDefEdit.GeometryType_2 = inputFeatureClass.ShapeType; pGeometryDefEdit.SpatialReference_2 = mapcontrol3.Map.SpatialReference; // Now we can create a feature data converter. IFeatureDataConverter featureDataConverter = new FeatureDataConverterClass(); IEnumInvalidObject enumInvalidObject = featureDataConverter.ConvertFeatureClass(inputclassName, null, null, featClsName, pGeometryDef, shapefileFields, "", 1000, 0);