About the Cut polygons without selection edit task Sample
[C#]
CutPolygonsWithoutSelectionEditTask.cs
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Collections;
using System.Text;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
namespace CutPolygonsWithoutSelection_CS
{
[Guid("637BF886-E416-4bcc-92A5-C0E455739346")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("CutPolygonsWithoutSelection_CS.CutPolygonWithoutSelection")]
public class CutPolygonsWithoutSelectionEditTask : ESRI.ArcGIS.Controls.IEngineEditTask
{
#region Private Members
IEngineEditor m_engineEditor;
IEngineEditSketch m_editSketch;
IEngineEditLayers m_editLayer;
#endregion
#region COM Registration Function(s)
[ComRegisterFunction()]
[ComVisible(false)]
static void RegisterFunction(Type registerType)
{
// Required for ArcGIS Component Category Registrar support
ArcGISCategoryRegistration(registerType);
}
[ComUnregisterFunction()]
[ComVisible(false)]
static void UnregisterFunction(Type registerType)
{
// Required for ArcGIS Component Category Registrar support
ArcGISCategoryUnregistration(registerType);
}
#region ArcGIS Component Category Registrar generated code
/// <summary>
/// Required method for ArcGIS Component Category registration -
/// Do not modify the contents of this method with the code editor.
/// </summary>
private static void ArcGISCategoryRegistration(Type registerType)
{
string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
EngineEditTasks.Register(regKey);
}
/// <summary>
/// Required method for ArcGIS Component Category unregistration -
/// Do not modify the contents of this method with the code editor.
/// </summary>
private static void ArcGISCategoryUnregistration(Type registerType)
{
string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
EngineEditTasks.Unregister(regKey);
}
#endregion
#endregion
#region IEngineEditTask Implementations
public void Activate(ESRI.ArcGIS.Controls.IEngineEditor editor, ESRI.ArcGIS.Controls.IEngineEditTask oldTask)
{
if (editor == null)
return;
//Initialize class member variables.
m_engineEditor = editor;
m_editSketch = editor as IEngineEditSketch;
m_editSketch.GeometryType = esriGeometryType.esriGeometryPolyline;
m_editLayer = m_editSketch as IEngineEditLayers;
//Wire editor events.
((IEngineEditEvents_Event)m_editSketch).OnTargetLayerChanged += new IEngineEditEvents_OnTargetLayerChangedEventHandler(OnTargetLayerChanged);
((IEngineEditEvents_Event)m_editSketch).OnCurrentTaskChanged += new IEngineEditEvents_OnCurrentTaskChangedEventHandler(OnCurrentTaskChanged);
}
public void Deactivate()
{
//Stop listening for editor events.
((IEngineEditEvents_Event)m_engineEditor).OnTargetLayerChanged -= OnTargetLayerChanged;
((IEngineEditEvents_Event)m_engineEditor).OnCurrentTaskChanged -= OnCurrentTaskChanged;
//Release object references.
m_engineEditor = null;
m_editSketch = null;
m_editLayer = null;
}
public string GroupName
{
get
{
return "Modify Tasks";
}
}
public string Name
{
get
{
return "Cut Polygons Without Selection (C#)";
}
}
//This method is not expected to be fired since we have unregistered from the event in Deactivate
public void OnCurrentTaskChanged()
{
UpdateSketchToolStatus();
}
public void OnTargetLayerChanged()
{
UpdateSketchToolStatus();
}
public void OnDeleteSketch()
{
}
public void OnFinishSketch()
{
if (m_editSketch == null)
return;
bool hasCutPolygons = false;
//Change the cursor to be hourglass shape.
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
try
{
//Get the geometry that performs the cut from the edit sketch.
IGeometry cutGeometry = m_editSketch.Geometry;
//The sketch geometry is simplified to deal with a multi-part sketch as well
//as the case where the sketch loops back over itself.
ITopologicalOperator2 topoOperator = cutGeometry as ITopologicalOperator2;
topoOperator.IsKnownSimple_2 = false;
topoOperator.Simplify();
//Create the spatial filter to search for features in the target feature class.
//The spatial relationship we care about is whether the interior of the line
//intersects the interior of the polygon.
ISpatialFilter spatialFilter = new SpatialFilterClass();
spatialFilter.Geometry = m_editSketch.Geometry;
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
//Find the polygon features that cross the sketch.
IFeatureClass featureClass = m_editLayer.TargetLayer.FeatureClass;
IFeatureCursor featureCursor = featureClass.Search(spatialFilter, false);
//Only do work if there are features that intersect the edit sketch.
IFeature origFeature = featureCursor.NextFeature();
if (origFeature != null)
{
//Check the first feature to see if it is ZAware and if it needs to make the
//cut geometry ZAware.
IZAware zAware = origFeature.Shape as IZAware;
if (zAware.ZAware)
{
zAware = cutGeometry as IZAware;
zAware.ZAware = true;
}
ArrayList comErrors = new ArrayList();
//Start an edit operation so we can have undo/redo.
m_engineEditor.StartOperation();
//Cycle through the features, cutting with the sketch.
while (origFeature != null)
{
try
{
//Split the feature. Use the IFeatureEdit::Split method which ensures
//the attributes are correctly dealt with.
IFeatureEdit featureEdit = origFeature as IFeatureEdit;
//Set to hold the new features that are created by the Split.
ISet newFeaturesSet = featureEdit.Split(cutGeometry);
//New features have been created.
if (newFeaturesSet != null)
{
newFeaturesSet.Reset();
hasCutPolygons = true;
}
}
catch (COMException comExc)
{
comErrors.Add(String.Format("OID: {0}, Error: {1} , {2}",origFeature.OID.ToString(), comExc.ErrorCode,comExc.Message));
}
finally
{
//Continue to work on the next feature if it fails to split the current one.
origFeature = featureCursor.NextFeature();
}
}
//If any polygons were cut, refresh the display and stop the edit operation.
if (hasCutPolygons)
{
//Clear the map's selection.
m_engineEditor.Map.ClearSelection();
//Refresh the display including modified layer and any previously selected component.
IActiveView activeView = m_engineEditor.Map as IActiveView;
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeography | esriViewDrawPhase.esriViewGeoSelection, null, activeView.Extent);
//Complete the edit operation.
m_engineEditor.StopOperation("Cut Polygons Without Selection");
}
else
{
m_engineEditor.AbortOperation();
}
//report any errors that have arisen while splitting features
if (comErrors.Count > 0)
{
StringBuilder stringBuilder = new StringBuilder("The following features could not be split: \n", 200);
foreach (string comError in comErrors)
{
stringBuilder.AppendLine(comError);
}
MessageBox.Show(stringBuilder.ToString(), "Cut Errors");
}
}
}
catch (Exception e)
{
MessageBox.Show("Unable to perform the cut task.\n" + e.Message);
m_engineEditor.AbortOperation();
}
finally
{
//Change the cursor shape to default.
System.Windows.Forms.Cursor.Current = Cursors.Default;
}
}
public string UniqueName
{
get
{
return "CutPolygonsWithoutSelection_CS_CutPolygonsWithoutSelection_CSharp";
}
}
#endregion
#region IEngineEditTask private methods
private void UpdateSketchToolStatus()
{
if (m_editLayer == null)
return;
//Only enable the sketch tool if there is a polygon target layer.
if (m_editLayer.TargetLayer.FeatureClass.ShapeType != esriGeometryType.esriGeometryPolygon)
m_editSketch.GeometryType = esriGeometryType.esriGeometryNull;
else
//Set the edit sketch geometry type to be esriGeometryPolyline.
m_editSketch.GeometryType = esriGeometryType.esriGeometryPolyline;
}
#endregion
}
}
[Visual Basic .NET]
CutPolygonsWithoutSelectionEditTask.vb
Imports System.Runtime.InteropServices
Imports System.Windows.Forms
Imports System.Text
Imports System.Collections
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Controls
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.ADF
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.ADF.CATIDs
<ComClass(CutPolygonsWithoutSelectionEditTask.ClassId, CutPolygonsWithoutSelectionEditTask.InterfaceId, CutPolygonsWithoutSelectionEditTask.EventsId), _
ProgId("CutPolygonsWithoutSelection_VB.CutPolygonsWithoutSelectionEditTask")> _
Public Class CutPolygonsWithoutSelectionEditTask
Implements ESRI.ArcGIS.Controls.IEngineEditTask
#Region "COM Registration Function(s)"
<ComRegisterFunction(), ComVisibleAttribute(False)> _
Public Shared Sub RegisterFunction(ByVal registerType As Type)
' Required for ArcGIS Component Category Registrar support
ArcGISCategoryRegistration(registerType)
'Add any COM registration code after the ArcGISCategoryRegistration() call
End Sub
<ComUnregisterFunction(), ComVisibleAttribute(False)> _
Public Shared Sub UnregisterFunction(ByVal registerType As Type)
' Required for ArcGIS Component Category Registrar support
ArcGISCategoryUnregistration(registerType)
'Add any COM unregistration code after the ArcGISCategoryUnregistration() call
End Sub
#Region "ArcGIS Component Category Registrar generated code"
''' <summary>
''' Required method for ArcGIS Component Category registration -
''' Do not modify the contents of this method with the code editor.
''' </summary>
Private Shared Sub ArcGISCategoryRegistration(ByVal registerType As Type)
Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
EngineEditTasks.Register(regKey)
End Sub
''' <summary>
''' Required method for ArcGIS Component Category unregistration -
''' Do not modify the contents of this method with the code editor.
''' </summary>
Private Shared Sub ArcGISCategoryUnregistration(ByVal registerType As Type)
Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
EngineEditTasks.Unregister(regKey)
End Sub
#End Region
#End Region
#Region "COM GUIDs"
' These GUIDs provide the COM identity for this class
' and its COM interfaces. If you change them, existing
' clients will no longer be able to access the class.
Public Const ClassId As String = "3d0e1daf-d468-4137-8955-1956cbc8da28"
Public Const InterfaceId As String = "4cec67ad-3d4b-427f-8de8-84566d54fd27"
Public Const EventsId As String = "3df03882-7c31-48df-af15-042a0541124a"
#End Region
' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
End Sub
#Region "Private Members"
Private m_engineEditor As IEngineEditor
Private m_editSketch As IEngineEditSketch
Private m_editLayer As IEngineEditLayers
#End Region
Public Sub Activate(ByVal editor As ESRI.ArcGIS.Controls.IEngineEditor, ByVal oldTask As ESRI.ArcGIS.Controls.IEngineEditTask) Implements ESRI.ArcGIS.Controls.IEngineEditTask.Activate
If editor Is Nothing Then
Return
End If
'Initialize class member variables.
m_engineEditor = editor
m_editSketch = DirectCast(editor, IEngineEditSketch)
m_editSketch.GeometryType = esriGeometryType.esriGeometryPolyline
m_editLayer = DirectCast(m_editSketch, IEngineEditLayers)
'Wire editor events.
AddHandler CType(m_editSketch, IEngineEditEvents_Event).OnTargetLayerChanged, AddressOf OnTargetLayerChanged
AddHandler CType(m_editSketch, IEngineEditEvents_Event).OnCurrentTaskChanged, AddressOf OnCurrentTaskChanged
End Sub
Public Sub Deactivate() Implements ESRI.ArcGIS.Controls.IEngineEditTask.Deactivate
'Stop listening for editor events.
RemoveHandler CType(m_engineEditor, IEngineEditEvents_Event).OnTargetLayerChanged, AddressOf OnTargetLayerChanged
RemoveHandler CType(m_engineEditor, IEngineEditEvents_Event).OnCurrentTaskChanged, AddressOf OnCurrentTaskChanged
'Release object references.
m_engineEditor = Nothing
m_editSketch = Nothing
m_editLayer = Nothing
End Sub
Public ReadOnly Property GroupName() As String Implements ESRI.ArcGIS.Controls.IEngineEditTask.GroupName
Get
Return "Modify Tasks"
End Get
End Property
Public ReadOnly Property Name() As String Implements ESRI.ArcGIS.Controls.IEngineEditTask.Name
Get
Return "Cut Polygons Without Selection (VB)"
End Get
End Property
Public Sub OnDeleteSketch() Implements ESRI.ArcGIS.Controls.IEngineEditTask.OnDeleteSketch
End Sub
Public Sub OnFinishSketch() Implements ESRI.ArcGIS.Controls.IEngineEditTask.OnFinishSketch
If m_editSketch Is Nothing Then
Return
End If
Dim hasCutPolygons As Boolean = False
'Change the cursor to be hourglass shape.
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
Try
'Get the geometry that performs the cut from the edit sketch.
Dim cutGeometry As IGeometry = m_editSketch.Geometry
'The sketch geometry is simplified to deal with a multi-part sketch as well
'as the case where the sketch loops back over itself.
Dim topoOperator As ITopologicalOperator2 = DirectCast(cutGeometry, ITopologicalOperator2)
topoOperator.IsKnownSimple_2 = False
topoOperator.Simplify()
'Create the spatial filter to search for features in the target feature class.
'The spatial relationship we care about is whether the interior of the line
'intersects the interior of the polygon.
Dim spatialFilter As ISpatialFilter = New SpatialFilterClass()
spatialFilter.Geometry = m_editSketch.Geometry
spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects
'Find the polygon features that cross the sketch.
Dim featureClass As IFeatureClass = m_editLayer.TargetLayer.FeatureClass
Dim featureCursor As IFeatureCursor = featureClass.Search(spatialFilter, False)
'Only do work if there are features that intersect the edit sketch.
Dim origFeature As IFeature = featureCursor.NextFeature()
If origFeature IsNot Nothing Then
'Check the first feature to see if it is ZAware and if it needs to make the
'cut geometry ZAware.
Dim zAware As IZAware = DirectCast(origFeature.Shape, IZAware)
If zAware.ZAware Then
zAware = DirectCast(cutGeometry, IZAware)
zAware.ZAware = True
End If
Dim comErrors As ArrayList = New ArrayList()
'Start an edit operation so we can have undo/redo.
m_engineEditor.StartOperation()
'Cycle through the features, cutting with the sketch.
While origFeature IsNot Nothing
Try
'Split the feature. Use the IFeatureEdit::Split method which ensures
'the attributes are correctly dealt with.
Dim featureEdit As IFeatureEdit = DirectCast(origFeature, IFeatureEdit)
'Set to hold the new features that are created by the Split.
Dim newFeaturesSet As ISet = featureEdit.Split(cutGeometry)
'New features have been created.
If newFeaturesSet IsNot Nothing Then
newFeaturesSet.Reset()
hasCutPolygons = True
End If
Catch comExc As COMException
comErrors.Add(String.Format("OID: {0}, Error: {1} , {2}", origFeature.OID.ToString(), comExc.ErrorCode, comExc.Message))
Finally
'Continue to work on the next feature if it fails to split the current one.
origFeature = featureCursor.NextFeature()
End Try
End While
'If any polygons were cut, refresh the display and stop the edit operation.
If hasCutPolygons Then
'Clear the map's selection.
m_engineEditor.Map.ClearSelection()
'Refresh the display including modified layer and any previously selected component.
Dim activeView As IActiveView = DirectCast(m_engineEditor.Map, IActiveView)
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeography Or esriViewDrawPhase.esriViewGeoSelection, Nothing, activeView.Extent)
'Complete the edit operation.
m_engineEditor.StopOperation("Cut Polygons Without Selection")
Else
m_engineEditor.AbortOperation()
End If
'report any errors that have arisen while splitting features
If comErrors.Count > 0 Then
Dim stringBuilder As New StringBuilder("The following features could not be split: " & Chr(10) & "", 200)
For Each comError As String In comErrors
stringBuilder.AppendLine(comError)
Next
MessageBox.Show(stringBuilder.ToString(), "Cut Errors")
End If
End If
Catch e As Exception
System.Windows.Forms.MessageBox.Show("Unable to perform the cut task." & Chr(10) & "" + e.ToString())
'In the event of an error, abort the operation.
m_engineEditor.AbortOperation()
Finally
'Change the cursor shape to default.
System.Windows.Forms.Cursor.Current = Cursors.[Default]
End Try
End Sub
Public ReadOnly Property UniqueName() As String Implements ESRI.ArcGIS.Controls.IEngineEditTask.UniqueName
Get
Return "CutPolygonsWithoutSelection_VB_CutPolygonsWithoutSelection_VB"
End Get
End Property
'This method is not expected to be fired since we have unregistered from the event in Deactivate
Public Sub OnCurrentTaskChanged()
UpdateScketchToolStatus()
End Sub
Public Sub OnTargetLayerChanged()
UpdateScketchToolStatus()
End Sub
#Region "IEngineEditTask private methods"
Private Sub UpdateScketchToolStatus()
If m_editLayer Is Nothing Then
Return
End If
'Only enable the sketch tool if there is a polygon target layer.
If m_editLayer.TargetLayer.FeatureClass.ShapeType <> esriGeometryType.esriGeometryPolygon Then
m_editSketch.GeometryType = esriGeometryType.esriGeometryNull
Else
m_editSketch.GeometryType = esriGeometryType.esriGeometryPolyline
'Set the edit sketch geometry type to be esriGeometryPolyline.
End If
End Sub
#End Region
End Class