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
{
}