ArcGIS SDK  

Extending ArcObjects

Difference Command Example

In this section:

  1. The case for a difference command
  2. Creating an editor command
  3. Creating the DifferenceCommand

Difference command example

Example Code Click here.

Description This project provides a custom editor command that will perform a difference operation on the two features currently selected in a layer being edited. The result is applied to the geometry of the first feature, and the second feature is deleted. The command will appear on the Editor menubar.

Design Coclass DifferenceCommand is a subtype of the Command abstract class and also sinks the IEditEvents interface.

License required ArcEditor or above

Libraries Carto, Editor, Framework, Geodatabase, Geometry, System, and SystemUI

Languages Visual Basic

Categories ESRI Mx Commands

Interfaces ICommand, IEditEvents

How to use

    1. Register the DifferenceCommandVB.dll and double-click the DifferenceCommandVB.reg file to register to component categories.
    2. Open ArcMap, click Tools, then click Customize.
    3. In the Customize dialog box, choose the Commands tab and click on 'Extending ArcObjects' in the left-hand Categories list.
    4. In the Commands list, choose the Difference command, and drag this onto the Editor menu below the existing Clip command. Click Close to dismiss the Customize dialog box.
    5. Add data with polygon features to ArcMap.
    6. Click on Editor and click Start Editing. Make sure that the polygon layer you added is editable and is the target layer.
    7. Select two overlapping polygon features, or alternatively, use the Editor tools and commands to create some overlapping features.
    8. Click on Editor and click Difference.

      The two features you selected will be combined into one feature with the overlapping area removed.


The case for a difference command

The standard Editor menu provides a number of spatial operations that can be applied to multiple features, for example, Union, Intersect, and Clip. However, if you want to merge two features into one feature, but remove the overlapping area (the area that intersects), there is no command available to allow you to do this operation in one step.

As no editor command provides the operation you require, you will create a custom editor command to meet your requirements by performing a difference operation.

This example demonstrates how to create an editor command to perform a difference operation on two features.


Creating an editor command

The previous topic, Editor Commands and Tools discussed how most Editor commands are implemented as a subtype of Command by implementing the ICommand interface. Most editor commands also sink the IEditEvents outbound interface from the Editor coclass, to respond to editing events.



Creating the DifferenceCommand

You can easily solve your requirements with a custom command that is similar to the Union, Intersect, and Clip commands. A custom command is appropriate here because you can rely on another tool like the Edit tool to make the selection beforehand, and your command will deal strictly with the task of performing the difference operation and setting the geometry of the feature to be the result of the operation.

You will create a subtype of Command called DifferenceCommand by implementing ICommand. and sinking the IEditEvents outbound interface from the Editor coclass.


Implementing ICommand

Begin by implementing OnCreate, where you will store references to the Application and Editor objects in the ArcMap application.

[Visual Basic 6]
Private m_pApp As esriFramework.IApplication
Private m_pEditor As esriEditor.IEditor
Private m_pEditLayers As esriEditor.IEditLayers
  
Private Sub ICommand_OnCreate(ByVal hook As Object)
  Dim pID As New esriSystem.UID
  pID = "esriEditor.Editor"
  Set m_pApp = hook
  Set m_pEditor = m_pApp.FindExtensionByCLSID(pID)
  
  If Not m_pEditor Is Nothing Then
    Set m_pEditLayers = m_pEditor
  End If
End Sub

To complete the enabled property, add a member variable m_bEnabled and return its value; you will set this value later when implementing IEditEvents.

[Visual Basic 6]
Private m_bEnabled As Boolean
  
Private Property Get ICommand_Enabled() As Boolean
  ICommand_Enabled = m_bEnabled ' Check private member
End Property

Now you can perform the difference operation in the OnClick member using the variables you stored in OnCreate.

