GetAnnotationProperties Method
Gets the
ArcGIS.Desktop.Editing.AnnotationProperties for annotation features in the inspector. This method must be called on the MCT. Use QueuedTask.Run.
Return Value
The annotation properties for the features currently loaded in the inspector.
Create Annotation Template
// get an anno layer
AnnotationLayer annoLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<AnnotationLayer>().FirstOrDefault();
if (annoLayer == null)
return;
QueuedTask.Run(() =>
{
Inspector insp = null;
// get the anno feature class
var fc = annoLayer.GetFeatureClass() as ArcGIS.Core.Data.Mapping.AnnotationFeatureClass;
// 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 labels, symbols
if ((labels.Count == 0) || (symbols.Count == 0))
return;
// find the label class required
// typically you would use a subtype name or some other characteristic
// in this case lets just use the first one
var label = labels[0];
// each label has a textSymbol
// the symbolName *should* be the symbolID to be used
var symbolName = label.TextSymbol.SymbolName;
int symbolID = -1;
if (!int.TryParse(symbolName, out symbolID))
{
// int.TryParse fails - attempt to find the symbolName in the symbol collection
foreach (var symbol in symbols)
{
if (symbol.Name == symbolName)
{
symbolID = symbol.ID;
break;
}
}
}
// no symbol?
if (symbolID == -1)
return;
// load the schema
insp = new Inspector();
insp.LoadSchema(annoLayer);
// ok to assign these fields using the inspector[fieldName] methodology
// these fields are guaranteed to exist in the annotation schema
insp["AnnotationClassID"] = label.ID;
insp["SymbolID"] = symbolID;
// set up some additional annotation properties
AnnotationProperties annoProperties = insp.GetAnnotationProperties();
annoProperties.FontSize = 36;
annoProperties.TextString = "My Annotation feature";
annoProperties.VerticalAlignment = VerticalAlignment.Top;
annoProperties.HorizontalAlignment = HorizontalAlignment.Justify;
insp.SetAnnotationProperties(annoProperties);
var tags = new[] { "Annotation", "tag1", "tag2" };
// use daml-id rather than guid
string defaultTool = "esri_editing_SketchStraightAnnoTool";
// tool filter is the tools to filter OUT
var toolFilter = new[] { "esri_editing_SketchCurvedAnnoTool" };
// create a new template
var newTemplate = annoLayer.CreateTemplate("new anno template", "description", insp, defaultTool, tags, toolFilter);
});
Annotation Construction Tool
//In your config.daml...set the categoryRefID
//<tool id="..." categoryRefID="esri_editing_construction_annotation" caption="Create Anno" ...>
//Sketch type Point or Line or BezierLine in the constructor...
//internal class AnnoConstructionTool : MapTool {
// public AnnoConstructionTool() {
// IsSketchTool = true;
// UseSnapping = true;
// SketchType = SketchGeometryType.Point;
//
protected async override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
if (CurrentTemplate == null || geometry == null)
return false;
// Create an edit operation
var createOperation = new EditOperation();
createOperation.Name = string.Format("Create {0}", CurrentTemplate.Layer.Name);
createOperation.SelectNewFeatures = true;
var insp = CurrentTemplate.Inspector;
var result = await QueuedTask.Run(() =>
{
// get the annotation properties class
AnnotationProperties annoProperties = insp.GetAnnotationProperties();
// set custom annotation properties
annoProperties.TextString = "my custom text";
annoProperties.Color = ColorFactory.Instance.RedRGB;
annoProperties.FontSize = 24;
annoProperties.FontName = "Arial";
annoProperties.HorizontalAlignment = ArcGIS.Core.CIM.HorizontalAlignment.Right;
annoProperties.Shape = geometry;
// assign annotation properties back to the inspector
insp.SetAnnotationProperties(annoProperties);
// Queue feature creation
createOperation.Create(CurrentTemplate.Layer, insp);
if (!createOperation.IsEmpty)
{
// Execute the operation
return createOperation.Execute(); //Execute and ExecuteAsync will return true if the operation was successful and false if not
}
else
return false;
});
return result;
}
Programmatically Create an Annotation Feature
await QueuedTask.Run(() =>
{
// annoLayer is ~your~ Annotation layer...
// pnt is ~your~ Annotation geometry ...
var op = new EditOperation();
// Use the inspector
var insp = new Inspector();
insp.LoadSchema(annoLayer);
// get the annotation properties from the inspector
AnnotationProperties annoProperties = insp.GetAnnotationProperties();
// change the annotation text
annoProperties.TextString = DateTime.Now.ToLongTimeString();
// change font color to green
annoProperties.Color = ColorFactory.Instance.GreenRGB;
// change the horizontal alignment
annoProperties.HorizontalAlignment = HorizontalAlignment.Center;
annoProperties.Shape = pnt;
// set the annotation properties back on the inspector
insp.SetAnnotationProperties(annoProperties);
// create the annotation
op.Create(annoLayer, insp);
if (!op.IsEmpty)
{
var result = op.Execute(); //Execute and ExecuteAsync will return true if the operation was successful and false if not
}
});
Update Annotation Text
await QueuedTask.Run(() =>
{
//annoLayer is ~your~ Annotation layer...
// use the inspector methodology
//at 2.x - var insp = new Inspector(true);
var insp = new Inspector();
insp.Load(annoLayer, oid);
// get the annotation properties
AnnotationProperties annoProperties = insp.GetAnnotationProperties();
// set the attribute
annoProperties.TextString = "Hello World";
// assign the annotation proeprties back to the inspector
insp.SetAnnotationProperties(annoProperties);
//create and execute the edit operation
EditOperation op = new EditOperation();
op.Name = "Update annotation";
op.Modify(insp);
if (!op.IsEmpty)
{
var result = op.Execute(); //Execute and ExecuteAsync will return true if the operation was successful and false if not
}
});
Modify Annotation Shape
await QueuedTask.Run(() =>
{
//Don't use 'Shape'....Shape is the bounding box of the annotation text. This is NOT what you want...
//
//var insp = new Inspector();
//insp.Load(annoLayer, oid);
//var shape = insp["SHAPE"] as Polygon;
//...wrong shape...
//Instead, we must use the AnnotationProperties
//annoLayer is ~your~ Annotation layer
//at 2.x - var insp = new Inspector(true);
var insp = new Inspector();
insp.Load(annoLayer, oid);
AnnotationProperties annoProperties = insp.GetAnnotationProperties();
var shape = annoProperties.Shape;
if (shape.GeometryType != GeometryType.GeometryBag)
{
var newGeometry = GeometryEngine.Instance.Move(shape, 10, 10);
annoProperties.Shape = newGeometry;
insp.SetAnnotationProperties(annoProperties);
EditOperation op = new EditOperation();
op.Name = "Change annotation angle";
op.Modify(insp);
if (!op.IsEmpty)
{
var result = op.Execute(); //Execute and ExecuteAsync will return true if the operation was successful and false if not
}
}
});
Modify Annotation Text Graphic
await QueuedTask.Run(() =>
{
var selection = annoLayer.GetSelection();
if (selection.GetCount() == 0)
return;
// use the first selelcted feature
//at 2.x - var insp = new Inspector(true);
var insp = new Inspector();
insp.Load(annoLayer, selection.GetObjectIDs().FirstOrDefault());
// getAnnoProperties should return null if not an annotation feature
AnnotationProperties annoProperties = insp.GetAnnotationProperties();
// get the textGraphic
CIMTextGraphic textGraphic = annoProperties.TextGraphic;
// change text
textGraphic.Text = "Hello world";
// set x,y offset via the symbol
var symbol = textGraphic.Symbol.Symbol;
var textSymbol = symbol as CIMTextSymbol;
textSymbol.OffsetX = 2;
textSymbol.OffsetY = 3;
textSymbol.HorizontalAlignment = HorizontalAlignment.Center;
// load the updated textGraphic
annoProperties.LoadFromTextGraphic(textGraphic);
// assign the annotation properties back
insp.SetAnnotationProperties(annoProperties);
EditOperation op = new EditOperation();
op.Name = "modify symbol";
op.Modify(insp);
if (!op.IsEmpty)
{
bool result = op.Execute(); //Execute and ExecuteAsync will return true if the operation was successful and false if not
}
});
Target Platforms: Windows 11, Windows 10
ArcGIS Pro version: 3 or higher.