//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=MapPointBuilder.CreateMapPoint(pt.X+tolerance,pt.Y,pt.SpatialReference);returnPolylineBuilder.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(()=>{varrc=annoLayer.GetTable().Search();rc.MoveNext();varaf=rc.CurrentasAnnotationFeature;vargraphic=af.GetGraphic();vartextGraphic=graphicasCIMTextGraphic;//Note: //var outline_geom = af.GetGraphicOutline(); //gets the anno text outline geometry...af.Dispose();rc.Dispose();});
Change Annotation Text Graphic
awaitQueuedTask.Run(()=>{EditOperationop=newEditOperation();op.Name="Change annotation graphic";//At 2.1 we must use an edit operation Callback...op.Callback(context =>{QueryFilterqf=newQueryFilter(){WhereClause="OBJECTID = 1"};//Cursor must be non-recycling. Use the table ~not~ the layer..i.e. "GetTable().Search()"//annoLayer is ~your~ Annotation layerusing(varrowCursor=annoLayer.GetTable().Search(qf,false)){if(rowCursor.MoveNext()){using(varannoFeature=rowCursor.CurrentasArcGIS.Core.Data.Mapping.AnnotationFeature){//Get the graphic from the anno featurevargraphic=annoFeature.GetGraphic();vartextGraphic=graphicasCIMTextGraphic;// change the text and the colortextGraphic.Text="hello world";varsymbol=textGraphic.Symbol.Symbol;symbol.SetColor(ColorFactory.Instance.RedRGB);textGraphic.Symbol=symbol.MakeSymbolReference();// update the graphicannoFeature.SetGraphic(textGraphic);// store is requiredannoFeature.Store();//refresh layer cachecontext.Invalidate(annoFeature);}}}},annoLayer.GetTable());op.Execute();});
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 selectedvarrc=annoLayer.GetFeatureClass().Search();rc.MoveNext();varaf=rc.CurrentasAnnotationFeature;varoutline_geom=af.GetGraphicOutline();//TODO - use the outline...//Note: //var graphic = annoFeature.GetGraphic(); //gets the CIMTextGraphic...af.Dispose();rc.Dispose();});
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 selectedvarrc=annoLayer.GetFeatureClass().Search();rc.MoveNext();varoid=rc.Current.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 scalevarmask_geom=annoLayer.QueryDrawingOutline(oid,mv,DrawingOutlineType.Exact);rc.Dispose();});