风过无痕 原文向已存在的要素类中添加字段

以前,在用AE写程序的时候,为了方便,一般都是直接新建一个MapControl窗体应用程序。这次需要解决的问题用不到窗口,就突发奇想,直接新建了一个Console应用程序。然后,就按照以前的习惯引用了必要的命名空间,对其进行显式声明,直接开始写代码。可是,事后才发现其实这里隐藏着一个问题。后来,在调试的时候,发现运行到一处,就是下面的这段:

IWorkspace pWorkspace = pWSF.OpenFromFile(path, );
IFeatureWorkspace pFWS = pWorkspace as IFeatureWorkspace;
pFC = pFWS.OpenFeatureClass(file);

运行到这里的时候,程序会报HRESULT_0x80040228错误。起初的时候,我以为是打开featureclass的代码有误,于是就仔细的看了几遍,可是都没有发现哪里不对。无奈之下,上网Google了一下,才发现是License验证的问题。这才醒悟,以前都是利用的MapControl程序,License验证之类的工作,都是工程初始化的时候就完成了。这里是新建的一个Console程序,却忘了手动的来进行验证。问题发现了,解决的办法也就很简单了。在VS中,单击项目,选中Add ArcGIS Checking选项即可。

  做了以上的工作之后,代码继续的运行。在向featureclass中的某个字段进行赋值的时候,弹出错误窗口,调试程序发现是字段没有添加成功。我起初写的向要素类中添加字段的函数如下:

static void AddFiled(IFeatureClass pFC,string name)
{ IFields pFields = pFC.Fields;
IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
IField pField = new FieldClass();
IFieldEdit pFieldEdit = pField as IFieldEdit;
pFieldEdit.Name_2 = name;
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
pFields.AddField(pField); }

看着,好像是没有错误。后来,查看了文档,才发现问题之所在。在向已存在的要素类中添加字段的时候,需要用到ICLASS接口。于是,进一步的调整代码如下,问题得以解决。

static void AddFiled(IFeatureClass pFC,string name)
{
DeleteFile(pFC, name);
IFields pFields = pFC.Fields;
IClass pClass = pFC as IClass;
IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
IField pField = new FieldClass();
IFieldEdit pFieldEdit = pField as IFieldEdit;
pFieldEdit.Name_2 = name;
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
pClass.AddField(pField);
}

除此之外,还碰到了一个印象比较深刻的问题,就是在几经尝试之后,终于确定了在AE中,要素类中的OID字段,无法获取。即像这样:

int i = Convert.ToInt32(pFeature.get_Value(pFeature.Fields.FindField(“OID”)));

以上代码,在AE中是通不过的。这样,我只好改变原始的想法,另外的在featureclass中添加了一新的tempID字段,用来生成包含空间关系的邻接矩阵。

总结:

  1)在写AE程序的时候,一定要进行License的验证。如果是WinForm程序,可以向窗口上拖放一个ArcGIS License控件;如果是Console程序,可以添加ArcGIS License Checking代码,实现的方式上面已经提及。

  2)在向已存在的要素类中添加新字段的时候,需要用到IClass接口。

  3)要素类中的OID字段,无法利用代码进行获取。

最近的几天,又在网上陆续的发现了好多示例代码,还是继续的使用着IFieldsEdit接口的AddField方法,以致使我都不由的怀疑起来,是不是我一直以来想的都不对。在此疑惑之下,才有了这次行动,来验证到底利用IFieldsEdit接口能不能成功的向已存在的FeatureClass中添加新的字段。

  一番行动下来,事实告诉我,我并没有错,利用IFieldsEdit接口中的方法确实不能向已存在的FeatureClass中添加新字段。但同时,我也发现了一个问题,苦思之下仍然无解,就趁此机会一并拿出和大家分享交流吧。

  说一下我所用的方法吧。很简单,我分别通过两种方法来添加字段,然后检查字段是否成功的添加。可是,就是在这个过程中,我也发现了一个我没有想明白的问题。这是后话,还是一步一步的说吧。

  首先,老规矩,贴出来我写的垃圾代码吧。

  1)通过IFieldsEdit接口的AddField方法的函数

static void AddField_IFields(IFeatureClass pFC, string name)
{
IFields pFields = pFC.Fields;
IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
IField pField = new FieldClass();
IFieldEdit pFieldEdit = pField as IFieldEdit;
pFieldEdit.Name_2 = name;
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
pFieldsEdit.AddField(pField);
}

2)通过IClass接口的AddField方法的函数

static void AddField_IClass(IFeatureClass pFc, string name)
{
IFields pFields = pFc.Fields;
IClass pClass = pFc as IClass;
IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
IField pField = new FieldClass();
IFieldEdit pFieldEdit = pField as IFieldEdit;
pFieldEdit.Name_2 = name;
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger;
pClass.AddField(pField);
}

准备工作做好后,我们就可以进行下一步的工作,向FeatureClass中添加字段,并查找其在属性表中的序号,来验证其是否添加成功。代码如下:

