How can I create Text Anntation with given FontSize and Alignment ? 

237
1
01-26-2018 12:22 PM
Highlighted
Occasional Contributor

Hi,

We are use 2.1 Arcgis Pro sdk to develope tools. How can I create Text Anntation with given FontSize and Alignment ? I can not set FontSize value (ex: 0,4) and Aligment value (ex: ArcGIS.Core.CIM.HorizontalAlignment.Center). I can do with second (update text annotation) operation after create with EditCompletedEvent like below :

var cimTextSymbol = symbol as CIMTextSymbol;
cimTextSymbol.HorizontalAlignment = ArcGIS.Core.CIM.HorizontalAlignment.Center;
cimTextSymbol.VerticalAlignment = ArcGIS.Core.CIM.VerticalAlignment.Center;

cimTextSymbol.SetSize(0.4);

How can I set values with the first operaton (create new text annotation) ?The code I'm using is below , here is also problem lines in bold text font :  

protected override async Task<bool> OnSketchCompleteAsync(Geometry geometry)
{

bool result = await QueuedTask.Run(() =>
{

var annoLayer = MapView.Active.Map.FindLayers("ANNOTATIONLAYER").FirstOrDefault() as AnnotationLayer;
if (annoLayer == null)
return false;

var fc = annoLayer.GetFeatureClass() as ArcGIS.Core.Data.Mapping.AnnotationFeatureClass;
if (fc == null)
return false;

var cimDefinition = fc.GetDefinition() as ArcGIS.Core.Data.Mapping.AnnotationFeatureClassDefinition;
var labels = cimDefinition.GetLabelClassCollection();
var symbols = cimDefinition.GetSymbolCollection();

if ((labels.Count == 0) || (symbols.Count == 0))
return false;

var label = labels[0];
if (labels.Count > 1)
{
foreach (var LabelClass in labels)
{
if (LabelClass.Name == CurrentTemplate.Name)
{
label = LabelClass;
break;
}
}
}

var symbolName = label.TextSymbol.SymbolName;
int symbolID = -1;
if (!int.TryParse(symbolName, out symbolID))
{
foreach (var symbol in symbols)
{
if (symbol.Name == symbolName)
{
symbolID = symbol.ID;
break;
}
}
}
if (symbolID == -1)
return false;

Dictionary<string, object> values = new Dictionary<string, object>();
values.Add("SymbolID", symbolID);
values.Add("AnnotationClassID", label.ID);

int idxField = annoLayer.GetFeatureClass().GetDefinition().FindField("TextString");

values.Add("TextString", "Text");
values["SHAPE"] = geometry;


values["VerticalAlignment"] = ArcGIS.Core.CIM.VerticalAlignment.Center;     //NOT SET VALUE 
values["HorizontalAlignment"] = ArcGIS.Core.CIM.HorizontalAlignment.Center;   //NOT SET VALUE
values["FontSize"] = 0.4;    //NOT SET VALUE

var createOperation = new EditOperation();
createOperation.SelectNewFeatures = true;
createOperation.Create(annoLayer, values);

return createOperation.Execute();

});

return result;
}

Thanks .

Reply
0 Kudos
1 Reply
Highlighted
Esri Contributor

Taner,

Unfortunately functionality to customize an annotation symbol at feature creation time at Pro 2.1 is limited. The expectation is that the symbols and templates defined on the annotation feature class are authored in such a way that additional customization is not required at creation.

As you have found, when using the dictionary signature of EditOperation.Create, the value in the SymbolID field determines the symbol used for the newly created feature. Additional symbol formatting properties set in the dictionary are ignored. (The TextString field is the exception.)

We are continuing to work on the annotation API and this is one of the areas identified that will be enhanced for ArcGIS Pro 2.2.

In the meantime, if you still wish to customize the symbol within the same operation there are two options
1. trap for the EditCompleted event, look for the features created and update the CIMTextGraphic as you indicate you have done.
2. Use a second operation that is chained to the first which performs the CIMTextGraphic modification via the EditOperation.Callback method.

Both of these options ensure you only have one item on the undo/redo stack.

Here's an example of how to use a chained operation to customize the text symbol after the feature is created.

