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; }
字段的配置
字段与值域
关于值域部分的内容,回头会写一篇新的文章,敬请期待。
字段与子类型
关于子类型部分的内容,回头也会写一篇新的文章,敬请期待。