ArcObjects Library Reference  

ConvertPart

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