[Visual Basic 6]
Private Sub ICommand_OnClick()
  On Error GoTo ErrorHandler:
  
  Dim pTopoOp As ITopologicalOperator
  Dim pGeoResult As IGeometry
  Dim pActiveView As IActiveView
  
  ' Start an edit operation
  m_pEditor.StartOperation
  
  ' Do the difference
  Set pTopoOp = m_pFeature1.Shape
  Set pGeoResult = pTopoOp.SymmetricDifference(m_pFeature2.Shape)
  
  If pGeoResult Is Nothing Then GoTo ErrorHandler
  
  ' Delete the second feature and reset feature_1's shape
  m_pFeature2.Delete
  Set m_pFeature1.Shape = pGeoResult
  m_pFeature1.Store
  
  ' Complete the operation and redraw new feature and selection
  m_pEditor.StopOperation "Difference"
  m_pEditor.Display.Invalidate m_pFeature1.Extent, True, 0
  Set pActiveView = m_pEditor.Map
  pActiveView.PartialRefresh esriViewGeoSelection, Nothing, Nothing
  
Exit Sub ' Exit sub to avoid error handler
ErrorHandler:
  'In the event of an error, abort the operation
  m_pEditor.AbortOperation
  MsgBox "Difference command failed."
End Sub

Editor commands are usually displayed as a caption only, so you do not need to return anything from the Bitmap member.

Implementing IEditEvents

By listening to the events on the IEditEvents interface, you can control access to your command. Commands are often not enabled until a specific set of criteria is met; in this case, you can write the command so that it is only enabled when the end user has selected two polygon features and set the target layer to a layer containing polygon features.

The best method for enabling a command based on selection criteria is to establish the command as an edit events client responding specifically to IEditEvents::OnSelectionChanged and IEditEvents::OnCurrentLayerChanged.

  1. Begin by sinking the default interface of the Editor coclass, IEditEvents, in your class.
    [Visual Basic 6]
    Private WithEvents EditorEvents As esriEditor.Editor
  2. Add a line to the ICommand::OnCreate method to start listening to the events.
    [Visual Basic 6]
    Private Sub ICommand_OnCreate(ByVal hook As Object)
      ...
      If Not m_pEditor Is Nothing Then
        Set m_pEditLayers = m_pEditor
        ' Respond to IEditEvents interface.
        Set EditorEvents = m_pEditor
      End If
    End Sub
  3. Create a function called SetEnabledStatus. In this function you need to verify that the user has selected only two valid polygon features and has set the current target layer to a polygon feature class.
    [Visual Basic 6]
    Private Sub SetEnabledStatus()
      Dim pEnumFeat As esriGeodatabase.IEnumFeature
      
      ' Assume command should not be enabled
      m_bEnabled = False
      
      ' Make sure the current layer exists. When ArcMap is shutting down,
      ' the Editor fires various events, some of which we are listening to,
      ' but the Editor's properties have likely been emptied at this point.
      If m_pEditLayers.CurrentLayer Is Nothing Then Exit Sub
      
      ' Check the target layer geometry type
      If m_pEditLayers.CurrentLayer.FeatureClass.ShapeType = esriGeometryPolygon Then
        ' Analyze the Editor's selection
        If m_pEditor.SelectionCount = 2 Then
          Set pEnumFeat = m_pEditor.EditSelection
          pEnumFeat.Reset
          Set m_pFeature1 = pEnumFeat.Next
          If m_pFeature1.Shape.IsEmpty Then Exit Sub
          Set m_pFeature2 = pEnumFeat.Next
          If m_pFeature2.Shape.IsEmpty Then Exit Sub
          
          ' If both features are polygons, enable the command
          If m_pFeature1.Shape.GeometryType = esriGeometryPolygon And _
           m_pFeature2.Shape.GeometryType = esriGeometryPolygon Then
            m_bEnabled = True
            Exit Sub
          End If
          
        End If
      End If
    End Sub
  4. Then implement the OnSelectionChanged and OnCurrentLayerChanged members of IEditEvents, and call the SetEnabledStatus function from these members to set the Enabled status.
    [Visual Basic 6]
    Private Sub EditorEvents_OnCurrentLayerChanged()
      SetEnabledStatus
    End Sub
      
    Private Sub EditorEvents_OnSelectionChanged()
      SetEnabledStatus
    End Sub

Now you can compile the DifferenceCommand project and use it in an ArcMap edit session.

 


Back to top

Go to example code.

See Also Editor Commands And Tools, and Split At Intersection Tool Example.