-
Notifications
You must be signed in to change notification settings - Fork 119
ProGuide Editing tool
Language: C# and Visual Basic
Subject: Editing
Contributor: ArcGIS Pro SDK Team <arcgisprosdk@esri.com>
Organization: Esri, http://www.esri.com
Date: 11/6/2017
ArcGIS Pro: 2.1
Visual Studio: 2015, 2017
This ProGuide shows how to build an editing tool to interact with and modify existing features. The code used to illustrate this add-in can be found at Sketch Tool Demo Sample.
Prerequisite
Create a new add-in, and add a map tool to the add-in called CutTool.cs
.
Step 1
In the constructor, change the SketchType
of the map tool to a line geometry type. This is the geometry of the map tool feedback used to symbolize the user interaction. For this example, you're using a single solid line that adds a linear segment on each mouse click.
// select the type of tool feedback you wish to implement.
SketchType = SketchGeometryType.Line;
// a sketch feedback is needed
IsSketchTool = true;
// the geometry is needed in map coordinates
SketchOutputMode = ArcGIS.Desktop.Mapping.SketchOutputMode.Map;
Step 2
Replace the code in the OnSketchCompleteAsync
method. Assign a method to modify features in the editor, and, since the API calls need to happen on the CIM thread, use a lambda function to handle the operation using the sketch geometry. For now, you simply declare the method. You will specify the code in step 4.
protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
return QueuedTask.Run(() => ExecuteCut(geometry));
}
protected Task<bool> ExecuteCut(Geometry geometry)
{
return Task.FromResult(true);
}
Step 3
Open the Config.daml
file and go to the entry for the tool. Add a categoryRefID
attribute setting it to categoryRefID="esri_editing_CommandList"
. This specifies the tool is to appear in the Modify Features pane. Also add the content
xml node to the tool specification. The attribute L_group
creates an entry in the pane with the specified name. The tool daml should be as below
<tool id="ProAppModule1_CutTool" categoryRefID="esri_editing_CommandList"
caption="CutTool" className="CutTool" loadOnClick="true"
smallImage="Images\GenericButtonRed16.png"
largeImage="Images\GenericButtonRed32.png">
<tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
<content L_group="Pro SDK Samples" gallery2d="true" gallery3d="false" />
</tool>
The attributes gallery2d
and gallery3d
specify whether the tool is automatically added to the gallery for 2D or 3D editing tools on the Edit ribbon. In this guide, you'll add the tool to the 2D gallery.
The modified xml configuration for the editing tool should look similar to the following definition:
<tool id="ProAppModule1_CutTool" categoryRefID="esri_editing_CommandList"
caption="CutTool" className="CutTool" loadOnClick="true"
smallImage="Images\GenericButtonRed16.png"
largeImage="Images\GenericButtonRed32.png">
<tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
<content L_group="Pro SDK Samples" gallery2d="true" gallery3d="false" />
</tool>
Step 4
Go back to the CutTool.cs
file and add the following code to the ExecuteCut
method. Since you're performing an edit, create a new instance of an EditOperation
to scope the modifies. See EditOperation in the ProConcept documentation to learn about its functionality.
// create an edit operation
EditOperation cutOperation = new EditOperation();
cutOperation.Name = "Cut Elements";
cutOperation.ProgressMessage = "Working...";
cutOperation.CancelMessage = "Operation canceled.";
cutOperation.ErrorMessage = "Error cutting polygons";
cutOperation.SelectModifiedFeatures = false;
cutOperation.SelectNewFeatures = false;
In the next step, you'll set up the target for the edit operation. For this example, you'll use the sketch geometry to perform a cut against all editable polygon features in the active map.
// create a collection of feature layers that can be edited
var editableLayers = ActiveMapView.Map.GetLayersAsFlattenedList()
.OfType<FeatureLayer>()
.Where(lyr => lyr.CanEditData() == true).Where(lyr =>
lyr.ShapeType == esriGeometryType.esriGeometryPolygon);
Step 5
For each identified target layer, do the following:
- Search for the features that are crossing the sketch geometry.
- Get the underlying feature class and determine the field index for the "Description" attribute field.
// for each of the layers
foreach (FeatureLayer editableFeatureLayer in editableLayers)
{
// find the features crossed by the sketch geometry
var rowCursor = editableFeatureLayer.Search(geometry, SpatialRelationship.Crosses);
// get the feature class associated with the layer
Table fc = editableFeatureLayer.GetTable();
// find the field index for the 'Description' attribute
int descriptionIndex = -1;
descriptionIndex = fc.GetDefinition().FindField("Description");
For each returned feature, test whether the feature is completely intersected by the sketch geometry by using the GeometryEngine.Instance.Relate
method. The string argument is detailed in the Dimensionally Extended Nine-Intersection Model.
If the geometry is completely intersected, store its ObjectID
in a list, and modify the Description attribute as part of the edit operation.
// add the feature IDs into our prepared list
while (rowCursor.MoveNext())
{
var feature = rowCursor.Current as Feature;
if (feature.GetShape() != null)
{
// we are looking for polygons are completely intersected by the cut line
if (GeometryEngine.Instance.Relate(geometry, feature.GetShape(), "TT*F*****"))
{
// add the current feature to the overall list of features to cut
cutOIDs.Add(rowCursor.Current.GetObjectID());
// adjust the attribute before the cut
if (descriptionIndex != -1)
cutOperation.Modify(rowCursor.Current, descriptionIndex, "Pro Sample");
}
}
}
Step 6
For every polygon layer, cue the cut for all the collected ObjectIDs. Once the code enumerates all the layers, execute the edit operation. Regardless of the number of modified features and polygon layers, there will be only one edit operation listed in the Undo/Redo stack for the active view.
// create an edit operation
EditOperation cutOperation = new EditOperation();
...
{
// for each layer perform the cut
...
// add the elements to cut into the edit operation
cutOperation.Cut(editableFeatureLayer, cutOIDs, geometry);
}
//execute the operation
var operationResult = cutOperation.Execute();
return Task.FromResult(operationResult);
Step 7
To emphasize the interactive operation, you may want to change the sketch symbol. You can influence the appearance of the sketch by overriding the OnSketchModifiedAsync
method. In this example, you'll change the style, width, and color of the line sketch after the second vertex.
protected override async Task<bool> OnSketchModifiedAsync()
{
// retrieve the current sketch geometry
Polyline cutGeometry = await base.GetCurrentSketchAsync() as Polyline;
await QueuedTask.Run(() =>
{
// if there are more than 2 vertices in the geometry
if (cutGeometry.PointCount > 2)
{
// adjust the sketch symbol
var symbolReference = base.SketchSymbol;
if (symbolReference == null)
{
var cimLineSymbol = SymbolFactory.Instance.ConstructLineSymbol(ColorFactory.Instance.RedRGB,
3, SimpleLineStyle.DashDotDot);
base.SketchSymbol = cimLineSymbol.MakeSymbolReference();
}
else
{
symbolReference.Symbol.SetColor(ColorFactory.Instance.RedRGB);
base.SketchSymbol = symbolReference;
}
}
});
return true;
}
Step 8
For the last step, you'll set up a custom action after the edit operation has successfully completed. Switch to the Module1.cs
file and override the Initialize
method for the add-in. Subscribe to the EditCompletedEvent
and define a callback method called ReportNumberOfRowsChanged
.
protected override bool Initialize()
{
// subscribe to the completed edit operation event
EditCompletedEvent.Subscribe(ReportNumberOfRowsChanged);
return true;
}
The callback method filters out the modifies that happened during the edit operation and reports the number of modifies back to the user.
/// <summary>
/// Method containing actions as the result of the EditCompleted (the operation) event.
/// This method reports the total number of changed rows/features.
/// </summary>
/// <param name="editArgs">Argument containing the layers where edits occurred and what
/// types of changes.</param>
/// <returns></returns>
private Task<bool> ReportNumberOfRowsChanged(EditCompletedEventArgs editArgs)
{
// get the dictionary containing the modifies on the current feature
// operation
var editChanges = editArgs.Modifies;
// use this variable to store the total number of modifies
int countOfModifies = editChanges.Values.Sum(list => list.Count);
if (countOfModifies > 0)
MessageBox.Show($"{countOfModifies.ToString()} features changed");
else
MessageBox.Show("The current edit operation did not contain any row/feature
modification.");
return Task.FromResult(true);
}
Home | API Reference | Requirements | Download | Samples
- Overview of the ArcGIS Pro SDK
- What's New for Developers at 3.4
- Installing ArcGIS Pro SDK for .NET
- Release notes
- Resources
- Pro SDK Videos
- ProSnippets
- ArcGIS Pro API
- ProGuide: ArcGIS Pro Extensions NuGet
Migration
- ProSnippets: Framework
- ProSnippets: DAML
- ProConcepts: Framework
- ProConcepts: Asynchronous Programming in ArcGIS Pro
- ProConcepts: Advanced topics
- ProGuide: Custom settings
- ProGuide: Command line switches for ArcGISPro.exe
- ProGuide: Reusing ArcGIS Pro Commands
- ProGuide: Licensing
- ProGuide: Digital signatures
- ProGuide: Command Search
- ProGuide: Keyboard shortcuts
Add-ins
- ProGuide: Installation and Upgrade
- ProGuide: Your first add-in
- ProGuide: ArcGIS AllSource Project Template
- ProConcepts: Localization
- ProGuide: Content and Image Resources
- ProGuide: Embedding Toolboxes
- ProGuide: Diagnosing ArcGIS Pro Add-ins
- ProGuide: Regression Testing
Configurations
Customization
- ProGuide: The Ribbon, Tabs and Groups
- ProGuide: Buttons
- ProGuide: Label Controls
- ProGuide: Checkboxes
- ProGuide: Edit Boxes
- ProGuide: Combo Boxes
- ProGuide: Context Menus
- ProGuide: Palettes and Split Buttons
- ProGuide: Galleries
- ProGuide: Dockpanes
- ProGuide: Code Your Own States and Conditions
Styling
- ProSnippets: Content
- ProSnippets: Browse Dialog Filters
- ProConcepts: Project Content and Items
- ProConcepts: Custom Items
- ProGuide: Custom Items
- ProGuide: Custom browse dialog filters
- ArcGIS Pro TypeID Reference
- ProSnippets: Editing
- ProConcepts: Editing
- ProConcepts: COGO
- ProConcepts: Annotation Editing
- ProConcepts: Dimension Editing
- ProGuide: Editing Tool
- ProGuide: Sketch Tool With Halo
- ProGuide: Construction Tools with Options
- ProGuide: Annotation Construction Tools
- ProGuide: Annotation Editing Tools
- ProGuide: Knowledge Graph Construction Tools
- ProGuide: Templates
3D Analyst Data
Plugin Datasources
Topology
Linear Referencing
Object Model Diagram
- ProSnippets: Geometry
- ProSnippets: Geometry Engine
- ProConcepts: Geometry
- ProConcepts: Multipatches
- ProGuide: Building Multipatches
Relational Operations
- ProSnippets: Knowledge Graph
- ProConcepts: Knowledge Graph
- ProGuide: Knowledge Graph Construction Tools
Reports
- ProSnippets: Map Authoring
- ProSnippets: Annotation
- ProSnippets: Charts
- ProSnippets: Labeling
- ProSnippets: Renderers
- ProSnippets: Symbology
- ProSnippets: Text Symbols
- ProConcepts: Map Authoring
- ProConcepts: Annotation
- ProConcepts: Dimensions
- ProGuide: Tray buttons
- ProGuide: Custom Dictionary Style
- ProGuide: Geocoding
3D Analyst
CIM
Graphics
Scene
Stream
Voxel
- ProSnippets: Map Exploration
- ProSnippets: Custom Pane with Contents
- ProConcepts: Map Exploration
- ProGuide: Map Pane Impersonation
- ProGuide: TableControl
Map Tools
- ProGuide: Feature Selection
- ProGuide: Identify
- ProGuide: MapView Interaction
- ProGuide: Embeddable Controls
- ProGuide: Custom Pop-ups
- ProGuide: Dynamic Pop-up Menu
Network Diagrams
- ArcGIS Pro API Reference Guide
- ArcGIS Pro SDK (pro.arcgis.com)
- arcgis-pro-sdk-community-samples
- ArcGISPro Registry Keys
- ArcGIS Pro DAML ID Reference
- ArcGIS Pro Icon Reference
- ArcGIS Pro TypeID Reference
- ProConcepts: Distributing Add-Ins Online
- ProConcepts: Migrating to ArcGIS Pro
- FAQ
- Archived ArcGIS Pro API Reference Guides
- Dev Summit Tech Sessions