Loading

ArcEngine 字段帮助类

public class FieldHelper
{

    private static readonly Dictionary<string, esriFieldType> FieldTypes = new Dictionary<string, esriFieldType>
    {
        {"esriFieldTypeSmallInteger", esriFieldType.esriFieldTypeInteger},
        {"esriFieldTypeInteger", esriFieldType.esriFieldTypeInteger},
        {"esriFieldTypeSingle", esriFieldType.esriFieldTypeSingle},
        {"esriFieldTypeDouble",esriFieldType.esriFieldTypeDouble},
        {"esriFieldTypeString", esriFieldType.esriFieldTypeString},
        {"esriFieldTypeDate",esriFieldType.esriFieldTypeDate},
        {"esriFieldTypeOID", esriFieldType.esriFieldTypeOID},
        {"esriFieldTypeGeometry", esriFieldType.esriFieldTypeGeometry},
        {"esriFieldTypeBlob",esriFieldType.esriFieldTypeBlob},
        {"esriFieldTypeRaster", esriFieldType.esriFieldTypeRaster},
        {"esriFieldTypeGUID", esriFieldType.esriFieldTypeGUID},
        {"esriFieldTypeGlobalID", esriFieldType.esriFieldTypeGlobalID},
        {"esriFieldTypeXML", esriFieldType.esriFieldTypeXML}

    };


    /// <summary>
    /// 根据ESRI字段类型获取.Net类型
    /// </summary>
    /// <param name="fieldType">ESRI字段类型</param>
    /// <returns>.Net类型</returns>
    public static Type GetTypeFromEsriFieldType(esriFieldType fieldType)
    {
        Type type = null;

        switch (fieldType)
        {
            case esriFieldType.esriFieldTypeString:
                type = Type.GetType("System.String");
                break;
            case esriFieldType.esriFieldTypeSingle:
                type = Type.GetType("System.Single");
                break;
            case esriFieldType.esriFieldTypeSmallInteger:
                type = Type.GetType("System.Int16");
                break;
            case esriFieldType.esriFieldTypeDate:
                type = Type.GetType("System.DateTime");
                break;
            case esriFieldType.esriFieldTypeInteger:
            case esriFieldType.esriFieldTypeOID:
                type = Type.GetType("System.Int32");
                break;
            case esriFieldType.esriFieldTypeDouble:
                type = Type.GetType("System.Double");
                break;
            default:
                break;
        }

        return type;
    }

    /// <summary>
    /// 判断字段可见性
    /// </summary>
    /// <param name="field"></param>
    /// <param name="layerFields"></param>
    /// <returns></returns>
    public static bool VisibleField(IField field, ILayerFields layerFields)
    {
        if (layerFields == null) return true;
        int index = layerFields.FindField(field.Name);
        if (index < 0) return true;
        IFieldInfo fieldInfo = layerFields.FieldInfo[index];
        return fieldInfo.Visible;
    }

    /// <summary>
    /// 设置图层字段可见性
    /// </summary>
    /// <param name="layerFields"></param>
    /// <param name="hideFields"></param>
    public static void SetVisibleField(ILayerFields layerFields, string[] hideFields)
    {
        if (layerFields == null || hideFields == null) return;
        foreach (string field in hideFields)
        {
            int index = layerFields.FindField(field);
            if (index >= 0)
                layerFields.FieldInfo[index].Visible = false;
        }
    }

    /// <summary>
    /// 获取图层不可见的字段
    /// </summary>
    /// <param name="layerFields"></param>
    /// <returns></returns>
    public static IEnumerable<string> GetVisibleField(ILayerFields layerFields)
    {
        if (layerFields == null) return null;
        List<string> listHideFields = new List<string>();
        for (int i = 0; i < layerFields.FieldCount; i++)
        {
            IFieldInfo fieldInfo = layerFields.FieldInfo[i];
            IField field = layerFields.Field[i];
            if (!fieldInfo.Visible)
                listHideFields.Add(field.Name);
        }
        return listHideFields.Count == 0 ? null : listHideFields;

    }

    /// <summary>
    /// 获得图形shape字段
    /// </summary>
    /// <param name="pFields">字段集合</param>
    /// <returns>图形shape字段</returns>
    public static IField GetShapeField(IFields pFields)
    {
        if (pFields == null) return null;
        for (int i = 0; i < pFields.FieldCount; i++)
        {
            if (pFields.Field[i].Type == esriFieldType.esriFieldTypeGeometry)
            {
                return pFields.Field[i];
            }
        }
        return null;
    }

