Working with labels and annotation - Overview

The topic provides an overview of the labeling and annotation components in ArcGIS.


One of the key factors in creating a usable map is labeling features on the map. Labeling is the placing of text near a feature to purvey information about that feature. Normally the label is based on attribute values of the feature itself, but it doesn't have to be.
The ArcGIS labeling objects offer a wide variety of methods for labeling features and for resolving conflicts when labels overlap each other. The labeling behavior includes the ability to specify which features are to be labeled (all features, features identified by an SQL query, and so on); the expression that is used to label them (expressions can be simple or complex based on VBScript and JScript); placement options and weights for those placements; and priority specifications of one layer versus another. Depending on the requirements of the user, it is also possible to label one layer with multiple expressions.
The objects in this model provide the ability to access all of the parameters associated with the labeling of features. Advanced developers can also create their own expression-parsing engines to be used in the labeling process.
Labeling is performed by a label engine.  Two labels engines are available for use with ArcGIS.  The ESRI Standard Label Engine is the default label engine.  The ESRI Maplex Label Engine is a additional label engine for high-end cartographic label placement and is available for use via the Maplex for ArcGIS Extension.
How labeling works
Drawing labels is significantly different than drawing features due to the desire not to have overlapping text on maps.  This requirement is the reason why label placement in ArcGIS is performed after feature drawing in the ArcGIS drawing pipeline.  Also for this reason, label placement is not performed on a layer by layer bases, instead it is performed for entire map at once.  This allows the label engine to consider labels from multiple layers together to optimize the text placement.  With each refresh of the map, label placement is run in order to achieve the best placement for the current map extent etc.
The labeling process is best understood by knowing each step in a label placement run.  These steps in order are:
1) Gather labeling properties from the layers in the map
2) Sort the labeling properties according to label priority
3) Gather the barriers to label placement from the map
4) Place the labels according to the labeling properties from each layer, the maps global level properties, and the barriers
5) Draw the labels to the screen
Map level labeling properties
The Map itself has properties for labeling.  The most significant of this is the annotation engine property accessible via IMap::AnnotationEngine.  This property designates which label engine is used for labeling in the map.  Set the AnnotateMap class to used the ESRI Standard Label Engine or set the MaplexAnnotateMap class to use the ESRI Maplex Label Engine.  Remember that Maplex labeling is architected as an extension and requires the application to have a Maplex license.
Each label engine has a unique set of labeling properties.  Therefore, when a label engine is switched on a map, all the layer level labeling properties are converted to properties of the current label engine.  This ensures that all the labeling properties in the map are properties for the current label engine and not a mix of properties.  This conversion is performed by the MaplexAnnotationPropertiesConverter class.
The Map also implements the interface IMapOverposter which provides access to the OverposterProperties object which implements IOverposterProperties, which implements for the current label engine.  These are general properties that affect labeling of the map.  Each label engine has its own OverposterProperties object.  The interface IOverposterOptions is implemented by BasicOverposterProperties and MaplexOverposterProperties and provides access to general properties such as whether or not to lock the labels (EnableLabelCache property), or draw unplaced labels (EnableDrawUnplaced property).
Layer level labeling properties
Feature layers store labeling properties which define the rules for how labels should be placed, the text string that should be used, and the TextSymbol that should be used.  Feature layers also have a layer level property that tells the label engine whether or not to place labels at all for the layer.  This property is IGeoFeatureLayer::DisplayAnnotation and it is simply set to True when labels are desired. 
Since it is common to place labels differently for different types of features in a single layer, the labeling framework supports multiple sets of labeling properties per layer.  These properties are more commonly known as "label classes" and they are stored in the AnnotateLayerPropertiesCollection of the layer.  The collection can be created, but it is typically retrieved from the IGeoFeatureLayer::AnnotationProperties property on a feature layer.  The IAnnotateLayerPropertiesCollection interface allows for the manipulation of the label classes (objects implementing IAnnotateLayerProperties) held within the collection.
Each label engine has its own object implementing IAnnotateLayerProperties.  The ESRI Standard Label Engine uses the LabelEngineLayerProperties object, while the ESRI Maplex Label Engine uses the MaplexLabelEngineLayerProperties object.
The IAnnotateLayerProperties interface is implemented by the LabelEngineLayerProperties and MaplexLabelEngineLayerProperties  objects and provides the answer to the question of which features to label and at what scales. Through this interface, the developer can specify the priority of the labels, a where clause to be applied to the feature layer, and a specification of what to do with unplaced elements.
The FeatureLinked, LabelWhichFeatures, and GraphicsContainer properties apply only when the set of labels is being converted to annotation. The developer can use the GraphicsContainer property to specify where the converted labels will go.
The FeatureLayer property is used internally during the labeling process. If you find it necessary to set this property, be sure to set it back to Null after labeling has completed.
The ILabelEngineLayerProperties2 interface is implemented by the LabelEngineLayerProperties and MaplexLabelEngineLayerProperties objects and provides access to the expression, symbol, and overposting properties of the label engine object. Use this interface when you want to access the AnnotationExpressionEngine and OverposterLayerProperties objects associated with the label engine object.  Each label engine has its own OverposterLayerProperties object which stores the properties unique to that label engine.
By default, the ExpressionParser property will return the AnnotationVBScriptEngine object. In general, you will will not change this property unless you want to switch to JScript for labeling. In this case, an AnnotationJScriptEngine object would be created, and the ExpressionParser property would be set to this. The expression to use is always set through the Expression property.
The IsExpressionSimple property identifies whether a complex expression is being used in the Expression property. Complex expressions involve a parser object (ExpressionParser property) to parse the string.
The SymbolID property is used during the conversion of labels to annotation when a symbol collection in the AnnotationFeatureClassExtension is referenced.
More precise control of the labeling properties can be obtained by accessing the OverposterLayerProperties of the LabelEngineLayerProperties or MaplexLabelEngineLayerProperties objects. There are two OverposterLayerProperties objects, the BasicOverposterLayerProperties object for the ESRI Standard Label Engine and the MaplexOverposterLayerProperties object for the ESRI Maplex Label Engine.  See the developer help for each of these objects for more information on the large range of labeling properties available for each label engine.
Converting labels to annotation
While labeling dynamically with each Map refresh is a common way to manage text on a map, often there is a desire to refine the placement of labels via editing.  Since labels are dynamically placed, they are not editable.  To edit text you need to convert labels to annotation.  To aide with the conversion of labels to annotation, a helper object named ConvertLabelsToAnnotation exists to make to process simpler.  For examples on how to use this object for various conversion operations see the following topics:
How to convert labels to geodatabase annotation for a single layer
How to convert labels to map annotation for a single layer
ArcGIS provides an annotation feature type for the storage of text in the geodatabase.  Storing text in the geodatabase provides the ability to edit the text and more efficient drawing speeds than dynamic labeling since the positions of text are fixed.  Geodatabase annotation  should not be confused with the similar Map Annotation which is text stored in the Map's BasicGraphicsLayer.  See Working with the map for more information on the Map's BasicGraphicsLayer
Annotation in ArcGIS is enabled through the use of a feature class extension and a special feature type. The AnnotationFeatureClassExtension is used to configure the drawing properties and symbology for annotation features. AnnotationFeature controls the store and communication of feature level operation.  Annotation feature classes are created using methods on the IAnnotationLayerFactory interface on the FDOGraphicsLayerFactory object.
The ArcGIS annotation model was upgraded significantly for the 9.0 release.  If you are working with existing annotation feature classes that have not been updated to the new model, it is a good idea to ensure that they are updated.  See the Geoprocessing tool Update Annotation for more information.

