1. 程式人生 > >ArcEngine 欄位小結

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工具

這裡寫圖片描述