protected override async Task<bool> OnSketchCompleteAsync(Geometry geometry)

{

   if (CurrentTemplate == null || geometry == null)

      return false;

   bool result = await QueuedTask.Run(() =>

   {

      // get the anno layer, feature class

      AnnotationLayer annoLayer = CurrentTemplate.Layer as AnnotationLayer;

      if (annoLayer == null)

        return false;

      var fc = annoLayer.GetFeatureClass() as ArcGIS.Core.Data.Mapping.AnnotationFeatureClass;

      if (fc == null)

        return false;

      // get the featureclass CIM definition which contains the labels, symbols

      var cimDefinition = fc.GetDefinition() as ArcGIS.Core.Data.Mapping.AnnotationFeatureClassDefinition;

      var labels = cimDefinition.GetLabelClassCollection();

      var symbols = cimDefinition.GetSymbolCollection();

      // make sure there are symbols

      if ((labels.Count == 0) || (symbols.Count == 0))

        return false;

      var label = labels[0];

      if (labels.Count > 1)

      {

         foreach (var LabelClass in labels)

         {

            if (LabelClass.Name == CurrentTemplate.Name)

            {

               label = LabelClass;

               break;

            }

         }

      }

      var symbolName = label.TextSymbol.SymbolName;

      int symbolID = -1;

      if (!int.TryParse(symbolName, out symbolID))

      {

         foreach (var symbol in symbols)

         {

            if (symbol.Name == symbolName)

            {

              symbolID = symbol.ID;

              break;

           }

         }

      }

      if (symbolID == -1)

         return false;

      // Create an edit operation

      var createOperation = new EditOperation();

      createOperation.Name = string.Format("Create {0}", CurrentTemplate.Layer.Name);

      createOperation.SelectNewFeatures = true;

     

      // use the dictionary to set values

      Dictionary<string, object> values = new Dictionary<string, object>();

      values.Add("SymbolID", symbolID);

      values.Add("AnnotationClassID, label.ID);

      int idxField = cimDefinition.FindField("TextString");
      if (idxField != -1)
         values.Add("TextString", "My annotation feature");

      // set the cimTextGraphic geometry to be the sketched line

      values["SHAPE"] = geometry;

      // create and execute

      long newFeatureID = -1;

      createOperation.Create(CurrentTemplate.Layer, values, oid => newFeatureID = oid);

      bool opResult = createOperation.Execute();

      // if success, 

      if (opResult)

      {

        // chain an operation to customize the text symbol - chaining means that the two operations will be grouped as one on the undo/redo stack

        var chainedOp = createOperation.CreateChainedOperation();

        chainedOp.Callback(context =>

        {

           // find the feature

           QueryFilter qf = new QueryFilter();

           qf.WhereClause = "OBJECTID = " + newFeatureID.ToString();

           // make sure you use a non-recycling cursor

           using (var rowCursor = fc.Search(qf, false))

           {

             rowCursor.MoveNext();

             if (rowCursor.Current != null)

            {

               ArcGIS.Core.Data.Mapping.AnnotationFeature annoFeature = rowCursor.Current as

ArcGIS.Core.Data.Mapping.AnnotationFeature;

               if (annoFeature != null)

               {

                  // get the CIMTextGraphic

                  var textGraphic = annoFeature.GetGraphic() as CIMTextGraphic;

                  if (textGraphic != null)

                 {

                    var symbol = textGraphic.Symbol.Symbol;

                    var cimTextSymbol = symbol as CIMTextSymbol;

                    cimTextSymbol.HorizontalAlignment = ArcGIS.Core.CIM.HorizontalAlignment.Center;

                    cimTextSymbol.VerticalAlignment = ArcGIS.Core.CIM.VerticalAlignment.Center;

                    cimTextSymbol.SetSize(0.4);

                    // update the graphic

                    annoFeature.SetGraphic(textGraphic);

                    // store

                    annoFeature.Store();

                    // refresh the cache

                    context.Invalidate(annoFeature);

                 }

               }

           }

         }

       }, fc);

       // execute the chained operation

       chainedOp.Execute();

     }
     return opResult;
  });

  return result;
}

Reply
0 Kudos