The annotation feature class extension

Annotation features persist and draw text or graphic elements stored in the geodatabase. An annotation feature class can be feature-linked or standard. Feature-linking allows the text of the annotation to be derived from the value of a related feature. The lifetime of the annotation is also controlled by the lifetime of the related feature.  Feature-linked annotation is defined by proper setup of label placement properties in the AnnotationFeatureClassExtension and the existence of a composite relationship class linking the two feature classes together.  Feature-linked annotation is created via converting labels to annotation and specifying that feature-linked annotation is desired or by creating feature-linked annotation with the FDOGraphicsLayerFactory. The IAnnotationClassExtention interface is used to access the properties of the annotation feature class extension. Commonly accessed properties are AnnotationLayerProperties and SymbolCollection.
Annotation features can persist either an entire symbol inline or reference a symbol in a symbol collection. These two persistence mechanisms balance performance with flexibility.
Storing the symbol inline allows the modification of the symbol on a feature-instance basis. Unfortunately, this method increases the size of a row dramatically and may cause performance degradation when drawing large numbers of features in a multiuser environment.
A more efficient alternative is to use symbols in the SymbolCollection of the AnnotationFeatureClassExtension. There symbols are stored as a property of the AnnotationFeatureClassExtension. The annotation feature stores an ID that references a symbol in the extension’s SymbolCollection. TextElements are linked to symbols in the symbol collection by using the ISymbolCollectionElement interface on the TextElement. A small number of commonly changed attributes can be overridden with minimal performance penalties using the ISymbolCollectionElement interface. Once an annotation feature has an element with a collection symbol, it is important that the symbol is not removed or modified in the SymbolCollection.
The IAnnoClassAdmin3 interface is used to update the properties of the class. In a versioned geodatabase, these properties apply to all versions and are not versioned. After creating an annotation feature class, modifying these properties may cause problems with the drawing and selection of annotation features. Adding new symbols to the SymbolCollection or changing the AutoCreate, UpdateOnShapeChange, OverposterProperties, and RequireSymbolID properties are the only recommended modifications. Deleting or modifying symbols in the SymbolCollection requires updating all annotation features whose elements reference the group symbol. When adding new symbols to the SymbolCollection use the AddSymbol method of ISymbolCollection2 , which will automatically assign a unique ID to the symbol. As with any schema related change, an exclusive schema lock must be obtained before calling the UpdateProperties method.
The OverposterProperties property indicates which label engine is to be used by the annotation feature class to generate/update feature-linked annotation.  If the annotation utilizes the ESRI Maplex Label Engine and the annotation is shared with a client without the Maplex for ArcGIS extension, the annotation will simply downgrade to the ESRI Standard Label Engine when labeling operations are run.
The RequireSymbolID property indicates if annotation features are required to reference a symbol in the symbol collection. Referencing a symbol in the symbol collection is the most efficient way to store annotation features. If a symbol does not reference a symbol in the symbol collection, the text symbol is inefficiently stored inline with the feature in the feature’s blob field. Setting this property ensures that features reference a symbol in the symbol collection and are therefore efficiently stored. To avoid separating annotation features from their referenced symbol, modify the properties of each annotation element using ISymbolCollectionElement. This interfaces allow access to the properties of an annotation feature class that can be overridden.
The AllowSymbolOverrides property indicates if an annotation may override a symbol property even though it references the symbol collection. If set to false, only the AnchorPoint, Background, and TextPath of the text symbol can be modified. Modifications of these properties should be performed using ISymbolCollectionElement. This property is best employed in conjunction with RequireSymbolID and is used to limit the properties of an annotation feature that can be edited for either database efficiency of institutional reasons.  Note that setting AllowSymbolOverrides to False greatly reduces the number of properties that can be overridden and it is not recommended that this property be set to False in most cases.
The annotation feature
The AnnotationFeature persists and draws GraphicElements that are stored in the geodatabase. Typically annotation stores TextElements and much of the behavior is optimized for TextElements. Annotation features can be linked to features in a related FeatureClass
The IAnnotationFeature interface is used for relating AnnotationFeatures to other features or updating the graphic of the annotation. The Annotation property accepts any GraphicElement. If a TextElement is used, a group symbol can be assigned by using the IGroupSymbol interface. A TextElement that does not reference a symbol in the symbol collection will have a group symbol ID of -1.
To relate an AnnotationFeature to another feature (a RelationshipClass must already exist), assign the OID of the related feature to the LinkedFeatureID property. If the AnnotationFeature is not linked, the LinkedFeatureID property is -1. After updating either of these properties, the IFeature::Store methods must be called.
The IAnnotationFeature2 interface was added to provide access to the AnnotationClassID and Status of the annotation feature. You may wish to update the status of an annotation feature from "Unplaced" to "Placed" after altering it.
The annotation feature class also has a series of fields which mirror properties stored in the annotation features Element field (where the GraphicElements are stored).  Updating the field values via the Geodatabase API will cause the annotation blob, and therefore the annotation feature to update.  This is a simple way to perform batch updates to an annotation feature.

Development licensingDeployment licensing
ArcGIS for Desktop BasicArcGIS for Desktop Basic
ArcGIS for Desktop StandardArcGIS for Desktop Standard
ArcGIS for Desktop AdvancedArcGIS for Desktop Advanced
Engine Developer KitEngine
ArcGIS for Desktop Basic: MaplexArcGIS for Desktop Basic: Maplex
ArcGIS for Desktop Standard: MaplexArcGIS for Desktop Standard: Maplex
Engine: Maplex