ArcGis 创建Annotation注记要素类、添加注记要素 并加载到Activeview AO C#
AO中一般有两种方式存储图面注记元素,一种使用TextElement,它是文档级的元素,编辑后要通过文档(mxd)保存;另一种是使用Annotation要素类,它是一个独立的要素类(featureclass),需要存储到地理数据库中。使用Annotation featureclass 的方式更灵活、更强大,至于如何灵活,如何强大,待你用到便自知。
1、创建一个标准的Annotation要素类(StandardAnnotationClass)
1 public AnnotationMark(IFeatureClass outPolygonFc,string mdbPath,int referenceScale) 2 { 3 string annotationName = "Annotation"; 4 IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactoryClass(); 5 IFeatureWorkspace featureWorkspace = workspaceFactory.OpenFromFile(mdbPath, 0) as IFeatureWorkspace; 6 IGeoDataset geoDataset = outPolygonFc as IGeoDataset; 7 ISpatialReference spatialReference = geoDataset.SpatialReference; 8 Utils.UserWorkspace.FeatureWorkspace.TryDeleteFeatureClass(annotationName, featureWorkspace); 9 featureClass = Utils.UserWorkspace.FeatureWorkspace.CreateStandardAnnotationClass(featureWorkspace, null,annotationName, spatialReference, referenceScale, esriUnits.esriMeters, null); 10 }
下面是一个摘自Esri官网的代码段,可以使用它创建StandardAnnotationClass。
值得注意的是:
featureDataset根据数据库是否有数据集(dataset)而定,可以是null;
referenceScale是注记的参考比例,注记元素会以此为基准,放大或缩小,一般建议设置为出图比例尺,这样所设置的字号即出图字号。
configKeyword=""
1 public static IFeatureClass CreateStandardAnnotationClass(IFeatureWorkspace featureWorkspace, IFeatureDataset featureDataset, String className, 2 ISpatialReference spatialReference, int referenceScale, esriUnits referenceScaleUnits, String configKeyword) 3 { 4 // Create an annotation class and provide it with a name. 5 ILabelEngineLayerProperties labelEngineLayerProperties = new 6 LabelEngineLayerPropertiesClass(); 7 IAnnotateLayerProperties annotateLayerProperties = (IAnnotateLayerProperties) 8 labelEngineLayerProperties; 9 annotateLayerProperties.Class = "Annotation"; 10 11 // Get the symbol from the annotation class. Make any changes to its properties 12 // here. 13 ITextSymbol annotationTextSymbol = labelEngineLayerProperties.Symbol; 14 ISymbol annotationSymbol = (ISymbol)annotationTextSymbol; 15 16 // Create a symbol collection and add the default symbol from the 17 // annotation class to the collection. Assign the resulting symbol ID 18 // to the annotation class. 19 ISymbolCollection symbolCollection = new SymbolCollectionClass(); 20 ISymbolCollection2 symbolCollection2 = (ISymbolCollection2)symbolCollection; 21 ISymbolIdentifier2 symbolIdentifier2 = null; 22 symbolCollection2.AddSymbol(annotationSymbol, "Annotation", out 23 symbolIdentifier2); 24 labelEngineLayerProperties.SymbolID = symbolIdentifier2.ID; 25 26 // Add the annotation class to a collection. 27 IAnnotateLayerPropertiesCollection annotateLayerPropsCollection = new 28 AnnotateLayerPropertiesCollectionClass(); 29 annotateLayerPropsCollection.Add(annotateLayerProperties); 30 31 // Create a graphics layer scale object. 32 IGraphicsLayerScale graphicsLayerScale = new GraphicsLayerScaleClass(); 33 graphicsLayerScale.ReferenceScale = referenceScale; 34 graphicsLayerScale.Units = referenceScaleUnits; 35 36 // Create the overposter properties for the standard label engine. 37 IOverposterProperties overposterProperties = new BasicOverposterPropertiesClass(); 38 39 // Instantiate a class description object. 40 IObjectClassDescription ocDescription = new 41 AnnotationFeatureClassDescriptionClass(); 42 IFeatureClassDescription fcDescription = (IFeatureClassDescription)ocDescription; 43 44 // Get the shape field from the class description's required fields. 45 IFields requiredFields = ocDescription.RequiredFields; 46 int shapeFieldIndex = requiredFields.FindField(fcDescription.ShapeFieldName); 47 IField shapeField = requiredFields.get_Field(shapeFieldIndex); 48 IGeometryDef geometryDef = shapeField.GeometryDef; 49 IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef; 50 geometryDefEdit.SpatialReference_2 = spatialReference; 51 52 // Create the annotation layer factory. 53 IAnnotationLayerFactory annotationLayerFactory = new FDOGraphicsLayerFactoryClass(); 54 55 // Create the annotation feature class and an annotation layer for it. 56 IAnnotationLayer annotationLayer = annotationLayerFactory.CreateAnnotationLayer 57 (featureWorkspace, featureDataset, className, geometryDef, null, 58 annotateLayerPropsCollection, graphicsLayerScale, symbolCollection, false, 59 false, false, true, overposterProperties, configKeyword); 60 61 // Get the feature class from the feature layer. 62 IFeatureLayer featureLayer = (IFeatureLayer)annotationLayer; 63 IFeatureClass featureClass = featureLayer.FeatureClass; 64 65 return featureClass; 66 }
2、创建Annotation要素(Annotation feature)
上面开始在AnnotationMark类的构造函数中创建了Annotation要素类featureClass,下面是创建Annotation 要素 feature的代码。
博主竟没有在墙内网络上找到相关的实现方案,只得爬墙去攒了这片代码,它主要是使用了ISymbolCollectionElement接口设置了Feature的各种属性。此外,网络上还有使用IFormattedTextSymbol
接口的方案,博主并未测试,有需要可以戳下面链接:
Why do these annotations appear stacked/overlapping?(再羡国外论坛生态)
值得注意的是:
IGeometry pointGeometry 这个几何对象应该是一个IPoint;
esriTextHorizontalAlignment 与 esriTextVerticalAlignment指示这个point在Annotation元素(一个面Polygon)的哪个位置,借此确定放置位置。
ISymbolCollectionElement或者IFormattedTextSymbol
还有更多的属性可以设置(本文不做补充),这些属性便是该要素记录各字段的值。
1 public void CreateAnnotationFeature(IGeometry pointGeometry,string text,string fontName,double fontSize,esriTextHorizontalAlignment horizontalAlignment, 2 esriTextVerticalAlignment verticalAlignment) 3 { 4 IFeature feature = featureClass.CreateFeature(); 5 6 ISymbolCollectionElement symbolCollectionElement = new TextElementClass(); 7 symbolCollectionElement.FontName = fontName; 8 symbolCollectionElement.Size = fontSize; 9 symbolCollectionElement.Text = text; 10 symbolCollectionElement.HorizontalAlignment = horizontalAlignment; 11 symbolCollectionElement.VerticalAlignment = verticalAlignment; 12 symbolCollectionElement.Geometry = pointGeometry; 13 14 IElement element = symbolCollectionElement as IElement; 15 IAnnotationFeature2 annotationFeature2 = feature as IAnnotationFeature2; 16 annotationFeature2.Annotation =element; 17 annotationFeature2.Status = esriAnnotationStatus.esriAnnoStatusPlaced; 18 feature.Store(); 19 }
3、要素类添加为图层
不啰嗦,上代码:
1 IWorkspaceFactory workspaceFactory = new AccessWorkspaceFactoryClass(); 2 IFeatureWorkspace featureWorkspace = workspaceFactory.OpenFromFile(mdbPath, 0) as IFeatureWorkspace; 3 IAnnotationLayerFactory annotationLayerFactory = new FDOGraphicsLayerFactoryClass(); 4 IAnnotationLayer annotationLayer = annotationLayerFactory.OpenAnnotationLayer(featureWorkspace, null, "Annotation"); 5 ILayer layer_Annotation = annotationLayer as ILayer; 6 layer_Annotation.Name = tfh + "_Annotation";