    /// <summary>
    /// 获取创建要素类所需的最少字段
    /// </summary>
    /// <param name="type"></param>
    /// <param name="spatialReference"></param>
    /// <param name="hasM"></param>
    /// <returns></returns>
    public static IFields CreatedDefaultFields(esriGeometryType type, ISpatialReference spatialReference, bool hasM = false)
    {
        //创建IFeatureClassDescription接口
        IFeatureClassDescription pFeaClassDesc = new FeatureClassDescriptionClass();
        IObjectClassDescription pObjClassDesc = (IObjectClassDescription)pFeaClassDesc;

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

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

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

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

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

        return pFields;
    }

    /// <summary>
    /// 添加字段
    /// </summary>
    /// <param name="featureClass"></param>
    /// <param name="field"></param>
    public static void AddField(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);
        }
    }

    /// <summary>
    /// 添加字段
    /// </summary>
    /// <param name="featureClass"></param>
    /// <param name="field"></param>
    public static void AddImField(IFeatureClass featureClass, IField field)
    {

        try
        {
            //判断字段是否存在,存在则返回,不存在则添加
            if (featureClass.FindField(field.Name) == -1)
            {
                // 添加字段
                featureClass.AddField(field);
            }
        }
        catch (Exception)
        {

        }

    }


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

    /// <summary>
    /// 删除字段
    /// </summary>
    /// <param name="pInFields"></param>
    /// <param name="pDeleteField"></param>
    public static void DeleteField(IFields pInFields, IField pDeleteField)
    {
        IFieldsEdit pFieldsEdit = pInFields as IFieldsEdit;
        if (pFieldsEdit == null) return;
        pFieldsEdit.DeleteAllFields(); //删除全部字段
        pFieldsEdit.DeleteField(pDeleteField); //删除指定字段
    }

    /// <summary>
    /// 删除字段
    /// </summary>
    /// <param name="objectClass"></param>
    /// <param name="fieldName"></param>
    public static void DeleteField(IObjectClass objectClass, string fieldName)
    {
        // Get the field to be deleted.
        int fieldIndex = objectClass.FindField(fieldName);
        IField field = objectClass.Fields.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);
        }
    }

    /// <summary>
    /// 拷贝字段
    /// </summary>
    /// <param name="pInField"></param>
    /// <returns></returns>
    public static IField CopyField(IField pInField)
    {
        IField pOutField = (pInField as IClone).Clone() as IField;
        return pOutField;
    }

    /// <summary>
    /// 读取blob字段到字符串中
    /// </summary>
    /// <param name="objValue"></param>
    /// <returns></returns>
    public string ReadStringFromBlob(object objValue)
    {
        string result = string.Empty;
        IMemoryBlobStreamVariant pMemoryBlobStreamVariant = objValue as IMemoryBlobStreamVariant;
        if (pMemoryBlobStreamVariant == null) return result;
        pMemoryBlobStreamVariant.ExportToVariant(out objValue);
        result = Encoding.Default.GetString(objValue as byte[]);
        return result;
    }

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

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

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

    /// <summary>
    /// 将Object对象写入到Blob字段中
    /// </summary>
    /// <param name="rowBuffer"></param>
    /// <param name="iFieldIndex"></param>
    /// <param name="value"></param>
    public static 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);
        }
    }
    /// <summary>
    /// 获取字段的总数
    /// </summary>
    /// <param name="pFields"></param>
    /// <returns></returns>
    public static int GetFieldsCount(IFields pFields)
    {
        IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
        return pFieldsEdit.FieldCount;
    }

    public static IGeometryDef GetGeometryDef(IFeatureClass featureClass)
    {
        // First, determine the name of the shape field.
        String shapeFieldName = featureClass.ShapeFieldName;

        // Get the feature class fields collection and find the shape field index.
        IFields fields = featureClass.Fields;
        int geometryIndex = fields.FindField(shapeFieldName);

        // Use the index value to get the field.
        IField field = fields.Field[geometryIndex];

        // Get the GeometryDef from the field and return it.
        IGeometryDef geometryDef = field.GeometryDef;
        return geometryDef;
    }

    public static IField CreateStringField(string name, string aliasName, string fieldType, int length)
    {
        return CreateField(name, aliasName, fieldType, length);
    }
    public static IField CreateIntegerField(string name, string aliasName, string fieldType, int precision)
    {
        return CreateField(name, aliasName, fieldType, -1, precision);
    }
    public static IField CreateFloatField(string name, string aliasName, string fieldType, int precision, int scale)
    {
        return CreateField(name, aliasName, fieldType, -1, precision, scale);
    }

    public static IField CreateField(string name, string aliasName, string fieldType, int length = -1, int precision = -1, int scale = -1, object defaultValue = null, bool isNullable = true)
    {
        IField pField = new FieldClass();
        IFieldEdit pFieldEdit = pField as IFieldEdit;
        pFieldEdit.Name_2 = name;
        pFieldEdit.AliasName_2 = aliasName;
        esriFieldType esriFieldType = GetGeometryType(fieldType);
        switch (esriFieldType)
        {
            case esriFieldType.esriFieldTypeSmallInteger:
            case esriFieldType.esriFieldTypeInteger:
                pFieldEdit.Precision_2 = precision;
                break;
            case esriFieldType.esriFieldTypeSingle:
            case esriFieldType.esriFieldTypeDouble:
                pFieldEdit.Precision_2 = precision;
                pFieldEdit.Scale_2 = scale;
                break;
            case esriFieldType.esriFieldTypeString:
                pFieldEdit.Length_2 = length;
                break;
        }
        pFieldEdit.Type_2 = esriFieldType;
        if (defaultValue != null)
            pFieldEdit.DefaultValue_2 = defaultValue;
        pFieldEdit.IsNullable_2 = isNullable;
        return pField;
    }


    public static IFields CreateFields(IEnumerable<FieldInfo> fieldInfos)
    {
        IFields pFields = new FieldsClass();
        IFieldsEdit pFieldsEdit = pFields as IFieldsEdit;
        foreach (FieldInfo fieldInfo in fieldInfos)
            pFieldsEdit.AddField(CreateField(fieldInfo));
        return pFields;
    }
    public static IField CreateField(FieldInfo fieldInfo)
    {

        IField pField = new FieldClass();
        IFieldEdit pFieldEdit = pField as IFieldEdit;
        pFieldEdit.Name_2 = fieldInfo.Name;
        pFieldEdit.AliasName_2 = fieldInfo.AliasName;
        esriFieldType esriFieldType = GetGeometryType(fieldInfo.Type);
        pFieldEdit.Type_2 = esriFieldType;
        switch (esriFieldType)
        {
            case esriFieldType.esriFieldTypeSmallInteger:
            case esriFieldType.esriFieldTypeInteger:
                pFieldEdit.Precision_2 = fieldInfo.Precision != null ? fieldInfo.Precision.Value : 9;
                break;
            case esriFieldType.esriFieldTypeSingle:
            case esriFieldType.esriFieldTypeDouble:
                pFieldEdit.Precision_2 = fieldInfo.Precision != null ? fieldInfo.Precision.Value : 2;
                pFieldEdit.Scale_2 = fieldInfo.Scale != null ? fieldInfo.Scale.Value : 2;
                break;
            case esriFieldType.esriFieldTypeString:
                pFieldEdit.Length_2 = fieldInfo.Length == 0 ? 255 : fieldInfo.Length;
                break;
        }
        if (fieldInfo.DefaultValue != null)
            pFieldEdit.DefaultValue_2 = fieldInfo.DefaultValue;
        pFieldEdit.IsNullable_2 = fieldInfo.IsNullable != null ? fieldInfo.IsNullable.Value : true;
        return pField;
    }

    public static esriFieldType GetGeometryType(string type)
    {
        return FieldTypes.ContainsKey(type)
            ? FieldTypes[type]
            : esriFieldType.esriFieldTypeString;
    }

}

/// <summary>
/// 字段信息
/// </summary>
public class FieldInfo
{
    /// <summary>
    /// 字段名称
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// 字段别名
    /// </summary>
    public string AliasName { get; set; }
    /// <summary>
    /// 字段的类型
    /// </summary>
    public string Type { get; set; }
    /// <summary>
    /// 字段长度
    /// </summary>
    public int Length { get; set; }

    /// <summary>
    /// 字段的数值精度
    /// </summary>
    public int? Precision { get; set; }

    /// <summary>
    /// 字段的小数点位数
    /// </summary>
    public int? Scale { get; set; }

    /// <summary>
    ///  是否为空值
    /// </summary>
    public bool? IsNullable { get; set; }

    /// <summary>
    /// 默认值
    /// </summary>
    public object DefaultValue { get; set; }
}

public class FieldInfoEx : FieldInfo
{

}
posted @ 2021-01-19 09:35  F(x)_King  阅读(169)  评论(0编辑  收藏  举报