ArcEngine 字段小结


字段的基础知识

定义表中的字段
ArcGIS 字段数据类型
ArcGIS 中支持的 DBMS 数据类型
ObjectID 字段的基础知识
修改字段属性
日期字段的基础知识
在 ArcGIS 中使用的查询表达式的 SQL 参考

字段的增删改

常用接口

  • IField、IField2
  • IFieldEdit、IFieldEdit2
  • ISchemaLock
  • IFields、IFields2
  • IFieldsEdit、IFieldsEdit2

添加字段

添加字段步骤

示例1:如何创建字段并添加到字段集中

        public IFields CreateFieldExample()
        {
            //1.新建IFields对象
            IFields pFields = new FieldsClass();
            //接口跳转到IFieldsEdit
            IFieldsEdit pFieldsEdit = (IFieldsEdit)pFields;
            //2.新建IField对象
            IField pField = new FieldClass();
            //接口跳转到IFieldEdit对象上进行编辑
            IFieldEdit2 pFieldEdit = (IFieldEdit2)pField;
            pFieldEdit.Name_2 = "FieldName";//Name属性只读,Name_2只写
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldEdit.Length_2 = 50;
            //3.将新建的IField对象添加到IFieldsEdit中
            pFieldsEdit.AddField(pField);

            return pFields;
        }
    }

示例2:将字段添加到已有的要素类中

        public void AddFieldToFeatureClass(IFeatureClass featureClass, IField field)

        {
            ISchemaLock schemaLock = (ISchemaLock)featureClass;//创建模式锁对象
            try
            {
                //修改为独占锁
                schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
                //判断字段是否存在,存在则返回,不存在则添加
                if (featureClass.FindField(field.Name) == -1)
                {
                    // 添加字段
                    featureClass.AddField(field);
                }
            }
            catch (Exception ex)
            {
                // 输出异常
                Console.WriteLine(ex.Message);
            }
            finally
            {
                // 修改为共享锁
                schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
            }
        }

获取创建要素类所需的最少字段

public IFields CreateFieldsCollectionForFeatureClass(ISpatialReference spatialReference)
        {
            //创建IFeatureClassDescription接口
            IFeatureClassDescription pFeaClassDesc = new FeatureClassDescriptionClass();
            IObjectClassDescription pObjClassDesc = (IObjectClassDescription)pFeaClassDesc;

            // 获取所需的字段集合
            IFields pFields = pObjClassDesc.RequiredFields;

            // 获取几何字段
            int iShapeFieldIndex = pFields.FindField(pFeaClassDesc.ShapeFieldName);
            IField pShapeField = pFields.get_Field(iShapeFieldIndex);

            // 获取几何定义
            IGeometryDef pGeometryDef = pShapeField.GeometryDef;
            IGeometryDefEdit pGeometryDefEdit = (IGeometryDefEdit)pGeometryDef;

            // 修改要素类的集合类型为线(默认为面)
            pGeometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPolyline;
            pGeometryDefEdit.HasM_2 = true;
            pGeometryDefEdit.GridCount_2 = 1;

            //设置格网大小为(0,0)
            pGeometryDefEdit.set_GridSize(0, 0);
            //设置坐标系
            pGeometryDefEdit.SpatialReference_2 = spatialReference;

            // 创建IFieldsEdit对象
            IFieldsEdit pFieldsEdit = (IFieldsEdit)pFields;

            // 创建自定义的字段
            IField incomeField = new FieldClass();
            IFieldEdit incomeFieldEdit = (IFieldEdit)incomeField;
            incomeFieldEdit.AliasName_2 = "Average income for 1999-2000";
            incomeFieldEdit.Editable_2 = true;//可编辑
            incomeFieldEdit.IsNullable_2 = false;//不允许为空
            incomeFieldEdit.Name_2 = "average_income";//字段名称
            incomeFieldEdit.Precision_2 = 2;//字段精度
            incomeFieldEdit.Scale_2 = 5;
            incomeFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;//字段类型
            //添加自定义字段
            pFieldsEdit.AddField(incomeField);

            return pFields;
        }

