在建立标准的地理数据库时,有时我们会遇上像这样的问题:现有的数据包括了很多的字段,而数据库的入库要求只含有特定的一个或几个字段。这篇文章解决了这样的问题。
功能的界面如下图所示,因为这个功能是项目中数据库系统的一个功能,所以就没有从文件系统中添加要素类的这一流程。标准要素类是指我们要求的含有特定字段的一个要素,这个要素可能是空的也可能并不是,原要素类就是含有很多我们不需要的属性的要素。通过标准要素类的下拉框选择要素后,表的左列会显示标准要素类除“shape”和“objectID”的所有属性字段。表的右列的每一行均为下拉框,当选择了原要素类后,从表中右侧每一个下拉框中选择原要素类的属性字段和左侧的目标字段匹配。另外,两个匹配的属性字段类型一定要一样,不然无法进行操作。
方法中的三个参数分别为原要素类,标准要素类和含有字段对照的二维字符串数组。处理时直接对标准要素类进行操作,主要包括两个操作:图形的复制和属性的复制,这里一定要注意用IFeatureBuffer可以很显著地提高运算速度,而将遍历的每一个图形和属性直接赋值给目标要素这种方式很慢,原因应该是后一种方式是需要不断的读取写入硬盘,而前者是直接读写内存。
/// <summary>
/// 创建标准要素类
/// </summary>
/// <param name="sourceFeatureClass">原要素类</param>
/// <param name="target_FeatureClass">标准要素类</param>
/// <param name="contrastTable">字段对照表,二维数组</param>
/// <returns>返回创建的标准要素类</returns>
public IFeatureClass CreateStandardFeatureClass(IFeatureClass sourceFeatureClass,IFeatureClass target_FeatureClass
,string[,] contrastTable)
{
IFeature pFeature;
IFeatureCursor sourceCursor = sourceFeatureClass.Search(null, false);
//用IFeatureBuffer提高运算速度
IFeatureBuffer pFeaBuffer = null;
IFeatureCursor targetCursor = target_FeatureClass.Insert(true);
while ((pFeature = sourceCursor.NextFeature()) != null)
{
pFeaBuffer = target_FeatureClass.CreateFeatureBuffer();
pFeaBuffer.Shape = pFeature.Shape;
for(int i = 0; i < contrastTable.Length / 2; i++)
{
pFeaBuffer.set_Value(target_FeatureClass.FindField(contrastTable[i,0]), pFeature.Value[sourceFeatureClass.Fields.FindField(contrastTable[i,1])]);
}
targetCursor.InsertFeature(pFeaBuffer);
}
targetCursor.Flush();
//运用IfeatureBuffer和IfeatureCursor时需要手动释放非托管对象
System.Runtime.InteropServices.Marshal.ReleaseComObject(sourceCursor);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pFeaBuffer);
System.Runtime.InteropServices.Marshal.ReleaseComObject(targetCursor);
return target_FeatureClass;
}
同样要注意的是运行时检查是否加了axLicense控件,program.cs中是否加了那几句话等。老规矩,完整代码见github:https://github.com/ranhongwu/190627FeatureStandard 。