About updating geometry of existing features
Updating and editing geometry of existing features is a main function of the editor. Most of the tools and commands in the user interface (UI) that work with the geometry of features derive their functionality from interfaces in the Editor, Geometry and Geodatabase libraries. Before working with geometry in the Editor application programming interface (API), you should have a basic knowledge of how geometry is represented in ArcGIS as well as the common interfaces used to create and modify geometry. For more information on working with geometry in ArcGIS, see Working with geometry.
Most edits or updates to the geometry of features in the Editor API fall into the following three categories:
- Moving whole features to a different location
- Replacing features with a new geometry
- Modifying part of an existing geometry
Accessing feature geometry
Accessing individual features can be done through spatial or attribute queries using geodatabase cursors or using the editor's selection. For information on searching and returning features via cursors, see Querying geodatabase tables. For information on using cursors to query and update data in an editing context, see Updating attributes of existing features.
You can also reference the set of selected features in the map through the editor via IEditor.EditSelection, returning an enumeration of features, IEnumFeature. As with cursors, you can iterate through this collection to return individual features. However, the selection can contain features from more than one layer, and you should take measures to handle this possibility.
Once you obtain a reference to IFeature (a feature), its geometry is returned via IFeature.Shape as an IGeometry. If you are unsure of the geometry type that will be returned, query IFeature.Shape.GeometryType beforehand.
All updates to geometry should take place within an edit operation bounded by IEditor.StartOperation and IEditor.StopOperation.
Moving features
Simple features and most geometry types can be moved or rotated using the ITransform2D interface. To use this interface, cast the geometry you want to move to the ITransform2D interface, then call the Move or MoveVector method with parameters to perform the transform. If you are moving or rotating a simple feature, such as a polygon or point, you will need to commit the modified geometry back to the row by calling IFeature.Store (derived from IRow.Store), and update the display as necessary.
The following code moves a feature a distance of three units to the right:
[C#]
ITransform2D trans2D = IFeature.Shape as ITransform2D;
double dx = 0;
double dy = 3;
trans2D.Move(dx, dy);
IFeature.Store();
[VB.NET]
Dim trans2D As ITransform2D = TryCast(IFeature.Shape, ITransform2D)
Dim dx As Double = 0
Dim dy As Double = 3
trans2D.Move(dx, dy)
IFeature.Store()
You can move features or geometries from known from and to points using the ITransform2D.MoveVector method with an ILine parameter. While constructing the ILine, you can use snapping to set the from and to points to enable a feature to move and snap to a specific location. The MoveVector method can also take an ILine with a different spatial reference than the feature. For more information on snapping, see Working with the ArcGIS snapping environment.
The previous code example shows how to move whole features, but ITransformation2D can also be used to move any given geometry including segments, vertices, and graphics. This is discussed further in the Modifying parts of a geometry section.
Moving a set of features
To move or rotate a set of features, in particular a feature that participates in a geometric network or topology, use the methods on the IFeatureEdit2 interface. Using the MoveSet or RotateSet method on this interface ensures that connectivity rules are maintained.
Replacing features
Sometimes it may be easier, or even necessary, to replace the whole geometry of a feature rather than modify an individual element within it. In this case, simply recreate the geometry following the procedures in the geometry topics to create an IGeometry object.
Modifying parts of a geometry
If you only need to modify a portion of a features geometry such as vertex location or a segment, you can again use the procedures in the Geometry library to access the specific element you want to modify and make the appropriate edit. For examples and workflows, see How to modify a specific vertex of a polyline and How to modify a specific segment of a polyline.
Using the edit sketch
The edit sketch can be used to both edit the geometry of a feature and provide the geometry for feature edits. For example, to edit the vertices of a feature, you can load the feature geometry into the edit sketch (IEditSketch3.Geometry) and use its properties and methods to perform the edits. Once you've finished the edits, replace the feature geometry with the edit sketch geometry. For more information, see Working with the edit sketch.
Many geometry operations, such as IPolyLine.Reshape, take a geometry as an input parameter. You can use an edit sketch geometry (assuming the user has created a sketch) to supply the geometry for this method.
Setting and storing geometry
Once you've modified or recreated the geometry for a feature, use the IFeature.Shape property to store the completed geometry. The feature is not written to the database until the IFeature.Store method has been called. Once Store has been called, all subsequent queries in the same edit session, using the Geodatabase API, reflect the modified state of the feature.
Updating and managing z-values
Z-values typically represent elevations or heights and can be used to display features in three-dimension. Each vertex of a feature can store a z-value and its x,y positional information.
While the ArcMap editing environment is two-dimensional, it provides the ability to input, edit, and maintain z-values. The editor supports capabilities to assign z-values from various sources and snap to existing features based on x,y,z coordinate values.
The behavior of the editor when creating or modifying features with z values depends on the properties established in the editors z environment. This is available on the IEditorZ and ISnapEnvironment2 interfaces. IEditorZ supports most of the properties to manipulate and define the methods used to assign z-values to new vertices.
The following code example shows how to access the editor's z-handling methods:
[C#]
UIDClass edUID = new UIDClass();
edUID.Value = "esriEditor.Editor";
editor = m_application.FindExtensionByCLSID(edUID)as IEditor;
IEditorZ editorZ = m_editor as IEditorZ;
[VB.NET]
Dim edID = New UID
m_editor = m_application.FindExtensionByCLSID(edID)
Dim editorZ As IEditorZ
editorZ = m_editor
Assigning z-values
The method used to assign z-values to features is determined by the order of priorities based on settings used by the editing environment and the general function the editing tool or command performs. Using these factors, a predictable model of assignment can be developed. How these assignments come together also depends on the editing action performed. The following is the general hierarchy and description of z-assignment methods:
- Maintain or apply existing z-values—When assigning z-values while editing, determine if it is appropriate for existing z-values to be maintained when editing a feature or creating a feature. For example, when an existing feature is rotated, scaled, spatially adjusted, or moved, or a new feature is created by copying and pasting from an existing feature, these actions are performed without adding or deleting vertices. While the x,y values can change, z-values are not changed. If a feature has existing z-values, the editor maintains them where appropriate.
- Obtain z-values by snapping to existing features—When it is not practical to use existing z-values, determine if snapping in z should occur. If there is an existing feature with z-values to snap to and it's within the z-snapping tolerance, assignment of z-values by snapping overrides other z-assignment behavior. Z-snapping requires that at least one x,y snap agent (vertex, edge, or end) be enabled for the layer. In addition, set a z-snap tolerance other than 0 (default value) for z-snapping to occur. Z-tolerance is used in conjunction with the x,y snap tolerance to describe a cylinder that determines if snap conditions are met in x,y, and z.
- Use one of three z-capture types or modes—In addition to using existing z-values and obtaining new z-values through snapping, z-assignment comes from one of the following z-capture types (also known as z-modes):
- CurrentZ (Assigning z-values based on a specific value)
- InterpolateZ (Assigning z-values based on interpolation or extrapolation
- SurfaceZ (Assigning z-values using a surface)
With CurrentZ, vertices are assigned the current z-value as specified programmatically or in the current z-control. A CurrentZ value always exists, with 0 as the default. CurrentZ is useful when elevations are constant, such as when sketching a bridge or overpass in a road network. The bridge has a known height above the surface that is typically constant over its length.
Interpolate mode is the second method for z-assignment, where vertices are assigned z-values interpolated (or extrapolated) from known z-values of existing features. In some cases, there are no values available to interpolate from; therefore, resulting z-values fall back to the CurrentZ value since it always exists. Interpolate mode can be useful to connect points with known x,y,z locations but lack the specific z-values between the points. Interpolate mode is also useful when reshaping existing features.
Surface mode is the third method, which allows vertices to be assigned z-values obtained from the cells or faces of a specified surface. The surface can be any type that implements IFuntionalSurface, including triangulated irregular networks (TINs), rasters, and terrains. When you have a relatively high-resolution surface available, surface mode is useful in most editing scenarios, such as creating features and editing existing features.
To ensure the feature fits the underlying surface more accurately, turn on draping, which automatically creates intermediate vertices at each change in elevation defined by the surface. Draping allows the segments in the sketch to more closely fit the underlying surface.
If you are capturing using an accurate surface with draping enabled to fit the feature to the underlying surface, use the DrapingTolerance to limit the number of vertices added to the edit sketch. Draping is not the same as stream mode digitizing, which also automatically adds vertices to a sketch. Draping considers the elevation differences within a segment when determining whether to create a vertex; therefore, vertices cannot be placed at an equal interval as they would be with stream mode digitizing. When z-snapping occurs, draping does not occur. Only points added through the draping process are removed as part of this process; any points explicitly added to the edit sketch are maintained.
To ensure the feature fits the underlying surface more accurately, turn on draping, which automatically creates intermediate vertices at each change in elevation defined by the surface. Draping allows the segments in the sketch to more closely fit the underlying surface.
If you are capturing using an accurate surface with draping enabled to fit the feature to the underlying surface, use the DrapingTolerance to limit the number of vertices added to the edit sketch. Draping is not the same as stream mode digitizing, which also automatically adds vertices to a sketch. Draping considers the elevation differences within a segment when determining whether to create a vertex; therefore, vertices cannot be placed at an equal interval as they would be with stream mode digitizing. When z-snapping occurs, draping does not occur. Only points added through the draping process are removed as part of this process; any points explicitly added to the edit sketch are maintained.
The following code example shows how to determine the z-capture type and sets up properties for draping the sketch on the surface:
[C#]
private void SetDrapeProperties()
{
// If the capture is surface, set up draping properties.
if (editorZ.ZCaptureType == esriZCaptureType.esriCaptureSurfaceZ)
{
editorZ.Draping = true;
editorZ.UseZDrapingTolerance = true;
editorZ.ZDrapingTolerance = 2;
}
}
[VB.NET]
Private Sub SetDrapeProperties()
If editorZ.ZCaptureType = esriZCaptureType.esriCaptureSurfaceZ Then
editorZ.Draping = True
editorZ.UseZDrapingTolerance = True
editorZ.ZDrapingTolerance = 2
End If
End Sub
For more information on z-capture types, see esriZCaptureType Constants.
Handling invalid z-values
Sometimes, there is no z-value defined for vertices. This can occur when the surface used for capture is unavailable, the point is outside the surface's extent, or a vertex is inserted programmatically, and its z-value is not specified. The geodatabase does not support not a number (NaN) values for z-values. If the geometry is committed to the geodatabase, a failure returns. To avoid this, the editor performs the following to ensure contained z-values are valid before committing the edit sketch:
-
Checks if the geometry is z-aware. If it is not z-aware, the geometry's z-aware property is set to true.
-
Checks if any vertex's z-value is considered non-simple (that is, NaN).
-
If the geometry has a non-simple z-value and a class implementing INotifyZFinalize is registered with the editor, the geometry is passed to the class to handle the non-simple z-values.
-
The editor checks the geometry a second time for non-simple z-values.
-
If non-simple z-values are still present, IZ.CalculateNonSimpleZs is called.
As a developer, you can handle these cases before the editor. The editor provides a callback mechanism with which you can register to intercept these cases, query the offending geometry, and optionally correct the invalid z-values.
To receive this notification, your class must implement INotifyZFinalize and set a reference to your class in the editor by IEditorZ.NotifyZFinalize. Before the edit sketch is committed, the editor notifies your class and provides a reference to the offending geometry. Query the geometry to determine the problem and optionally, correct the geometry. If you do modify the geometry, set the Boolean flag to true to notify the editor that you have addressed the issue. If your extension returns true, the editor will not check the geometry to ensure its validity again.
Only one extension receives these events. When an extension attempts to register with the callback, the existing extension is replaced. To minimize potential conflicts, verify another extension has registered with the editor before registering your extension.
Snapping using z-values
The editor snap environment supports additional behavior for feature snap agents whose feature class supports z-values. When paired with one of the x,y hit types—for example, vertex, end, and edge—this supports x,y,z snapping. See the following code example:
[C#]
private void SetZSnapping(IEditor editor)
{
ISnapEnvironment2 snapEnv = editor as ISnapEnvironment2;
if (snapEnv == null)
return ;
// Set general snapping environment information.
snapEnv.UseSnapZTolerance = true;
snapEnv.SnapZTolerance = 3;
IFeatureSnapAgent2 featureSnap = null;
IField field = null;
IGeometryDef geomDef = null;
IFeatureClass featureClass = null;
// Iterate each feature snap agent. If the underlying feature class
// supports z-values, enable snapping to z-values.
for (int i = 0; i < snapEnv.SnapAgentCount; i++)
{
featureSnap = snapEnv.get_SnapAgent(i)as IFeatureSnapAgent2;
if (featureSnap != null)
{
featureClass = featureSnap.FeatureClass;
field = featureClass.Fields.get_Field(featureClass.FindField
(featureClass.ShapeFieldName));
geomDef = field.GeometryDef;
if (geomDef.HasZ)
{
featureSnap.ZSnappingEnabled = true;
}
}
}
}
[VB.NET]
Private Sub SetZSnapping(ByVal editor As IEditor)
Dim snapEnv As ISnapEnvironment2 = editor As ISnapEnvironment2
If snapEnv Is Nothing Then
Return
End If
' Set general snapping environment information.
snapEnv.UseSnapZTolerance = True
snapEnv.SnapZTolerance = 3
Dim featureSnap As IFeatureSnapAgent2 = Nothing
Dim field As IField = Nothing
Dim geomDef As IGeomeTryDef = Nothing
Dim featureClass As IFeatureClass = Nothing
' Iterate each feature snap agent. If the underlying feature class
' supports z-values, enable snapping to z-values.
Dim i As Integer
For i = 0 To snapEnv.SnapAgentCount - 1 Step i + 1
featureSnap = snapEnv.get_SnapAgentCType(As IFeatureSnapAgent2, i)
If Not featureSnap Is Nothing Then
featureClass = featureSnap.FeatureClass
field = featureClass.Fields.get_Field
(featureClass.FindField(featureClass.ShapeFieldName))
geomDef = field.GeomeTryDef
If geomDef.HasZ Then
featureSnap.ZSnappingEnabled = True
End If
End If
Next
End Sub
Development licensing | Deployment licensing |
---|---|
ArcGIS for Desktop Advanced | ArcGIS for Desktop Advanced |
ArcGIS for Desktop Standard | ArcGIS for Desktop Standard |
ArcGIS for Desktop Basic | ArcGIS for Desktop Basic |