About the Convert part to feature command Sample
[C#]
ConvertPart.cs
using System;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Editor;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.esriSystem;
namespace Convert_Part_To_FeatureCS
{
/// <summary>
/// The command must be in the edit sketch context menu
/// and converts a selected part to its own feature.
/// </summary>
[Guid("f766682c-3a1c-4b97-8354-af3c12706e1f")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("Convert_Part_To_FeatureCS.ConvertPart")]
public sealed class ConvertPart : BaseCommand
{
#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);
SketchMenuCommands.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);
SketchMenuCommands.Unregister(regKey);
}
#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);
}
#endregion
private IApplication m_application;
public ConvertPart()
{
base.m_category = "Developer Samples";
base.m_caption = "Convert Part to Feature";
base.m_message = "Command must be run from Edit Sketch Context Menu only";
base.m_toolTip = "Creates a new feature from a part";
base.m_name = "Convert Part to Feature";
}
public IEditor m_editor;
public IEditSketch m_editSketch;
public IFeatureClass featureClass;
public IMap map = new Map();
#region Overriden Class Methods
/// <param name="hook">Instance of the application</param>
public override void OnCreate(object hook)
{
if (hook == null)
return;
m_application = hook as IApplication;
if (m_application == null)
return;
UID uID = new UID();
uID.Value = "esriEditor.Editor";
m_editor = m_application.FindExtensionByCLSID(uID) as IEditor;
if (m_editor == null)
return;
m_editSketch = m_editor as IEditSketch;
}
/// <summary>
/// Command Enabled called to determine enable status.
/// </summary>
public override bool Enabled
{
get
{
if (m_editor == null)
return false;
if (!m_editSketch.Geometry.IsEmpty && m_editor.SelectionCount == 1)
{
return true;
}
else
{
return false;
}
}
}
/// <summary>
/// After enabling the edit sketch of a multipart feature right click on the part to be converted and
/// select Convert Part to Feature, to make the part it's own feature.
/// </summary>
public override void OnClick()
{
IActiveView activeView;
if (m_editor == null)
return;
m_editor.StartOperation();
//if the sketch only has one part to begin with - exit.
IGeometryCollection geometryCollection = m_editSketch.Geometry as IGeometryCollection;
{
if (geometryCollection.GeometryCount == 1)
{
return;
}
//get the part, this is the one the user right-clicked on.
int Part = m_editSketch.Part;
IEnumFeature enumFeature = m_editor.EditSelection;
enumFeature.Reset();
IFeature origFeature = enumFeature.Next();
if (origFeature == null)
{
m_editor.AbortOperation();
return;
}
featureClass = origFeature.Class as IFeatureClass;
IFeature newFeature = featureClass.CreateFeature();
geometryCollection = origFeature.Shape as IGeometryCollection;
IGeometry origPartGeometry = geometryCollection.get_Geometry(Part);
//delete the original part.
geometryCollection.RemoveGeometries(Part, 1);
geometryCollection.GeometriesChanged();
origFeature.Shape = geometryCollection as IGeometry;
origFeature.Store();
//check the type of geometry.
IPolygon polygon = new PolygonClass();
IPolyline polyline = new PolylineClass();
IMultipoint multiPoint = new MultipointClass();
object Missing = Type.Missing;
//make sure the new geometry is z aware, set a flag for later use.
IGeometryDef fcGeoDef = CheckZGeometryDef(featureClass);
//if the feature class is z aware set the flag to true.
Boolean isZAware = true;
IZAware zAware;
if (fcGeoDef.HasZ == false)
{
isZAware = false;
}
switch (origPartGeometry.GeometryType)
{
case esriGeometryType.esriGeometryRing:
if (isZAware == true)
{
zAware = polygon as IZAware;
zAware.ZAware = true;
}
geometryCollection = polygon as IGeometryCollection;
geometryCollection.AddGeometry
(origPartGeometry, ref Missing, ref Missing);
break;
case esriGeometryType.esriGeometryPath:
if (isZAware == true)
{
zAware = polyline as IZAware;
zAware.ZAware = true;
}
geometryCollection = polyline as IGeometryCollection;
geometryCollection.AddGeometry
(origPartGeometry, ref Missing, ref Missing);
break;
case esriGeometryType.esriGeometryPoint:
if (isZAware == true)
{
zAware = multiPoint as IZAware;
zAware.ZAware = true;
}
geometryCollection = multiPoint as IGeometryCollection;
geometryCollection.AddGeometry
(origPartGeometry, ref Missing, ref Missing);
break;
default:
m_editor.AbortOperation();
break;
}
newFeature.Shape = geometryCollection as IGeometry;
//copy the attributes of the orig feature the new feature.
IField field = new FieldClass();
IFields fields = origFeature.Fields;
//skip OID and geometry.
for (int fieldCount = 0; fieldCount < fields.FieldCount; fieldCount++)
{
field = fields.get_Field(fieldCount);
if ((field.Type != esriFieldType.esriFieldTypeGeometry) &&
(field.Type != esriFieldType.esriFieldTypeOID) && field.Editable)
{
newFeature.set_Value(fieldCount, origFeature.get_Value(fieldCount));
}
}
newFeature.Store();
m_editor.StopOperation("Convert Part to Feature");
//refresh map according to old and new selections.
activeView = m_editor.Map as IActiveView;
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
m_editor.Map.ClearSelection();
ILayer featLayer = GetFeatureLayer(newFeature);
if (featLayer == null)
return;
m_editor.Map.SelectFeature(featLayer, newFeature);
activeView.PartialRefresh
(esriViewDrawPhase.esriViewGeoSelection, null, null);
}
}
//}
/// <summary>
/// Function to obtain the feature layer from the selected feature.
/// </summary>
public ILayer GetFeatureLayer(IFeature feature)
{
if (feature == null)
return null;
map = m_editor.Map;
featureClass = feature.Class as IFeatureClass;
for (int layerCount = 0; layerCount < map.LayerCount; layerCount++)
{
// Search the layers for the layer in question and get the name.
if (featureClass.AliasName == map.get_Layer(layerCount).Name)
{
return map.get_Layer(layerCount);
}
}
return null;
}
public IGeometryDef CheckZGeometryDef(IFeatureClass featureClass)
{
string shapeFieldName = featureClass.ShapeFieldName;
IFields fields = featureClass.Fields;
int geometryIndex = fields.FindField(shapeFieldName);
IField field = fields.get_Field(geometryIndex);
IGeometryDef geometryDef = field.GeometryDef;
return geometryDef;
}
}
}
#endregion
[Visual Basic .NET]
ConvertPart.vb
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports ESRI.ArcGIS.ArcMapUI
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Editor
Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Geometry
Imports ESRI.ArcGIS.SystemUI
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.ADF.BaseClasses
<ComClass(ConvertPart.ClassId, ConvertPart.InterfaceId, ConvertPart.EventsId), _
ProgId("ConvertPartToFeatureVBNet.ConvertPart")> _
Public NotInheritable Class ConvertPart
Inherits BaseCommand
#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 = "16d21edb-5aae-4e70-87df-9a14b09e94ca"
Public Const InterfaceId As String = "4a35c83d-7be9-4c51-8e67-e79a050e1cf9"
Public Const EventsId As String = "070850b8-e8f7-40e5-a185-6fbc7f6a3b78"
#End Region
#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)
SketchMenuCommands.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)
SketchMenuCommands.Unregister(regKey)
End Sub
#End Region
#End Region
Private m_application As IApplication
''' <summary>
''' 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.
''' </summary>
''' <remarks></remarks>
Public Sub New()
MyBase.New()
MyBase.m_caption = "Convert Part to Feature"
MyBase.m_message = "Command must be run from Edit Sketch Context Menu only"
MyBase.m_toolTip = "Creates a new feature from a part"
MyBase.m_name = "Convert Part to Feature"
End Sub
Private m_editor As IEditor
Private m_editSketch As IEditSketch
''' <summary>
''' Enable the command only when an edit sketch is selected for one feature.
''' Called to determine enabled status.
''' </summary>
''' <value>boolean</value>
''' <returns>enabled status</returns>
Public Overrides ReadOnly Property Enabled() As Boolean
Get
If Not m_editSketch.Geometry.IsEmpty And m_editor.SelectionCount = 1 Then
Enabled = True
Else
Enabled = False
End If
End Get
End Property
''' <param name="hook">Instance of the application</param>
Public Overrides Sub OnCreate(ByVal hook As Object)
If Not (hook Is Nothing) Then
If TypeOf (hook) Is IApplication Then
m_application = CType(hook, IApplication)
End If
Else
Exit Sub
End If
Dim uID As New UID
m_application = hook
uID.Value = "esriEditor.Editor"
m_editor = m_application.FindExtensionByCLSID(uID)
If m_editor Is Nothing Then Exit Sub
'QI.
m_editSketch = m_editor
End Sub
''' <summary>
''' After enabling the edit sketch of a multipart feature right click
''' on the part to be converted and select Convert Part to Feature,
''' to make the part it's own feature.
''' </summary>
''' <remarks></remarks>
Public Overrides Sub OnClick()
Dim activeView As IActiveView
Dim bInOperation As Boolean
'if the sketch only has one part to begin with - exit.
Dim geometryCollection As IGeometryCollection
geometryCollection = m_editSketch.Geometry
If geometryCollection.GeometryCount = 1 Then Exit Sub
m_editor.StartOperation()
bInOperation = True
'get the part, this is the one the user right-clicked on.
Dim Part As Integer
Part = m_editSketch.Part
Dim enumFeature As IEnumFeature
enumFeature = m_editor.EditSelection
enumFeature.Reset()
Dim origFeature As IFeature
origFeature = enumFeature.Next
If origFeature Is Nothing Then
m_editor.AbortOperation()
Exit Sub
End If
Dim featureClass As IFeatureClass
featureClass = origFeature.Class
Dim origPartGeometry As IGeometry
Dim newFeature As IFeature
newFeature = featureClass.CreateFeature
geometryCollection = origFeature.Shape
origPartGeometry = geometryCollection.Geometry(Part)
'delete the original part.
geometryCollection.RemoveGeometries(Part, 1)
geometryCollection.GeometriesChanged()
origFeature.Shape = geometryCollection
origFeature.Store()
'check the type of geometry.
Dim polygon As New Polygon
Dim polyline As New Polyline
Dim multiPoint As New Multipoint
'Make sure the new geometry is z aware, set a flag for later use.
Dim fcGeoDef As IGeometryDef = CheckZGeometryDef(featureClass)
'If the feature class is z aware set the flag to true.
Dim isZAware As Boolean = True
Dim zAware As IZAware
If fcGeoDef.HasZ = False Then
isZAware = False
End If
Select Case origPartGeometry.GeometryType
Case esriGeometryType.esriGeometryRing
'Only set the geometry z-aware if the feature class is z-aware.
If isZAware = True Then
zAware = CType(polygon, IZAware)
zAware.ZAware = True
End If
geometryCollection = polygon
geometryCollection.AddGeometry(origPartGeometry)
Case esriGeometryType.esriGeometryPath
If isZAware = True Then
zAware = CType(polyline, IZAware)
zAware.ZAware = True
End If
geometryCollection = polyline
geometryCollection.AddGeometry(origPartGeometry)
Case esriGeometryType.esriGeometryPoint
If isZAware = True Then
zAware = CType(multiPoint, IZAware)
zAware.ZAware = True
End If
geometryCollection = multiPoint
geometryCollection.AddGeometry(origPartGeometry)
Case Else
m_editor.AbortOperation()
Exit Sub
End Select
newFeature.Shape = geometryCollection
'copy the attributes of the orig feature the new feature.
Dim fields As IFields
fields = origFeature.Fields
'skip OID and geometry.
Dim fieldCount As Integer
Dim field As IField
For fieldCount = 0 To fields.FieldCount - 1
field = origFeature.Fields.Field(fieldCount)
If Not field.Type = esriFieldType.esriFieldTypeGeometry And Not field.Type = esriFieldType.esriFieldTypeOID And field.Editable Then
newFeature.Value(fieldCount) = origFeature.Value(fieldCount)
End If
Next fieldCount
newFeature.Store()
m_editor.StopOperation("Convert Part to Feature")
bInOperation = False
'refresh map according to old and new selections.
activeView = m_editor.Map
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)
m_editor.Map.ClearSelection()
Dim newLayer As ILayer
newLayer = GetFeatureLayer(newFeature)
If (Not newLayer Is Nothing) Then
m_editor.Map.SelectFeature(newLayer, newFeature)
Else
Exit Sub
End If
activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)
End Sub
''' <summary>
''' Function to obtain the feature layer from the selected feature.
''' </summary>
''' <param name="feature"></param>
''' <returns>Layer</returns>
Private Function GetFeatureLayer(ByRef feature As IFeature) As ILayer
Dim map As IMap
Dim featureClass As IFeatureClass
Dim LayerCount As Integer
map = m_editor.Map
featureClass = feature.Class
'Loop thru the layers to get the selected features layer.
For LayerCount = 0 To map.LayerCount - 1
If featureClass.AliasName = map.Layer(LayerCount).Name Then
GetFeatureLayer = map.Layer(LayerCount)
Exit Function
Else
Exit Function
End If
Next LayerCount
End Function
''' <summary>
''' This function looks at the shape field to get the geometry def of the feature class.
''' </summary>
''' <param name="sAFeatureClass"></param>
''' <returns>IGeometryDef</returns>
Public Function CheckZGeometryDef(ByVal sAFeatureClass As IFeatureClass) As IGeometryDef
Dim shapeFieldName As String = sAFeatureClass.ShapeFieldName
Dim fields As IFields = sAFeatureClass.Fields
Dim geometryIndex As Integer = fields.FindField(shapeFieldName)
Dim field As IField = fields.Field(geometryIndex)
Dim geometryDef As IGeometryDef = field.GeometryDef
Return geometryDef
End Function
End Class