I am developing pythonaddin tool which as a result should update/accumulate a predefined geodatabase annotation standard class. I am stucked at the point where I believe that arcpy has limitations within annotation operations.
With click on the button, I am aiming to show labels with given expresion, to set up data frame scale, convert label to annotation and append it to already predefined annotation.
In the tool, I am able to finalize steps with labels, but not to convert and update existing annotation layer using arcpy.

 if layer.supports("LABELCLASSES"):
    for lblClass in layer.labelClasses:
        lblClass.showClassLabels = True
 lblClass.expression ='"%s" & [export.DARST1] & "%s"' % ("<CLR red='255' green='0' blue='0'>", "</CLR>")
 layer.visible = True
 layer.showLabels = True
 self.df.scale = 10000

The arcpy methods arcpy.TiledLabelsToAnnotation_cartography and then arcpy.AppendAnnotation_management do not really help, because they create new annotation features and then trying to append it to predefined annotation is getting hard - makes it difficult and slow, but I will not say imposible.
Moreover, the last steps I need, would be possible to execute manually (pic below), therefore my assumption is that it can to be performed by adding some lines of code from arcobjects?!
convert labels and attach to existing annotation feature

Any help if it is possible with python for arcobjects is welcome, otherwise I assume the problem can be solved by working with ArcObjects for .NET/C#...

1 Answer 1


I actually ended up learning and developing the addin using ArcObjects in C# .NET as I was not certain if it's possible in arcpy. With help of ArcObjects reference book as well as the book Beginning ArcGIS Desktop Development using .NET I found the following solution:

  • to change a color from text label, the interfaces applied were: IColor, IRgbColor from ArcObjects
  • to change the label text style, it was applied: stdole.IFontDisp .NET reference
  • to set up the label expression, there were applied IAnnotateLayerProperties and ILabelEngineLayerProperties2, the method: Expression
  • To convert label to annotation, the interface IConvertLabelsToAnnotation
  • Finally the snippet code, on which the solution was mostly referenced

Here you can find the code for ArcMap Add-In Component Button (note: only field name has changed to "UEBSCHL").

using System;
using System.Collections.Generic;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Display;
using System.Windows.Forms;

namespace LabelToAnnotation
    public class LabelToAnnotation : ESRI.ArcGIS.Desktop.AddIns.Button
        static void ConvertLabelsToGDBAnnotationSingleLayer(IMap pMap, int layerIDx, bool featureLinked)
            // call ConvertLabelsTo Annotation Interface and define necessary parameters
            IConvertLabelsToAnnotation pConvertLabelsToAnnotation = new ConvertLabelsToAnnotation() as IConvertLabelsToAnnotation;
            //ITrackCancel parameter
            ITrackCancel pTrackCancel = new CancelTracker() as ITrackCancel;
            //Change global level options for the conversion by sending in different parameters to the next line.
            pConvertLabelsToAnnotation.Initialize(pMap, esriAnnotationStorageType.esriDatabaseAnnotation, esriLabelWhichFeatures.esriSelectedFeatures, true, pTrackCancel, null);

            //get layer according to provided index and obtain dataset
            ILayer pLayer = pMap.get_Layer(layerIDx);
            IGeoFeatureLayer pGeoFeatureLayer = pLayer as IGeoFeatureLayer;
            IFeatureClass pFeatureClass = pGeoFeatureLayer.FeatureClass;
            IDataset pDataset = pFeatureClass as IDataset;

            //color for labels
            IRgbColor rgbColor = new RgbColor() as IRgbColor;
            rgbColor.Red = 255;
            rgbColor.Green = 0;
            rgbColor.Blue = 0;

            IColor lColor = rgbColor as IColor;
            // create font for labels
            stdole.IFontDisp newFont = new stdole.StdFont() as stdole.IFontDisp;
            newFont.Bold = true;
            newFont.Size = 8;

           // create text symbol and set parameters for label style
            ITextSymbol lTxtSymbol = new TextSymbol() as ITextSymbol;
            lTxtSymbol.Color = rgbColor;
            lTxtSymbol.Font = newFont;
            lTxtSymbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHALeft;
            lTxtSymbol.VerticalAlignment = esriTextVerticalAlignment.esriTVABottom;

            if (pGeoFeatureLayer != null)
                //define annotation layer properties collection
                IAnnotateLayerPropertiesCollection annotationLPC = pGeoFeatureLayer.AnnotationProperties;
                pGeoFeatureLayer.DisplayAnnotation = true;

                //define annotation layer properties, set up label symbology and expression
                //add to collection
                IAnnotateLayerProperties annotateLP = new LabelEngineLayerProperties() as IAnnotateLayerProperties;
                ILabelEngineLayerProperties2 labelELP = annotateLP as ILabelEngineLayerProperties2;
                labelELP.Expression = string.Format("[UEBSCHL]");
                labelELP.Symbol = lTxtSymbol;

                //get feature workspace GDB needed for ConvertLabelsToAnnotation 
                IFeatureWorkspace pFeatureWorkspace = pDataset.Workspace as IFeatureWorkspace;

                Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
                IWorkspaceFactory wsF = Activator.CreateInstance(factoryType) as IWorkspaceFactory;
                IWorkspace ws = wsF.OpenFromFile(pDataset.Workspace.PathName, ArcMap.Application.hWnd);
                IFeatureWorkspace fws = ws as IFeatureWorkspace;
                IWorkspace2 ws2 = fws as IWorkspace2;

                //set up scale on 1:10000 
                pMap.MapScale = 10000;

                //create base annotation if not exists
                if (ws2.get_NameExists(esriDatasetType.esriDTFeatureClass, "KARTE_LP_DARST1_temp") == false)

                    MessageBox.Show(string.Format("The {0} FeatureClass doesn't exist", pDataset.Name));
                    pConvertLabelsToAnnotation.AddFeatureLayer(pGeoFeatureLayer,"KARTE_LP_DARST1_temp", pFeatureWorkspace,
                    pFeatureClass.FeatureDataset, featureLinked, false, false, true, true, "");

                    //Do the conversion.

                    IEnumLayer pEnumLayer = pConvertLabelsToAnnotation.AnnoLayers;
                    //Turn off labeling for the layer converted.
                    pGeoFeatureLayer.DisplayAnnotation = false;

                    //Add the result annotation layer to the map.
                    pMap.AddLayers(pEnumLayer, true);

                //otherwise append labels of selected features on base annotation layer
                    //append to annotation with layer name: "KARTE_LP_DARST1_temp" 
                    pConvertLabelsToAnnotation.AddFeatureLayer(pGeoFeatureLayer,/*pGeoFeatureLayer.Name + */"KARTE_LP_DARST1_temp", pFeatureWorkspace, pFeatureClass.FeatureDataset, featureLinked, true);


                //Refresh the map to update the display.
                IActiveView pActiveView = pMap as IActiveView;

        public LabelToAnnotation()

        protected override void OnClick()
            //get the mxd document and data frame
            IMxDocument pMxDoc = ArcMap.Application.Document as IMxDocument;
            IMap pMap = pMxDoc.FocusMap;
            //the labels of the first (selected)features layer in data frame will be appended to "KARTE_LP_DARST1_temp"
            ConvertLabelsToGDBAnnotationSingleLayer(pMap, 0 , false);

        protected override void OnUpdate()
            Enabled = ArcMap.Application != null;


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.