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)