基于C#的ArcEngine二次开发50:MDB创建新要素类及“无当前记录”异常处理

目录

1 MDB与GDB的区别与联系分析

2 ArcEngine处理GDB、MDB和shape

2.1 获取三类数据

2.2 打开要素类

3 新建要素类

3.1 CreateFeatureClass函数解析

3.2 Fields

3.2.1 方案1-使用IFeatureClassDescription

3.2.2 方案2-先创建再添加

3.3 CLSID

3.4 EXTCLSID

3.5 创建代码

3.6 添加字段


最近做数据处理,需要想MDB中写入一个错误导出图层,没有注意到MDB和GDB的区别,直接使用了GDB 的套路,结果报了“无当前记录”的错误,瞬间懵逼。在网上溜达了一圈,找到都是下面这个答案:

问题:使用 IFeatureWorkspace.CreateFeatureClass() 方法,出现异常:无当前记录百度/谷歌没有找到合适的解决之道.而是用IFeatureWorkspace.CreateTable()方法却正常.要素工作空间为AccessWorkspaceClass(),

原因:不明

解决方法:此段代码直接在Personal Geodatabase中新建要素类,后来改为FileGeoDatabase中新建,出现的异常提示 与空间参考相关.

后来新建FeatureDataset,在FeatureDataset设置空间参考.之后,再在FeatureDataset中新建FeatureClass.成功

看了半天不明所以,问题并没有解决;我理解它的思路是用GDB解决了问题;但是我的需求是导出MDB,所以自己就摸索了一番,把摸索的结果在这里记录一下。

问题原因:CreateFeatureClass的Fields字段出错

我的方案是:先创建只包含SHAPE的要素类,然后再添加字段

1 MDB与GDB的区别与联系分析

这一部分参考源为:https://www.cnblogs.com/xiongyunqi/p/5517118.html

一、平台支援:

1、Personal Geodatabase:仅可在Windows 上运行;

2、File Geodatabase:跨平台支援,可在Windows 及UNIX、linux上运行。

评价:这是个非常大的亮点,使得数据可以更好的移植。

二、存储方式:

1、Personal Geodatabase 是一个MS-Access 的mdb 数据库文档;

2、File Geodatabase 以一个文件夹方式储存。

评价:Personal Geodatabase有依托微软的access数据库的限制,File Geodatabase,可以慢慢摆脱依靠access的限制,不用受制与微软的技术。

三、存储限制:

1、Personal Geodatabase:相同于MS Accesss 限制,数据库最大容量为2GB。

2、File Geodatabase:数据库无限制,每个表限制为1TB(1000GB)。

评价:File Geodatabase支持对海量数据的处理。

四、储存空间

同样的资料,在File Geodatabase 中比Personal Geodatabase 和Shapefile占用的硬盘空间更少,通常可以减少50%~70%,最多可减少到1/5。

五、效能:

File Geodatabase 相较于Personal Geodatabase 处理数据的速度可快20%到10倍,这部分随着资料量的增加,效能差异越大。

六、是否支持数据压缩:

1、Personal Geodatabase:不支持数据压缩。

2、File Geodatabase:支持一种新的数据压缩格式,在查询与显示方面均与未压缩格式相同,压缩比率可从2:1 到25:1。

2 ArcEngine处理GDB、MDB和shape

2.1 获取三类数据

E中,GDB和MDB的获取方式是不同的,对于GDB的工作空间工厂为:

IWorkspaceFactory pWF = new FileGDBWorkspaceFactoryClass();
IWorkspace pWS = pWF.OpenFromFile(gdbPath, 0);

而打开MDB的代码为:

IWorkspaceFactory pWF = new AccessWorkspaceFactoryClass();
IWorkspace pWS = pWF.OpenFromFile(gdbPath, 0);

获取Shape文件的代码为:

IWorkspaceFactory pWF = new ShapefileWorkspaceFactoryClass();
IWorkspace pWS = pWF.OpenFromFile(shapeDir, 0);

显然在AE中,采用了三种不同的方式来处理三类数据,其中MDB和shape表现的是文件的形式,而GDB则是以文件夹的形式表示;但是有一点是相同的,在使用OpenFromFile打开时,GDB和mdb传的是完整路径,而shape文件则传的是其上级目录。

2.2 打开要素类

所谓殊途同归,在这里最合适不过了,打开要素类,三种数据源不约而同的使用OpenFeatureClass函数:

IFeatureWorkspace pFWs = pWS as IFeatureWorkspace;
IFeatureClass pFeaCls = pWS.OpenFeatureClass("LRDL");

但是还是要注意以下几点:

  1. GDB使用该方法只能打开直接存放在GDB下的要素类,要打开存放在要素集中要素类,需要先打开要素集FeatureDataset
  2. shape文件传递的参数是shape的文件名称,因为shape的文件名即要素类名称

3 新建要素类

本文要解决的主要问题是MDB中新建要素类,之前的权当铺垫。

3.1 CreateFeatureClass函数解析

该方法包含以上7个参数:

public IFeatureClass CreateFeatureClass (     

    stringName,

    IFieldsFields,

    UIDCLSID,

    UIDEXTCLSID,

    esriFeatureTypeFeatureType,

    stringShapeFieldName,

    stringConfigKeyword);

参数1为要素类的名字,必备参数;

