ArcEngine 欄位小結
阿新 • • 發佈:2018-12-18
欄位的基礎知識
定義表中的欄位
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;
}
欄位的配置
欄位與值域
關於值域部分的內容,回頭會寫一篇新的文章,敬請期待。
欄位與子型別
關於子型別部分的內容,回頭也會寫一篇新的文章,敬請期待。