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 .
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;
}