//Using Inspector... internal async void UpdateTextString() { BasicFeatureLayer annoLayer = MapView.Active.Map.GetLayersAsFlattenedList().First() as BasicFeatureLayer; var oid = 1; #region 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 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(); } }); #endregion #region 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 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(); } } } }); #endregion #region Change Annotation Text Graphic 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(); }); #endregion }
protected override async Task OnToolActivateAsync(bool active) { // get the Precincts feature layer in the active map _pointLayer = ActiveMapView.Map.GetLayersAsFlattenedList().OfType <FeatureLayer>(). Where(lyr => lyr.Name == "Police Stations").FirstOrDefault(); if (_pointLayer == null) { return; } // build the attribute dictionaries _attributesValid = new Dictionary <string, bool>(); _attributes = new Dictionary <string, object>(); // get the embedded control if (_attributeVM == null) { _attributeVM = this.EmbeddableControl as AttributeControlViewModel; } // these are the fields that we will collect values from the user var fieldNames = new List <string>() { "Precinct", "Address" }; // set up the inspector var inspector = new Inspector(); foreach (var fieldName in fieldNames) { // add the attribute ArcGIS.Desktop.Editing.Attributes.Attribute attr = await inspector.AddAttributeAsync(_pointLayer, fieldName, false); // set the validity to true _attributesValid.Add(fieldName, true); // add some validation - in this example we will make each field mandatory attr.AddValidate(() => { var errors = new List <ArcGIS.Desktop.Editing.Attributes.Attribute.ValidationError>(); if (string.IsNullOrWhiteSpace(attr.CurrentValue.ToString())) { // add an error errors.Add(ArcGIS.Desktop.Editing.Attributes.Attribute.ValidationError.Create("Value is mandatory", ArcGIS.Desktop.Editing.Attributes.Severity.High)); // set the validity to false _attributesValid[fieldName] = false; } else { // store the value if (!_attributes.ContainsKey(fieldName)) { _attributes.Add(fieldName, attr.CurrentValue); } else { _attributes[fieldName] = attr.CurrentValue; } // set the validity to true _attributesValid[fieldName] = true; } return(errors); }); } // create the embedded control and assign the view/viewmodel pair var tuple = inspector.CreateEmbeddableControl(); _attributeVM.InspectorViewModel = tuple.Item1; _attributeVM.InspectorView = tuple.Item2; }
protected async void Button_Click(object sender, RoutedEventArgs e) { gesture = new List <Point>(); sketchPad.Children.Clear(); try { BasicFeatureLayer layer = null; List <Inspector> inspList = new List <Inspector>(); Inspector inspector = null; await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => { //find selected layer if (MapView.Active.GetSelectedLayers().Count == 0) { //MessageBox.Show("Select a feature class from the Content 'Table of Content' first."); return; } layer = MapView.Active.GetSelectedLayers()[0] as BasicFeatureLayer; // get selected features from the map var features = layer.GetSelection(); if (features.GetCount() == 0) { return; /*ToDo : add error msg: no feature selected*/ } // get ids of all the selected features var featOids = features.GetObjectIDs(); if (featOids.Count == 0) {/* ToDo : something is wrong*/ } // adding the inspectors to a list so that separate id values can be assigned later for (int i = 0; i < featOids.Count; i++) { var insp = new Inspector(); insp.Load(layer, featOids.ElementAt(i)); inspList.Add(insp); } inspector = new Inspector(); inspector.Load(layer, featOids); }); if (layer == null) { } //MessageBox.Show("Unable to find a feature class at the first layer of the active map"); else { //update the attributes of those features // make sure tha attribute exists ArcGIS.Desktop.Editing.Attributes.Attribute att = inspector.FirstOrDefault(a => a.FieldName == "UID"); if (att == null) { // if the attribute doesn't exist we create a new field var dataSource = await GetDataSource(layer); //MessageBox.Show($@"{dataSource} was found ... adding a new Field"); await ExecuteAddFieldTool(layer, new KeyValuePair <string, string>("UID", "uniqueId"), "Text", 50); } await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => { // we add values of ids to the selected features for (int i = 0; i < inspList.Count; i++) { if (inspList.ElementAt(i)["UID"] == null || (String)inspList.ElementAt(i)["UID"] == String.Empty) { // putting a random string now, this should be replaced by the tag user puts in after the recognition part is done. inspList.ElementAt(i)["UID"] = "newAtr" + attributeIndex++; var op = new EditOperation(); op.Name = "Update"; op.SelectModifiedFeatures = true; op.SelectNewFeatures = false; op.Modify(inspList.ElementAt(i)); op.Execute(); } } /* var att2 = insp.Select(a => a.FieldName == "UID"); * var att3 = insp.GroupBy(a => a.FieldName == "UID"); * var att4 = insp.Any(a => a.FieldName == "UID"); * var att5 = insp.Where(a => a.FieldName == "UID")*/ //insp["UID"] = "newAtr"; }); } } catch (Exception ex) { //MessageBox.Show(ex.ToString()); } }