static void Main(string[] args)
{
//ESRI License Initializer generated code.
m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeEngine },
new esriLicenseExtensionCode[] { });
string strFile = @"D:\Test\select.shp";
IFeatureClass pFC = ReturnFC(strFile);
string name1 = "ByIFields";
string name2 = "ByIClass";
AddField_IFields(pFC, name1);
AddField_IClass(pFC, name2);
int index_IFields = GetFieldIndex(pFC, name1);
int index_IClass = GetFieldIndex(pFC, name2);
Console.WriteLine("{0}字段的序号是:{1}",name1,index_IFields);
Console.WriteLine("{0}字段的序号是:{1}", name2,index_IClass);
Console.ReadKey();
}

  貌似通过这两种方法,都成功的向FeatureClass中添加了字段,可以成功的查询到加入的字段在属性表中的序号。好,我们先暂且不管这个。继续的往下做。我们将添加字段的那两条语句注释掉,然后重新的运行一下程序。

  工作做到这里,我们就会发现问题了。在向FeatureClass中添加完字段后,如果立刻进行查找,我们就会得到我们想到的结果,那就是添加成功。而如果,我们什么都不做,重新的对添加进去的字段进行查找的时候,我们就会发现,通过IFieldsEdit接口的AddField方法并没有向FeatureClass中加入新字段。属性表也可以表明这一点。

  因此,结论如下:向已存在的FeatureClass中添加新字段,需要使用IClass接口的AddField方法,而如果使用IFieldsEdit接口的AddField方法并不能成功的添加。但是,为何在添加字段后接着进行验证,可以返回积极的结果,暂时我还不知道原因。可能咨询一下ESRI公司是个可能的途径,同时也希望知道的同学可以给我一些指导。

AE 向已存在的要素类中添加字段的更多相关文章

  1. C#读取shp文件并获取图形保存到sde要素类中(不使用ESRI的类库,纯c#实现)

    说明:首先要将sde要素类发布成对应的要素服务,通过对要素服务的操作,实现数据在sde要素类中的增删 //向服务器发出请求 public string getPostData(string postS ...

  2. 向已写好的多行插入sql语句中添加字段和值

    #region 添加支款方式--向已写好的多行插入sql语句中添加字段和值 public int A_ZhifuFS(int diqu) { ; string strData = @"SEL ...

  3. 在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出MethodArgumentNotValidException异常,因此,只需要在ExceptionHandler类中添加处理对应异常的方法即可。

    在SpringMVC中,当Json序列化,反序列化失败的时候,会抛出HttpMessageNotReadableException异常, 当Bean validation失败的时候,会抛出Method ...

  4. C#类中的字段、属性和方法

    C#类中的字段.属性和方法 刚开始学C#,对于类中的字段.属性和方法很难分清,写下这份笔记,帮助理解 字段:与类相关的变量 声明方法与声明变量类似,可在前面添加访问修饰符.static关键字等: 属性 ...

  5. Django 向数据表中添加字段方法

    在模型order中添加字段discount字段,并给予初始值0 方法: 先在models.py中修改模型 添加 discount = models.DecimalField(max_digits=8, ...

  6. 【2016.3.30项目技术记录】]VS2010自动生成MFC单文档框架程序的修改:去除属性框,在CViewTree类中添加鼠标单击响应

    转自http://blog.csdn.net/yanfeiouc2009/archive/2010/06/07/5653360.aspx 手头上有个东西要用到单文档,由于想省事,直接用VS2010做了 ...

  7. Type.GetField 修改类中私有字段。

    上一篇Popup Bug中修改了SystemParameters类中静态只读属性MenuDropAlignment. var t = typeof(SystemParameters); var fie ...

  8. 向OC类中添加默认的协议实现(ProtocolKit)

    以forkingdog的PorotocolKit举例 举例 ProtocolKit Protocol extension for Objective-C Usage Your protocol: @p ...

  9. 类中添加log4j日志

    在编写代码的时候需要随时查看工作日志,查看工作日志的好处就是随时能检查出错误.所以我一般就需要在编写代码的前期添加工作日志,以便更好的查看相关错误输出. 以一个springmvc小demo为例子  主 ...

随机推荐

  1. es6 -- 透彻掌握Promise的使用,读这篇就够了

    Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻.这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现. 在实际的使用当中,有非常多的应用场景我们不能 ...

  2. javaweb一

    JavaWeb就是在服务器端以Java语言为解释运行基础的web程序. php代码要想在服务器端运行,需要在服务器软件(通常是Apache)上加php的解释器,Java也一样,但是这个解释器是Tomc ...

  3. OpenCV —— 图像变换

    将一副图像转变成另一种表现形式 ,比如,傅里叶变换将图像转换成频谱分量 卷积 —— 变换的基础 cvFilter2D  源图像 src 和目标图像 dst 大小应该相同 注意:卷积核的系数应该是浮点类 ...

  4. PHP表单生成器,快速生成现代化的form表单,快速上手

    form-builder PHP表单生成器,快速生成现代化的form表单.包含复选框.单选框.输入框.下拉选择框等元素以及省市区三级联动.时间选择.日期选择.颜色选择.树型.文件/图片上传等功能. 详 ...

  5. django模型系统二

    常用查询及表关系的实现 1.常用查询 每一个django模型类,都有一个默认的管理器 objects QuerySet表示数据库中对象的列表,它可以有0到多个过滤器.过滤器通过给定参数,缩小查询范围. ...

  6. 今日SGU 5.1

    SGU 100 题意: 普通的a+b #include<bits/stdc++.h> #define de(x) cout<<#x<<"="&l ...

  7. python中lambda的另类使用

    带if/else: ( lambda x, y: x if x < y else y )( 1, 2 ) 科里化: ( lambda x: ( lambda y: ( lambda z: x + ...

  8. php课程 12-39 继承中parent的作用是什么

    php课程 12-39 继承中parent的作用是什么 一.总结 一句话总结:PHP5中使用parent::来引用父类的方法.parent:: 可用于调用父类中定义的成员方法. parent::的追溯 ...

  9. php实现遍历文件目录

    php实现遍历文件目录 一.总结 1.熟悉简单:很经典的例子,多看,然后发现熟悉了很简单 二.php实现遍历目录 php实现遍历目录 代码一: //遍历目录 function iteral($path ...

  10. Day3上午解题报告

    预计分数:100+40+50=190 实际分数:100+40+50=190 T1 https://www.luogu.org/problem/show?pid=T15365 表示从来没做过博弈论的题, ...