varoid=1;// See "Change Annotation Text Graphic" for an alternative if TEXTSTRING is missing from the schema// Note: QueuedTask is required to access the Inspector{// use the inspector methodologyvarinsp=newInspector();insp.Load(annotationLayer,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(annotationLayer, oid, newAtts);op.Execute();}}
Rotate or Move the Annotation
varoid=1;//ObjectID of the annotation feature to modify// Note: QueuedTask is required to access the AnnotationFeature{//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(annotationLayer, 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...QueryFilterqf=newQueryFilter(){WhereClause="OBJECTID = 1"};//annotationLayer is ~your~ Annotation layerusingvarrowCursor=annotationLayer.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(annotationLayer,oid,rotatedPolyline);op.Execute();}}}
Get the Annotation Text Graphic
// Note: QueuedTask is required to access the AnnotationFeature{usingvartable=annotationLayer.GetTable();usingvarrc=table.Search();rc.MoveNext();usingvaraf=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
// Note: QueuedTask is required to access the AnnotationFeature{//get the first annotation feature...//...assuming at least one feature gets selectedusingvarfc=annotationLayer.GetFeatureClass();usingvarrc=fc.Search();rc.MoveNext();usingvaraf=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
varmv=MapView.Active;// Note: QueuedTask is required to access the AnnotationFeature{//get the first annotation feature...//...assuming at least one feature gets selectedusingvarfc=annotationLayer.GetFeatureClass();usingvarrc=fc.Search();rc.MoveNext();usingvarrow=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 scalevarmask_geom=annotationLayer.GetDrawingOutline(oid,mv,DrawingOutlineType.Exact);}
Create Annotation Construction Tool
publicclassAnnoConstructionTool:MapTool{//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...publicAnnoConstructionTool(){IsSketchTool=true;UseSnapping=true;SketchType=SketchGeometryType.Point;}/// <summary>/// Callback when the sketch operation is complete./// </summary>/// <param name="geometry">The geometry resulting from the sketch operation. Must not be <see langword="null"/>.</param>/// <returns>A task that represents the asynchronous operation. The task result is <see langword="true"/> if the feature/// creation operation succeeds; otherwise, <see langword="false"/>.</returns>protectedasyncoverrideTask<bool>OnSketchCompleteAsync(ArcGIS.Core.Geometry.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();}/// <summary>/// Creates a polyline starting from the specified map point, with an additional point offset by the given tolerance./// </summary>/// <param name="pt">The starting <see cref="MapPoint"/> for the polyline.</param>/// <param name="tolerance">The distance, in the same spatial reference units as <paramref name="pt"/>, used to calculate the offset for the/// second point.</param>/// <returns>A <see cref="Task{Polyline}"/> representing the asynchronous operation. The result contains the constructed/// polyline.</returns>publicTask<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});});}}