创建一个要素类是很简单的,只需要获取一枚IFeatureWorkspace或者一个IFeatureDataset,然后调用其CreateFeatureClass()即可。
这个CreateFeatureClass()方法定义如下:
public IFeatureClass CreateFeatureClass (
string Name,
IFields Fields,
UID CLSID,
UID EXTCLSID,
esriFeatureType FeatureType,
string ShapeFieldName,
string ConfigKeyword
);
第二个参数很关键,叫字段集合,有很多开发者报错也是这个。
有关这个参数怎么写的问题,网上代码相当多了。
我们知道在ArcGIS中创建要素类的时候,会有两个必须存在的系统字段:OBJECTID、SHAPE;
在AO/AE编程中,必须自己创建这两个字段(字段名可以自己定义,但是相关的属性必须设置好,此处为了好看将全大写的SHAPE改为Shape),至少创建Shape字段。
问题来了,我们在ArcGIS中创建要素类的时候,是可以不选空间参考的:
1. 在IFeatureWorkspace中CreateFeatureClass()不允许空坐标系
在AO/AE中,创建数据库中独立的要素类,而不是在要素数据集中的要素类则不行,必须对IGeometryDefEdit.SpatialReference进行赋值:
/// <summary>
/// 创建Shape字段的代码,以及为Shape字段添加几何定义
/// </summary> // 创建字段所需的几何定义
IGeometryDef geometryDef = new GeometryDefClass();
IGeometryDefEdit geometryDefEdit = geometryDef as IGeometryDefEdit;
geometryDefEdit.GeometryType_2 = esrigeomtryType;
geometryDefEdit.HasZ_2 = true;
geometryDefEdit.SpatialReference_2 = // 必须在此设置参考,不能为null,也不能为new UnknownCoordinateSystem();
// 创建字段
IField geometryField = new FieldClass();
IFieldEdit geometryFieldEdit = (IFieldEdit)geometryField;
geometryFieldEdit.Name_2 = "Shape";
geometryFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
// 赋予几何定义
geometryFieldEdit.GeometryDef_2 = geometryDef;
否则创建要素类就会报错,VS调试模式中,报错信息提示:缺少空间参考。
这已经被我测试了N次,以下为证据:
1.1 使用ArcCatalog中导出的Unknown.prj文件创建未知坐标系
使用Unknown.prj文件创建坐标系,判断其是否为IUnknownCoordinateSystem,结果返回true。
1.2 地图的参考系可以为空,但是要素类的参考系不能为空
我写了这么一段代码:
其中,nowMap是IMap类型的变量,代表了一个数据框(地图)。
下面,打开ArcMap,不加载任何数据的情况下,查看坐标系统:
点击测试按钮反馈:
提示空指针,证明了不添加数据时,数据框的坐标系就是null,而不是IUnknownCoordinateSystem;
紧接着,添加一个点要素类进数据库,点要素没有定义坐标系,点击按钮反馈:
此时,nowMap变量的坐标系就变成了IUnknownCoordinateSystem。
2. 在IFeatureDataset中CreateFeatureClass()
若要素数据集设置的是未知坐标系:
则可以不对IGeometryDefEdit.SpatialReference进行赋值,而且创建的要素的坐标系一定是要素数据集的IUnknownCoordinateSystem,且不会报错。
相关代码(在ArcGIS默认数据库的Test数据集中创建名为TestFC要素类):
结果:
(因为在要素数据集下,所以要素类的坐标系是不能被更改的)
3. UnknownCoordinateSystem类的定义
我找到了这个类:UnknownCoordinateSystem
实现了很多接口,包括ISpatialReference和IUnknownCoordinateSystem,这为编程判断类型提供了帮助(类型转换的as和is)