近日碰到在执行feature.shape=geo的操作时会报geometry没有z值(the geometry has no z values)以及geometry的z值为空(the geometry has no null values)的错误,这通常是因为使用的数据源是用其它软件导出的,默认是有z值的,但是arcgis默认是没有z值的,以致产生了矛盾。然而网上找的许多解决方案并不完善,因此优化后解决方案如下:
确保创建的字段是有z值的
///获取参考几何信息
public static IGeometryDef GetGeometryDef(IFeatureClass featureClass)
{
var fieldName = featureClass.ShapeFieldName;
var index = featureClass.FindField(fieldName);
return featureClass.Fields.Field[index].GeometryDef;
}
///创建字段
public IFields CreateFields(esriGeometryType type,IGeometryDef geometryDef)
{
IFields fields = new FieldsClass();
var fieldsEdit = fields as IFieldsEdit;
#region objectid
IField field = new FieldClass();
var fieldEdit = field as IFieldEdit;
fieldEdit.Name_2 = "OBJECTID";
fieldEdit.Type_2 = esriFieldType.esriFieldTypeOID;
fieldEdit.IsNullable_2 = false;
fieldEdit.Required_2 = false;
fieldsEdit.AddField(field);
#endregion
#region Shape
IField field_shp = new FieldClass();
var fieldEdit_shp = field_shp as IFieldEdit;
IGeometryDef geoDef = new GeometryDefClass();
var geoDefEdit = (IGeometryDefEdit)geoDef;
geoDefEdit.GeometryType_2 = type;
geoDefEdit.GridCount_2 = geometryDef.GridCount;
geoDefEdit.HasM_2 = geometryDef.HasM;
//使图层具有Z值(无,则创建一个二维文件,不具备Z值)
geoDefEdit.HasZ_2 = geometryDef.HasZ;
geoDefEdit.SpatialReference_2 = geometryDef.SpatialReference;
fieldEdit_shp.Name_2 = "SHAPE";
fieldEdit_shp.Type_2 = esriFieldType.esriFieldTypeGeometry;
fieldEdit_shp.GeometryDef_2 = geoDef;
fieldEdit_shp.IsNullable_2 = true;
fieldEdit_shp.Required_2 = true;
fieldsEdit.AddField(field_shp);
#endregion
return fields;
}
给几何设置z值
/// <summary>
/// 给几何信息设置z值
/// </summary>
/// <param name="geo"></param>
/// <param name="geometryDef"></param>
public static void SetZ(IGeometryDef geometryDef,ref IGeometry geo)
{
if (geometryDef.HasZ)
{
IZAware zAware = geo as IZAware;
zAware.ZAware = true;
switch (geo.GeometryType)
{
case esriGeometryType.esriGeometryPoint:
IPoint point = geo as IPoint;
point.Z = 0;
geo = point;
break;
case esriGeometryType.esriGeometryMultipoint:
IPointCollection collection = geo as IPointCollection;
for(int i = 0; i < collection.PointCount; i++)
{
var p = collection.Point[i];
p.Z = 0;
collection.UpdatePoint(i, p);
}
geo = collection as IMultipoint;
break;
default:
IZ iz = geo as IZ;
if (iz != null)
iz.SetConstantZ(0);
break;
}
}
}