参数2为字段集,表示为创建的要素类添加的字段;

CLSID为要素类的要素的类型,如点线面等;

EXTCLSID表示拓展要素类UID,具体没搞明白,直接填null;

FeatureType表示要素的类型,这个是标识要素是简单图形,还是其他图形;

ShapeFieldName表示图形字段的名称

ConfigKeyword表示配置关键字,一般写null.

 

3.2 Fields

其中报的无当前记录异常,就是出在Fields字段上

一次性创造了好几个字段,然后一把整进去,结果就报了错;实际上AE内部是不让咱这么干的,在你创建的时候只有几个关键字段,如OBJECTID、Shape等,这些默认字段;其余的字段,你要想加,只能是要素类创建完成了,再一个一个往里边添加。这么分析未知对错,但是解决了我遇到的这个问题

3.2.1 方案1-使用IFeatureClassDescription

IFeatureClassDescription fcDescription = new FeatureClassDescriptionClass();
IObjectClassDescription ocDescription = (IObjectClassDescription)fcDescription;
IFields fields = ocDescription.RequiredFields;

使用这个代码倒是解决了异常,投影没办法设置,想做实验的参考这篇文章:AE新建工作空间要素类示例

3.2.2 方案2-先创建再添加

  • 首先定义几何图形的类型、参考系统、字段名称、几何类型
//设置几何图形类型
IGeometryDef geometryDef = shpfield.GeometryDef;
IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;

//设置参考系统
ISpatialReferenceFactory3 spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
ISpatialReference spatialReference = spatialReferenceFactory.CreateSpatialReference((int)esriSRGeoCSType.esriSRGeoCS_WGS1984);

geometryDefEdit.SpatialReference_2 = spatialReference;

//创建字段并赋值
IField field = new FieldClass();
IFieldEdit fieldEdit = (IFieldEdit)field;
fieldEdit.Name_2 = "Shape";
fieldEdit.Type_2 = esriFieldType.esriGeometryType;
fieldEdit.GeometryDef_2 = geometryDef;


fieldsEdit.AddField(field);

3.3 CLSID

 //pUidClsID字段为空时
 if (pUidClsId == null)
 {
     pUidClsId = new UIDClass();
     switch (pFeatureType)
     {
         case (esriFeatureType.esriFTSimple):
             if (pGeometryType == esriGeometryType.esriGeometryLine)
                 pGeometryType = esriGeometryType.esriGeometryPolyline;
             pUidClsId.Value = "{52353152-891A-11D0-BEC6-00805F7C4268}";
             break;
         case (esriFeatureType.esriFTSimpleJunction):
             pGeometryType = esriGeometryType.esriGeometryPoint;
             pUidClsId.Value = "{CEE8D6B8-55FE-11D1-AE55-0000F80372B4}";
             break;
         case (esriFeatureType.esriFTComplexJunction):
             pUidClsId.Value = "{DF9D71F4-DA32-11D1-AEBA-0000F80372B4}";
             break;
         case (esriFeatureType.esriFTSimpleEdge):
             pGeometryType = esriGeometryType.esriGeometryPolyline;
             pUidClsId.Value = "{E7031C90-55FE-11D1-AE55-0000F80372B4}";
             break;
         case (esriFeatureType.esriFTComplexEdge):
             pGeometryType = esriGeometryType.esriGeometryPolyline;
             pUidClsId.Value = "{A30E8A2A-C50B-11D1-AEA9-0000F80372B4}";
             break;
         case (esriFeatureType.esriFTAnnotation):
             pGeometryType = esriGeometryType.esriGeometryPolygon;
             pUidClsId.Value = "{E3676993-C682-11D2-8A2A-006097AFF44E}";
             break;
         case (esriFeatureType.esriFTDimension):
             pGeometryType = esriGeometryType.esriGeometryPolygon;
             pUidClsId.Value = "{496764FC-E0C9-11D3-80CE-00C04F601565}";
             break;
     }
 }

3.4 EXTCLSID

//pUidClsExt字段为空时
if (pUidClsExt == null)
{
    switch (pFeatureType)
    {
        case esriFeatureType.esriFTAnnotation:
            pUidClsExt = new UIDClass();
            pUidClsExt.Value = "{24429589-D711-11D2-9F41-00C04F6BC6A5}";
            break;
        case esriFeatureType.esriFTDimension:
            pUidClsExt = new UIDClass();
            pUidClsExt.Value = "{48F935E2-DA66-11D3-80CE-00C04F601565}";
            break;
    }
}

3.5 创建代码

tFeatureClass = tFeatureWorkspace.CreateFeatureClass(pName, pFields, pUidClsId,
 pUidClsExt, pFeatureType, strShapeFieldName, pConfigWord);

3.6 添加字段


    int checkFieldIndex = poFeaterClass.FindField("检查结果记录");
    if(checkFieldIndex == -1)
    {
        IFields pFields = new FieldClass();
        IFieldEdit pFieldEdit = pFields as IFieldEdit;
        pFieldEdit.Name_2 = "检查结果记录";
        pFieldEdit.Type_2 = filedType;    
        pFieldEdit.Length_2 = fieldLength;
        poFeaterClass.AddField(pFieldEdit);    
    }
   

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小薛引路

喜欢的读者,可以打赏鼓励一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值