验证字段

        public IFields ValidateFieldsForWorkspace(IFields fields, IWorkspace workspace)
        {
            // 创建IFieldChecker对象.
            IFieldChecker pFieldChecker = new FieldCheckerClass();
            pFieldChecker.ValidateWorkspace = workspace;
            // 验证字段集
            IEnumFieldError enumFieldError = null;
            IFields validatedFields = null;
            pFieldChecker.Validate(fields, out enumFieldError, out validatedFields);
            // 显示字段错误
            IFieldError fieldError = null;
            enumFieldError.Reset();
            while ((fieldError = enumFieldError.Next()) != null)
            {
                IField errorField = fields.get_Field(fieldError.FieldIndex);
                Console.WriteLine("Field '{0}': Error '{1}'", errorField.Name, fieldError.FieldError);
            }
            //返回验证的字段
            return validatedFields;
        }

修改字段

修改字段有两种方法,一种是调用接口IFieldEdit2,另外一种是调用GP工具(ArcMap中位置:Data Management Tools\Fields\AlterField)。
建议:建议使用GP修改,成功率高、较稳定,使用接口只能修改成功部分属性。

        //更新字段的第一种方法,调用IFieldEdit2接口(属性后面带“_2”的代表只写,不带“_2”的代表只读)
        public void UpdateField(IField pInField)
        {
            IFieldEdit2 pFieldEdit = pInField as IFieldEdit2;
            pFieldEdit.Name_2 = "NewName";
            pFieldEdit.AliasName_2 = "NewAlias";
            pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
            pFieldEdit.Length_2 = pFieldEdit.Length + 50;
            pFieldEdit.IsNullable_2 = !pFieldEdit.IsNullable;
            //......
        }

        //更新字段的第二种方法,调用GP工具,代码略

删除字段

删除字段有两种方法,一种是调用接口IFieldsEdit,另外一种是调用GP工具,(ArcMap中位置:Data Management Tools\Fields\DeleteField)。

        //删除字段的第一种方法,调用IFieldsEdit接口
        public void DeleteField(IFields pInFields,IField pDeleteField)
        {
            IFieldsEdit pFieldsEdit = pInFields as IFieldsEdit;
            pFieldsEdit.DeleteAllFields();//删除全部字段
            pFieldsEdit.DeleteField(pDeleteField);//删除指定字段
        }

        //官方版示例,开始模式锁,然后再删除字段
        public void DeleteField(IObjectClass objectClass, String fieldName)
        {
            // Get the field to be deleted.
            int fieldIndex = objectClass.FindField(fieldName);
            IField field = objectClass.Fields.get_Field(fieldIndex);

            // Cast to the ISchemaLock interface.
            ISchemaLock schemaLock = (ISchemaLock)objectClass;
            try
            {
                // Get an exclusive schema lock on the object class. 
                schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);

                // Alter the class extension for the class.
                objectClass.DeleteField(field);
            }
            catch (Exception e)
            {
                // An error was raised; therefore, notify the user.
                Console.WriteLine(e.Message);
            }
            finally
            {
                // Since the Finally block is always called, the exclusive lock is demoted
                // to a shared lock after the field is deleted and after an error is raised.
                schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
            }
        }

        //删除字段的第二种方法,调用GP工具,代码略

字段批量赋值

字段批量赋值有三种方法:①遍历数据,然后用游标查询进行赋值 ②利用GP工具CalculateField进行批量赋值 ③利用IWorkspace的ExcuteSQL执行Update语句进行批量赋值。(具体代码略)
效率对比:③>②>①

字段的读取

遍历字段

        //遍历字段
        public void TraversalQuery(IFields pFields)
        {
            for (int i = 0; i < pFields.FieldCount; i++)
            {
                IField pField = pFields.get_Field(i);
                //......

            }
        }

        //获取字段的总数
        public int GetFieldsCount(IFields pFields)
        {
            IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
            return pFieldsEdit.FieldCount;
        }       

