AE(C#)Shapefile导入mdb数据库
在CSDN这里得到过许多人提供的帮助,非常感激。一直想把自己写过的代码记录下来,跟各位交流,另一方面以备不时之需。最近在编写Shapefile导入数据库功能,发现在这里没找到多少这方面的知识。经过几天的搜寻,也终于完成了这个功能,可能还存在缺陷,不过程序运行情况良好,下面提供我的主要步骤和核心代码供各位Giser参考。
将Shapefile存入到个人地理数据库,我分为三个步骤:
1.创建个人地理数据库
2.创建要素数据集
3.将Shapefile导入到要素数据集
以下是三个主要方法
/// <summary>/// 创建数据库/// </summary>/// <param name="mdbFolder"></param>/// <param name="mdbName"></param>/// <returns></returns>public IWorkspace CreateMdb(string mdbFolder, string mdbName){IWorkspaceFactory pFtWsFct = new AccessWorkspaceFactory();IWorkspaceName workspaceName = pFtWsFct.Create(mdbFolder, mdbName, null, 0);IFeatureWorkspace pFeatureWorkSpace = (workspaceName as IName).Open() as IFeatureWorkspace;IWorkspace pWorkspace = (workspaceName as IName).Open() as IWorkspace;return pWorkspace;}
/// <summary>// 创建要素数据集/// </summary>/// <param name="workspace"></param>/// <param name="code"></param>/// <param name="datasetName"></param>/// <returns></returns>public IFeatureDataset CreateFeatureClass(IWorkspace workspace, int code, string datasetName){IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;//创建一个要素集创建一个投影ISpatialReferenceFactory spatialRefFactory = new SpatialReferenceEnvironmentClass();ISpatialReference spatialReference = spatialRefFactory.CreateProjectedCoordinateSystem(code);//确定是否支持高精度存储空间Boolean supportsHighPrecision = false;IWorkspaceProperties workspaceProperties = (IWorkspaceProperties)workspace;IWorkspaceProperty workspaceProperty = workspaceProperties.get_Property(esriWorkspacePropertyGroupType.esriWorkspacePropertyGroup,(int)esriWorkspacePropertyType.esriWorkspacePropSupportsHighPrecisionStorage);if (workspaceProperty.IsSupported){supportsHighPrecision = Convert.ToBoolean(workspaceProperty.PropertyValue);}//设置投影精度IControlPrecision2 controlPrecision = (IControlPrecision2)spatialReference;controlPrecision.IsHighPrecision = supportsHighPrecision;//设置容差ISpatialReferenceResolution spatialRefResolution = (ISpatialReferenceResolution)spatialReference;spatialRefResolution.ConstructFromHorizon();spatialRefResolution.SetDefaultXYResolution();ISpatialReferenceTolerance spatialRefTolerance = (ISpatialReferenceTolerance)spatialReference;spatialRefTolerance.SetDefaultXYTolerance();//创建要素集IFeatureDataset featureDataset = featureWorkspace.CreateFeatureDataset(datasetName, spatialReference);return featureDataset;}
/// <summary>/// 获得参照投影的编码/// </summary>/// <param name="tFeatureLayer"></param>/// <returns></returns>public int getSpatialReferenceCode(IFeatureClass tFeatureClass){IDataset dataset = tFeatureClass as IDataset;IGeoDataset geoDataset = (IGeoDataset)dataset;int code = geoDataset.SpatialReference.FactoryCode;return code;}
/// <summary>/// 将Shapefile导入到数据库/// </summary>/// <param name="pFeaClass"></param>/// <param name="pWorkspace"></param>/// <param name="tFeatureClass"></param>private void importToDB(IFeatureClass pFeaClass, IWorkspace pWorkspace, IFeatureDataset tFeatureClass,string SHPName){IFeatureClassDescription featureClassDescription = new FeatureClassDescriptionClass();IObjectClassDescription objectClassDescription = featureClassDescription as IObjectClassDescription;IFields pFields = pFeaClass.Fields;IFieldChecker pFieldChecker = new FieldCheckerClass();IEnumFieldError pEnumFieldError = null;IFields vFields = null;pFieldChecker.ValidateWorkspace = pWorkspace as IWorkspace;pFieldChecker.Validate(pFields, out pEnumFieldError, out vFields);IFeatureWorkspace featureWorkspace = pWorkspace as IFeatureWorkspace;IFeatureClass sdeFeatureClass = null;if (sdeFeatureClass == null){sdeFeatureClass = tFeatureClass.CreateFeatureClass(SHPName, vFields,objectClassDescription.InstanceCLSID, objectClassDescription.ClassExtensionCLSID,pFeaClass.FeatureType , pFeaClass.ShapeFieldName, "");IFeatureCursor featureCursor = pFeaClass.Search(null, true);IFeature feature = featureCursor.NextFeature();IFeatureCursor sdeFeatureCursor = sdeFeatureClass.Insert(true);IFeatureBuffer sdeFeatureBuffer;while (feature != null){sdeFeatureBuffer = sdeFeatureClass.CreateFeatureBuffer();IField shpField = new FieldClass();IFields shpFields = feature.Fields;for (int i = 0; i < shpFields.FieldCount; i++){shpField = shpFields.get_Field(i);if (shpField.Name.Contains("Area") || shpField.Name.Contains("Leng") || shpField.Name.Contains("FID")) continue;int index = sdeFeatureBuffer.Fields.FindField(shpField.Name);if (index != -1){sdeFeatureBuffer.set_Value(index, feature.get_Value(i));}}sdeFeatureCursor.InsertFeature(sdeFeatureBuffer);sdeFeatureCursor.Flush();feature = featureCursor.NextFeature();}featureCursor.Flush();Marshal.ReleaseComObject(feature);Marshal.ReleaseComObject(featureCursor);}}
/// <summary>/// 导入到数据库/// </summary>/// <param name="sourceFeatureClass"></param>/// <param name="pWorkspace"></param>/// <param name="targetFeatureDataset"></param>private void importToDB(IFeatureClass sourceFeatureClass, IWorkspace pWorkspace, IFeatureDataset targetFeatureDataset,string SHPName){IFeatureClassDescription featureClassDescription = new FeatureClassDescriptionClass();IObjectClassDescription objectClassDescription = featureClassDescription as IObjectClassDescription;IFields pFields = sourceFeatureClass.Fields;IFieldChecker pFieldChecker = new FieldCheckerClass();IEnumFieldError pEnumFieldError = null;IFields vFields = null;pFieldChecker.ValidateWorkspace = pWorkspace as IWorkspace;pFieldChecker.Validate(pFields, out pEnumFieldError, out vFields);IFeatureWorkspace featureWorkspace = pWorkspace as IFeatureWorkspace;IFeatureClass sdeFeatureClass = null;if (sdeFeatureClass == null){sdeFeatureClass = targetFeatureDataset.CreateFeatureClass(SHPName, vFields,objectClassDescription.InstanceCLSID, objectClassDescription.ClassExtensionCLSID,sourceFeatureClass.FeatureType , sourceFeatureClass.ShapeFieldName, "");IFeatureCursor featureCursor = sourceFeatureClass.Search(null, true);IFeature feature = featureCursor.NextFeature();IFeatureCursor sdeFeatureCursor = sdeFeatureClass.Insert(true);IFeatureBuffer sdeFeatureBuffer;while (feature != null){sdeFeatureBuffer = sdeFeatureClass.CreateFeatureBuffer();IField shpField = new FieldClass();IFields shpFields = feature.Fields;for (int i = 0; i < shpFields.FieldCount; i++){shpField = shpFields.get_Field(i);if (shpField.Name.Contains("Area") || shpField.Name.Contains("Leng") || shpField.Name.Contains("FID")) continue;int index = sdeFeatureBuffer.Fields.FindField(shpField.Name);if (index != -1){sdeFeatureBuffer.set_Value(index, feature.get_Value(i));}}sdeFeatureCursor.InsertFeature(sdeFeatureBuffer);sdeFeatureCursor.Flush();feature = featureCursor.NextFeature();}featureCursor.Flush();Marshal.ReleaseComObject(feature);Marshal.ReleaseComObject(featureCursor);}}
调用方法:
public void startOutput(){IFeatureLayer mCphFeatureLayer = OpenShapeFile.openShapeFile(mCphPath);//这是获得要入库的shapefile,获取其FeatureLayer即可//1.创建数据库IWorkspace pWorkspace = CreateMdb(mDBPath, mDBName);//参数为mdb的目录路径和数据库名//2.创建要素数据集IFeatureClass pCphFeatureClass = mCphFeatureLayer.FeatureClass;int code = getSpatialReferenceCode(mCphFeatureLayer);//参照投影的代号string datasetName = pCphFeatureClass.AliasName;//要素数据集的名称IFeatureDataset pCphDataset = CreateFeatureClass(pWorkspace, code, datasetName);//3.导入SHP到要素数据集(importToDB(pCphFeatureClass, pWorkspace, pCphDataset, pCphFeatureClass.AliasName);}
至此,SHP入库完成。由于网上代码比较少,费了较长时间在这个功能上,中间还出了很多错误。借鉴我的错误在此提醒一下大家:
1.导入到库里的Shapefile名字不能以数字开头(上课没认真听,我竟然不知道有这个,害我瞎折腾了一番),不然导出来的图层在放大到一定范围后会报错。
2.使用线程运行的话,在线程外传递IFeatureLayer等参数到线程内操作是不行的,不熟悉线程,不知道是ArcEngine的问题还是线程操作不当的问题,在set_Value的时候,一直报“The coordinates or measures are out of bounds.”的错误。后来受同学指点,线程参数只传递string类型,就不报错了。
这两个问题让我折腾了好几天,在这里给大家提醒一下了。当然大牛就忽略吧,或者指点下小弟为什么会有这两个问题,小弟会感激不尽的。
希望这些代码能帮助到有需要的人,在此也感谢CSDN各位大牛的帮助。第一次写博客,就到这里吧
赞 (0)
