-
Notifications
You must be signed in to change notification settings - Fork 117
ProSnippets Annotation
uma2526 edited this page Nov 10, 2021
·
15 revisions
Language: C#
Subject: Annotation
Contributor: ArcGIS Pro SDK Team <arcgisprosdk@esri.com>
Organization: esri, http://www.esri.com
Date: 10/29/2021
ArcGIS Pro: 2.9
Visual Studio: 2017, 2019
.NET Target Framework: 4.8
//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;
// update the geometry point into a 2 point line
//annotation needs at minimum a 2 point line for the text to be placed
double tol = 0.01;
var polyline = await CreatePolylineFromPointAsync((MapPoint)geometry, tol);
// Queue feature creation
createOperation.Create(CurrentTemplate, polyline);
// Execute the operation
return await createOperation.ExecuteAsync();
}
internal Task<Polyline> CreatePolylineFromPointAsync(MapPoint pt, double tolerance)
{
return QueuedTask.Run(() =>
{
// create a polyline from a starting point
//use a tolerance to construct the second point
MapPoint pt2 = MapPointBuilder.CreateMapPoint(pt.X + tolerance, pt.Y, pt.SpatialReference);
return PolylineBuilder.CreatePolyline(new List<MapPoint>() { pt, pt2 });
});
}
//See "Change Annotation Text Graphic" for an alternative if TEXTSTRING is missing from the schema
await QueuedTask.Run(() =>
{
//annoLayer is ~your~ Annotation layer...
// use the inspector methodology
var insp = 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 operation
EditOperation op = 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();
}
});
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 AnnotationFeature
QueryFilter qf = new QueryFilter()
{
WhereClause = "OBJECTID = 1"
};
//annoLayer is ~your~ Annotation layer
using (var rowCursor = annoLayer.Search(qf))
{
if (rowCursor.MoveNext())
{
using (var annoFeature = rowCursor.Current as ArcGIS.Core.Data.Mapping.AnnotationFeature)
{
var graphic = annoFeature.GetGraphic();
var textGraphic = graphic as CIMTextGraphic;
var textLine = textGraphic.Shape as Polyline;
// rotate the shape 90 degrees
var origin = GeometryEngine.Instance.Centroid(textLine);
Geometry rotatedPolyline = 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);
EditOperation op = new EditOperation();
op.Name = "Change annotation angle";
op.Modify(annoLayer, oid, rotatedPolyline);
op.Execute();
}
}
}
});
await QueuedTask.Run(() =>
{
var rc = annoLayer.GetTable().Search();
rc.MoveNext();
var af = rc.Current as AnnotationFeature;
var graphic = af.GetGraphic();
var textGraphic = graphic as CIMTextGraphic;
//Note:
//var outline_geom = af.GetGraphicOutline();
//gets the anno text outline geometry...
af.Dispose();
rc.Dispose();
});
await QueuedTask.Run(() =>
{
EditOperation op = new EditOperation();
op.Name = "Change annotation graphic";
//At 2.1 we must use an edit operation Callback...
op.Callback(context =>
{
QueryFilter qf = new QueryFilter()
{
WhereClause = "OBJECTID = 1"
};
//Cursor must be non-recycling. Use the table ~not~ the layer..i.e. "GetTable().Search()"
//annoLayer is ~your~ Annotation layer
using (var rowCursor = annoLayer.GetTable().Search(qf, false))
{
if (rowCursor.MoveNext())
{
using (var annoFeature = rowCursor.Current as ArcGIS.Core.Data.Mapping.AnnotationFeature)
{
//Get the graphic from the anno feature
var graphic = annoFeature.GetGraphic();
var textGraphic = graphic as CIMTextGraphic;
// change the text and the color
textGraphic.Text = "hello world";
var symbol = textGraphic.Symbol.Symbol;
symbol.SetColor(ColorFactory.Instance.RedRGB);
textGraphic.Symbol = symbol.MakeSymbolReference();
// update the graphic
annoFeature.SetGraphic(textGraphic);
// store is required
annoFeature.Store();
//refresh layer cache
context.Invalidate(annoFeature);
}
}
}
}, annoLayer.GetTable());
op.Execute();
});
var annoLayer = MapView.Active.Map.GetLayersAsFlattenedList()
.OfType<AnnotationLayer>().FirstOrDefault();
if (annoLayer == null)
return;
QueuedTask.Run(() =>
{
//get the first annotation feature...
//...assuming at least one feature gets selected
var rc = annoLayer.GetFeatureClass().Search();
rc.MoveNext();
var af = rc.Current as AnnotationFeature;
var outline_geom = af.GetGraphicOutline();
//TODO - use the outline...
//Note:
//var graphic = annoFeature.GetGraphic();
//gets the CIMTextGraphic...
af.Dispose();
rc.Dispose();
});
var annoLayer = MapView.Active.Map.GetLayersAsFlattenedList()
.OfType<AnnotationLayer>().FirstOrDefault();
if (annoLayer == null)
return;
var mv = MapView.Active;
QueuedTask.Run(() =>
{
//get the first annotation feature...
//...assuming at least one feature gets selected
var rc = annoLayer.GetFeatureClass().Search();
rc.MoveNext();
var oid = 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 scale
var mask_geom = annoLayer.QueryDrawingOutline(oid, mv, DrawingOutlineType.Exact);
rc.Dispose();
});
Home | API Reference | Requirements | Download | Samples