定义表中的字段
ArcGIS 字段数据类型
ArcGIS 中支持的 DBMS 数据类型
ObjectID 字段的基础知识
修改字段属性
日期字段的基础知识
在 ArcGIS 中使用的查询表达式的 SQL 参考
示例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字段到字符串中
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;
}
关于值域部分的内容,回头会写一篇新的文章,敬请期待。
关于子类型部分的内容,回头也会写一篇新的文章,敬请期待。