//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=new EditOperation();
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=await CreatePolylineFromPointAsync((MapPoint)geometry, tol);// Queue feature creation
createOperation.Create(CurrentTemplate, polyline);// Execute the operationreturnawait createOperation.ExecuteAsync();}internalTask<Polyline>CreatePolylineFromPointAsync(MapPointpt,doubletolerance){return QueuedTask.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);return PolylineBuilderEx.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 schemaawait QueuedTask.Run(()=>{//annoLayer is ~your~ Annotation layer...// use the inspector methodologyvarinsp=new Inspector(); insp.Load(annoLayer, oid);// make sure TextString attribute exists.//It is not guaranteed to be in the schema ArcGIS.Desktop.Editing.Attributes.Attribute att= insp.FirstOrDefault(a => a.FieldName =="TEXTSTRING");if(att!=null){ insp["TEXTSTRING"]="Hello World";//create and execute the edit operationEditOperationop=new EditOperation(); 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
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 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=new QueryFilter(){WhereClause="OBJECTID = 1"};//annoLayer is ~your~ Annotation layerusing(varrowCursor= annoLayer.Search(qf)){if(rowCursor.MoveNext()){using(varannoFeature= rowCursor.Current as ArcGIS.Core.Data.Mapping.AnnotationFeature){vargraphic= annoFeature.GetGraphic();vartextGraphic= graphic as CIMTextGraphic;vartextLine= textGraphic.Shape as Polyline;// 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=new EditOperation(); op.Name ="Change annotation angle"; op.Modify(annoLayer, oid, rotatedPolyline); op.Execute();}}}});
Get the Annotation Text Graphic
await QueuedTask.Run(()=>{using(vartable= annoLayer.GetTable()){using(varrc= table.Search()){ rc.MoveNext();using(varaf= rc.Current as AnnotationFeature){vargraphic= af.GetGraphic();vartextGraphic= graphic as CIMTextGraphic;//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.Current as AnnotationFeature){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);}}}});