一、获取字段信息
/// <summary>
/// 获取字段信息
/// </summary>
/// <param name="pField"></param>
public static void GetMsgFromField(IField pField)
{
var name = pField.Name; //字段名 OBJECTID;SHAPE;BSM;HDMC;BZ;TBMJ
bool req = pField.Required; //是否为必要字段 true;true;false;false;false;false
bool eid = pField.Editable; //是否可编辑 false;true;true;true;true;true
var aName = pField.AliasName; //字段别名 OBJECTID;SHAPE;标识码;HDMC;备注;图斑面积
bool nullable = pField.IsNullable; //可包含空值 false;true;true;true;true;true
//bool valid = pField.CheckValue(1111); //检查Value在字段中是否有效,感觉没啥用处啊
esriFieldType fieldType = pField.Type; //字段类型 esriFieldTypeOID;esriFieldTypeGeometry;esriFieldTypeString;esriFieldTypeString;esriFieldTypeString;esriFieldTypeDouble
var varType = pField.VarType; //字段的变量类型 3;13;8;8;8;5
int len = pField.Length; //字段长度 4;0;18;100;2147483647;8
int preci = pField.Precision; //精度 0;0;0;0;0;0
var dValue = pField.DefaultValue; //默认值
int sca=pField.Scale;//字段范围 0;0;0;0;0;0
bool domFixed = pField.DomainFixed; //是否为混合域 true;false;false;false;false;false
IDomain pDom = pField.Domain; //字段的默认域 null;null;null;有;null;有
if (pDom != null)
{
string domName = pDom.Name; //默认值域名 DM;JSR
string domDes = pDom.Description; //默认值域描述 代码;净收入
esriFieldType pFieldType = pDom.FieldType; //字段类型 esriFieldTypeString;esriFieldTypeDouble
esriDomainType pDomainType = pDom.Type; //域类型 esriDTCodedValue;esriDTRange
int domId = pDom.DomainID; //1051;1052
bool domVail= pDom.MemberOf("Q"); //检查Value在字段中是否有效 true
string domOwner = pDom.Owner; //所属者 "";""
esriMergePolicyType pPolicyType = pDom.MergePolicy; //合并策略 esriMPTDefaultValue;esriMPTSumValues
esriSplitPolicyType pSplitPolicy = pDom.SplitPolicy; //分割策略 esriSPTDefaultValue;esriSPTGeometryRatio
}
IGeometryDef pGeometryDef = pField.GeometryDef; //几何定义 null;有;null
if (pGeometryDef != null)
{
esriGeometryType pGeometryType = pGeometryDef.GeometryType; //几何类型 ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon
int numPoints = pGeometryDef.AvgNumPoints; //每个要素的估计平均点数 0
int gridCount = pGeometryDef.GridCount; //空间索引网格的数目 1
double gridSize = pGeometryDef.get_GridSize(0); //空间索引网格的大小 350
bool hasZ = pGeometryDef.HasZ; //是否具有Z值 false
bool hasM = pGeometryDef.HasM; //是否具有M值 false
ISpatialReference pSpatialReference = pGeometryDef.SpatialReference; //空间参考 ISpatialReference继承ISpatialReferenceInfo接口
}
}
二、创建字段
1、由已有要素类创建
1)、普通方式
/// <summary>
/// 从源数据集获取字段集合
/// </summary>
/// <param name="fClass">源数据集</param>
/// <returns></returns>
public static IFields GetFieldsBySource(IFeatureClass fClass)
{
IFields flds = new FieldsClass();
IFieldsEdit fldsEdit = flds as IFieldsEdit;
for (int i = 0; i < fClass.Fields.FieldCount; i++)
{
if (!fClass.Fields.Field[i].Required) //过滤必要字段 Geometry字段为必要字段但可编辑
fldsEdit.AddField(fClass.Fields.Field[i]);
}
//修改IField字段
IField pGeometryField = fClass.Fields.get_Field(fClass.FindField(fClass.ShapeFieldName));
IGeometryDef pGeomDef = new GeometryDefClass();
IGeometryDefEdit pGeomDefEdit = pGeomDef as IGeometryDefEdit;
pGeomDefEdit.GeometryType_2 = pGeometryField.GeometryDef.GeometryType;
pGeomDefEdit.SpatialReference_2 = pGeometryField.GeometryDef.SpatialReference;
IFieldEdit pGeometryFieldEdit = pGeometryField as IFieldEdit;
pGeometryFieldEdit.GeometryDef_2 = pGeomDefEdit;
fldsEdit.AddField(pGeometryField);
return flds;
}
2)、IObjectCopy接口
/// <summary>
/// IObjectCopy从源数据集拷贝字段
/// </summary>
/// <param name="featureClass"></param>
/// <returns></returns>
public IFields GetFieldsFromFClass(IFeatureClass featureClass)
{
IObjectCopy pObjectCopy = new ObjectCopyClass();
IFields pCopiedFields = pObjectCopy.Copy(featureClass.Fields) as IFields;
// Find the shape field.若不设置,导入数据的时候可能会报错
//int shapeFieldIndex = featureClass.FindField(featureClass.ShapeFieldName);
//IField shapeField = pCopiedFields.get_Field(shapeFieldIndex);
var hasZ = shapeField.GeometryDef.HasZ;//是否含有Z值
设置几何字段属性
//IGeometryDef pGeomDef = new GeometryDefClass();
//IGeometryDefEdit pGeomDefEdit = pGeomDef as IGeometryDefEdit;
//pGeomDefEdit.GeometryType_2 = shapeField.GeometryDef.GeometryType;
//pGeomDefEdit.SpatialReference_2 = shapeField.GeometryDef.SpatialReference;
//IFieldEdit pGeometryFieldEdit = shapeField as IFieldEdit;
//pGeometryFieldEdit.GeometryDef_2 = pGeomDefEdit;
return pCopiedFields;
}
2、自定义创建字段
/// <summary>
/// 自定义创建字段
/// </summary>
/// <returns></returns>
public IFields CreateIFields()
{
// 创建字段集合.
IFields fields = new FieldsClass();
IFieldsEdit fieldsEdit = (IFieldsEdit)fields;
// 在字段集合中添加一个Object ID. 必要字段.
IField oidField = new FieldClass();
IFieldEdit oidFieldEdit = (IFieldEdit)oidField;
oidFieldEdit.Name_2 = "OID";
oidFieldEdit.AliasName_2 = "索引";
oidFieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
fieldsEdit.AddField(oidField);
//给要素类创建几何定义和空间参考
IGeometryDef geometryDef = new GeometryDefClass();
IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
ISpatialReference spatialReference = spatialReferenceFactory.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_NAD1983UTM_20N);
ISpatialReferenceResolution spatialReferenceResolution = (ISpatialReferenceResolution)spatialReference;//提供对控制空间引用分辨率的成员的访问。
spatialReferenceResolution.ConstructFromHorizon();//定义此空间参照的xy分辨率和域范围(基于其地平线的范围)。低精度SRS当前单位的最小分辨率为1/10毫米。
ISpatialReferenceTolerance spatialReferenceTolerance = (ISpatialReferenceTolerance)spatialReference;//访问空间信息和M偏差
spatialReferenceTolerance.SetDefaultXYTolerance();//设置用于控制X和Y尺寸中的点合并的默认簇公差(相当于当前空间参考单位中的1 mm)。
geometryDefEdit.SpatialReference_2 = spatialReference;
//添加几何字段.附加几何定义
IField geometryField = new FieldClass();
IFieldEdit geometryFieldEdit = (IFieldEdit)geometryField;
geometryFieldEdit.Name_2 = "Shape";
geometryFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
geometryFieldEdit.GeometryDef_2 = geometryDef;
fieldsEdit.AddField(geometryField);
// Create a text field called "Name" for the fields collection.
IField nameField = new FieldClass();
IFieldEdit nameFieldEdit = (IFieldEdit)nameField;
nameFieldEdit.Name_2 = "Name";
nameFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
nameFieldEdit.Length_2 = 20;
fieldsEdit.AddField(nameField);
return fields;
}
3、由FeatureClassDescriptionClass创建
/// <summary>
/// 使用描述对象创建要素类和修改默认的几何定义(定义空间参考和几何类型)
/// </summary>
/// <param name="spatialReference">空间参考</param>
/// <returns></returns>
public IFields CreateIFieldsByDescription(ISpatialReference spatialReference)
{
// 初始化描述对象获得必要字段
IFeatureClassDescription fcDescription = new FeatureClassDescriptionClass();
IObjectClassDescription ocDescription = (IObjectClassDescription)fcDescription;
IFields fields = ocDescription.RequiredFields;
IFieldsEdit fieldsEdit = (IFieldsEdit)fields;
//在必要字段中找到“shape”字段并修改它的几何定义(修改为点和设置空间参考)
int shapeFieldIndex = fields.FindField(fcDescription.ShapeFieldName);
IField field = fields.get_Field(shapeFieldIndex);
IGeometryDef geometryDef = field.GeometryDef;
IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
geometryDefEdit.GeometryType_2 = esriGeometryType.esriGeometryPoint;
geometryDefEdit.SpatialReference_2 = spatialReference;
// 添加一个 "Name" 字段.
IField nameField = new FieldClass();
IFieldEdit fieldEdit = (IFieldEdit)nameField;
fieldEdit.Name_2 = "Name";
fieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
fieldsEdit.AddField(nameField);
return fields;
}
三、验证字段
/// <summary>
/// 验证字段
/// </summary>
/// <param name="fields">字段集合</param>
/// <param name="sourceWk">源工作空间</param>
/// <param name="targetWk">目标工作空间</param>
/// <param name="errlis">返回错误</param>
/// <returns></returns>
public static IFields ValidateFields(IFields fields, IWorkspace sourceWk, IWorkspace targetWk, out List<string> errlis)
{
// Create the objects and references necessary for field validation.
IFieldChecker fieldChecker = new FieldCheckerClass();
IFields sourceFields = fields;
IFields targetFields = null;
IEnumFieldError enumFieldError = null;
// Set the required properties for the IFieldChecker interface.
fieldChecker.InputWorkspace = sourceWk;
fieldChecker.ValidateWorkspace = targetWk;
// Validate the fields and check for errors.
fieldChecker.Validate(sourceFields, out enumFieldError, out targetFields);
errlis = new List<string>();
if (enumFieldError != null)
{
enumFieldError.Reset();
IFieldError fiderr = null;
while ((fiderr = enumFieldError.Next()) != null)
{
errlis.Add($"错误类型【{fiderr.FieldError}】,字段名【{fields.Field[fiderr.FieldIndex].Name}】别名【{fields.Field[fiderr.FieldIndex].AliasName}】");
}
}
return targetFields;
}