//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;//protectedasyncoverrideTask<bool>OnSketchCompleteAsync(Geometrygeometry){if(CurrentTemplate==null||geometry==null)returnfalse;// Create an edit operationvarcreateOperation=newEditOperation();createOperation.Name=string.Format("Create {0}",CurrentTemplate.Layer.Name);createOperation.SelectNewFeatures=true;// update the geometry point into a 2 point line//annotation needs at minimum a 2 point line for the text to be placeddoubletol=0.01;varpolyline=awaitCreatePolylineFromPointAsync((MapPoint)geometry,tol);// Queue feature creationcreateOperation.Create(CurrentTemplate,polyline);// Execute the operationreturnawaitcreateOperation.ExecuteAsync();}internalTask<Polyline>CreatePolylineFromPointAsync(MapPointpt,doubletolerance){returnQueuedTask.Run(()=>{// create a polyline from a starting point//use a tolerance to construct the second pointMapPointpt2=MapPointBuilderEx.CreateMapPoint(pt.X+tolerance,pt.Y,pt.SpatialReference);returnPolylineBuilderEx.CreatePolyline(newList<MapPoint>(){pt,pt2});});}
Update Annotation Text via attribute. Caveat: The TEXTSTRING Anno attribute must exist
//See "Change Annotation Text Graphic" for an alternative if TEXTSTRING is missing from the schemaawaitQueuedTask.Run(()=>{//annoLayer is ~your~ Annotation layer...// use the inspector methodologyvarinsp=newInspector();insp.Load(annoLayer,oid);// make sure TextString attribute exists.//It is not guaranteed to be in the schemaArcGIS.Desktop.Editing.Attributes.Attributeatt=insp.FirstOrDefault(a =>a.FieldName=="TEXTSTRING");if(att!=null){insp["TEXTSTRING"]="Hello World";//create and execute the edit operationEditOperationop=newEditOperation();op.Name="Update annotation";op.Modify(insp);//OR using a Dictionary - again TEXTSTRING has to exist in the schema//Dictionary<string, object> newAtts = new Dictionary<string, object>();//newAtts.Add("TEXTSTRING", "hello world");//op.Modify(annoLayer, oid, newAtts);op.Execute();}});
Rotate or Move the Annotation
awaitQueuedTask.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 get the TextGraphic from the anno feature.//The TextGraphic shape will be the anno baseline...//At 2.1 the only way to retrieve this textLine is to obtain the TextGraphic from the AnnotationFeatureQueryFilterqf=newQueryFilter(){WhereClause="OBJECTID = 1"};//annoLayer is ~your~ Annotation layerusing(varrowCursor=annoLayer.Search(qf)){if(rowCursor.MoveNext()){using(varannoFeature=rowCursor.CurrentasArcGIS.Core.Data.Mapping.AnnotationFeature){vargraphic=annoFeature.GetGraphic();vartextGraphic=graphicasCIMTextGraphic;vartextLine=textGraphic.ShapeasPolyline;// rotate the shape 90 degreesvarorigin=GeometryEngine.Instance.Centroid(textLine);GeometryrotatedPolyline=GeometryEngine.Instance.Rotate(textLine,origin,System.Math.PI/2);//Move the line 5 "units" in the x and y direction//GeometryEngine.Instance.Move(textLine, 5, 5);EditOperationop=newEditOperation();op.Name="Change annotation angle";op.Modify(annoLayer,oid,rotatedPolyline);op.Execute();}}}});
Get the Annotation Text Graphic
awaitQueuedTask.Run(()=>{using(vartable=annoLayer.GetTable()){using(varrc=table.Search()){rc.MoveNext();using(varaf=rc.CurrentasAnnotationFeature){vargraphic=af.GetGraphic();vartextGraphic=graphicasCIMTextGraphic;//Note: //var outline_geom = af.GetGraphicOutline(); //gets the anno text outline geometry...}}}});
Get the Outline Geometry for an Annotation
varannoLayer=MapView.Active.Map.GetLayersAsFlattenedList().OfType<AnnotationLayer>().FirstOrDefault();if(annoLayer==null)return;QueuedTask.Run(()=>{//get the first annotation feature...//...assuming at least one feature gets selectedusing(varfc=annoLayer.GetFeatureClass()){using(varrc=fc.Search()){rc.MoveNext();using(varaf=rc.CurrentasAnnotationFeature){varoutline_geom=af.GetGraphicOutline();//TODO - use the outline...//Note: //var graphic = annoFeature.GetGraphic(); //gets the CIMTextGraphic...}}}});
Get the Mask Geometry for an Annotation
varannoLayer=MapView.Active.Map.GetLayersAsFlattenedList().OfType<AnnotationLayer>().FirstOrDefault();if(annoLayer==null)return;varmv=MapView.Active;QueuedTask.Run(()=>{//get the first annotation feature...//...assuming at least one feature gets selectedusing(varfc=annoLayer.GetFeatureClass()){using(varrc=fc.Search()){rc.MoveNext();using(varrow=rc.Current){varoid=row.GetObjectID();//Use DrawingOutlineType.BoundingEnvelope to retrieve a generalized//mask geometry or "Box". The mask will be in the same SpatRef as the map.//The mask will be constructed using the anno class reference scale//At 2.x - var mask_geom = annoLayer.QueryDrawingOutline(oid, mv, DrawingOutlineType.Exact);varmask_geom=annoLayer.GetDrawingOutline(oid,mv,DrawingOutlineType.Exact);}}}});