读取字段值列表

        public List<string> GetFieldUniqueValue(ITable pTable, string sFieldName, IQueryFilter pQueryFilter = null)
        {
            if (pTable == null || pTable.FindField(sFieldName) < 0)
            {
                return null;
            }
            List<string> valuesList = new List<string>();
            using (ComReleaser pComReleaser = new ComReleaser())
            {
                ICursor pCursor = pTable.Search(pQueryFilter, true);
                pComReleaser.ManageLifetime(pCursor);
                IDataStatistics pDataStats = new DataStatisticsClass();
                pComReleaser.ManageLifetime(pDataStats);
                pDataStats.Cursor = pCursor;
                pDataStats.Field = sFieldName;
                IEnumerator pEnumValues = pDataStats.UniqueValues;
                pComReleaser.ManageLifetime(pEnumValues);
                pEnumValues.Reset();
                while (pEnumValues.MoveNext())
                {
                    object objValue = pEnumValues.Current;
                    if (objValue == null || Convert.IsDBNull(objValue))
                    {
                        continue;
                    }
                    valuesList.Add(objValue.ToString());
                }
            }
            return valuesList;
        }

        public List<string> GetFieldUniqueValue(IFeatureWorkspace pFeaWs, string sTableName,
            string sFldName, string sWhere = "")
        {
            List<string> values = new List<string>();
            using (ComReleaser pComreleaser = new ComReleaser())
            {
                IQueryDef pQueryDef = pFeaWs.CreateQueryDef();
                pComreleaser.ManageLifetime(pQueryDef);
                pQueryDef.Tables = sTableName;
                pQueryDef.SubFields = "DISTINCT(" + sFldName + ")";
                if (sWhere != "")
                {
                    pQueryDef.WhereClause = sWhere;
                }
                ICursor pCursor = pQueryDef.Evaluate();

                IRow pRow = null;
                while ((pRow = pCursor.NextRow()) != null)
                {
                    string sValue = CommonAPI.ConvertToString(pRow.get_Value(0));
                    values.Add(sValue);
                }
                return values;
            }
        }

字段值汇总

参考链接

Blob字段的读写

        //读取blob字段到字符串中
        public  string ReadStringFromBlob(object objValue)
        {
            string sResault = "";
            IMemoryBlobStreamVariant pMemoryBlobStreamVariant = objValue as IMemoryBlobStreamVariant;
            if (pMemoryBlobStreamVariant != null)
            {
                pMemoryBlobStreamVariant.ExportToVariant(out objValue);
                sResault = Encoding.Default.GetString(objValue as byte[]);
            }
            return sResault;
        }

        //读取Blob字段中的二进制字节数组
        public  byte[] ReadBytesFromBlob(object objValue)
        {
            IMemoryBlobStreamVariant pMemoryBlobStreamVariant = objValue as IMemoryBlobStreamVariant;
            if (pMemoryBlobStreamVariant != null)
            {
                pMemoryBlobStreamVariant.ExportToVariant(out objValue);
            }
            byte[] bytes = objValue as byte[];
            return bytes;
        }

        //将字符串写入Blob流对象
        public  IMemoryBlobStream WriteStringToBlob(string sValue)
        {
            IMemoryBlobStream blobStream = new MemoryBlobStreamClass();
            if (!string.IsNullOrWhiteSpace(sValue))
            {
                object objValue = Encoding.Default.GetBytes(sValue);
                (blobStream as IMemoryBlobStreamVariant).ImportFromVariant(objValue);
            }
            return blobStream;
        }

        //将字节数组写入Blob流对象
        public  IMemoryBlobStream WriteBytesToBlob(byte[] bytes)
        {
            IMemoryBlobStream blobStream = new MemoryBlobStreamClass();
            (blobStream as IMemoryBlobStreamVariant).ImportFromVariant(bytes);
            return blobStream;
        }       

        //将Object对象写入到Blob字段中
        public  void SaveBlobValue(IRowBuffer rowBuffer, int iFieldIndex, object value)
        {
            if (value is IPersistStream)
            {
                IMemoryBlobStream pBlobStream = new MemoryBlobStreamClass();
                (value as IPersistStream).Save(pBlobStream, 0);
                rowBuffer.set_Value(iFieldIndex, pBlobStream);
            }
            else
            {
                IMemoryBlobStream pBlobStream = new MemoryBlobStreamClass();
                rowBuffer.set_Value(iFieldIndex, pBlobStream);
            }
        }       

字段的拷贝

        public IField CopyField(IField pInField)
        {
            IField pOutField = (pInField as ESRI.ArcGIS.esriSystem.IClone).Clone() as IField;
            return pOutField;
        }

字段的配置

字段与值域

关于值域部分的内容,回头会写一篇新的文章,敬请期待。

字段与子类型

关于子类型部分的内容,回头也会写一篇新的文章,敬请期待。

相关GP工具

这里写图片描述

转载自:https://blog.csdn.net/yh0503/article/details/79009150

You may also like...