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";