How to create a feature inside the editor


This document was published with and applies to ArcGIS 9.3.
A 9.2 version also exists.
Summary This topic shows how to create a feature when editing the workspace.

Development licensing Deployment licensing
ArcView ArcView
ArcEditor ArcEditor
ArcInfo ArcInfo

In this topic


Starting an edit session

There are two common methods that can be used to start editing data in ArcMap. The method you select can depend on the complexity of the edit operation and the type of data used. A large operation in a geodatabase can provide better performance if edited using the edit workspace from the StartEditOperation, and a smaller operation that is more focused can start editing from the editor. 
 
By using the IEditor interface, more methods are available to control the edit task, display, and target layer.
 
The following code example shows how to start editing from the IWorkspaceEdit interface. To create an AccessWorkspaceFactory, you need to add the ESRI.ArcGIS.DataSourcesGDB namespace to your project.
 

[C#]
public override void OnClick()
{
  //Initialize the application.
  esriLicenseStatus licenseStatus = esriLicenseStatus.esriLicenseUnavailable;
  IAoInitialize m_AoInitialize = new AoInitializeClass();
  licenseStatus = m_AoInitialize.Initialize
    (esriLicenseProductCode.esriLicenseProductCodeArcInfo);
  //Get the workspace and set it to a creatable coclass.
  IWorkspaceFactory factoryWork = new AccessWorkspaceFactory();
  //Open the access workspace.
  IWorkspace work = factoryWork.OpenFromFile(@"C:\temp\test.mdb",
    m_application.hWnd);
  //Query interface (QI) the workspace to do the edits with the editor.
  IWorkspaceEdit editWork = work as IWorkspaceEdit;
  //Create a feature workspace to open the feature class.
  IFeatureWorkspace featWork = editWork as IFeatureWorkspace;
  IFeatureClass featClass = featWork.OpenFeatureClass("poly");
  if (featClass == null)
    return ;
  editWork.StartEditing(true);
  editWork.StartEditOperation();

[VB.NET]
Public Overrides Sub OnClick()
'Initialize the application.
Dim licenseStatus As esriLicenseStatus = esriLicenseStatus.esriLicenseUnavailable
Dim m_AoInitialize As IAoInitialize = New AoInitialize
licenseStatus = m_AoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo)
'Get the workspace and set it to a cocreatable coclass for the access database.
Dim factoryWork As IWorkspaceFactory = New AccessWorkspaceFactory
'Open the access workspace.
Dim work As IWorkspace = factoryWork.OpenFromFile("C:\temp\test.mdb", m_application.hWnd)
'QI the workspace to do the edits inside the editor.
Dim editWork As IWorkspaceEdit = CType(work, IWorkspaceEdit)
'Create a feature workspace to open the feature class.
Dim featWork As IFeatureWorkspace = CType(editWork, IFeatureWorkspace)
Dim featClass As IFeatureClass = featWork.OpenFeatureClass("line")
If featClass Is Nothing Then
    Return
End If
editWork.StartEditing(True)
editWork.StartEditOperation()
If the tool or command requires the editor, the user can manually start an edit session. To verify, check the following:
 
If the result is true, before completing the edits add the following line:
 
By using this method when you stop editing, you must provide a name for the operation that is put on the edit stack and can be used to undo the operation of the following:
 

Defining the feature location in space

To define the location of the feature, points are created and in the process, the x,y coordinates are created.
 
Depending on the type of data, it may be m-aware defining measure values and or it may be z-aware defining elevation values. The m- and z-values are not seen inside the attribute table, but they are stored in the edit sketch. For more information, see How to work with the edit sketch.
 
The editor populates the z-value in each vertex based on the current z-value as it is set using either the current z-control or by setting IEditSketch2.CurrentZ value. IEditorZ has been added z environment properties that provide more options for editing z-aware data. This is valuable if an applicable terrain, TIN, or raster surface is available. The z-values at each x,y location can be extrapolated from a surface that is set thru the IEditorZ.Surface property.
 
The following code example shows how to create a point with an x,y coordinate. The z-value is set using a defined current Z. However, defining an ISurface and setting the zCaptureType to surface sets the editing environment so that the z-value is extrapolated from the surface. In the following code sample the m-value is hard-coded to 10, which may not be useful to your situation.
 

[C#]
private IPoint CreatePoint(Double X, Double Y, IEditor editor)
{
  IEditorZ zeditProps = editor as IEditorZ;
  //If a surface is available define it here.
  //Set capture type to surface so that the vertex z-values are extrapolated from the surface.
  //zeditProps.ZCaptureType = esriCaptureSurfaceZ.
  zeditProps.ZCaptureType = esriCaptureCurrentZ;
  IEditSketch2 editSketch = editor as IEditSketch2;
  editSketch.Currentz = 394;
  IPoint CreatePoint = new PointClass();
  //CreatePoint.X or CreatePoint.Y can be used to set the coordinates individually.
  CreatePoint.PutCoords(X, Y);
  CreatePoint.M = 10;
  return CreatePoint;
}

[VB.NET]
Private Function CreatePoint(ByVal x As Double, ByVal y As Double, Byval editor As IEditor) As IPoint
    Dim zeditProps As IEditorZ = editor
    'If a surface is available define it here.
    'set the capture type to surface so that the vertex z-values are extrapolated from the surface.
    'zeditProps.ZCaptureType = esriCaptureSurfaceZ
    zeditProps.ZCaptureType = esriCaptureCurrentZ
    Dim editSketch As IEditSketch2 = editor
    editSketch2.CurrentZ = 395
    Dim cPoint As IPoint = New ESRI.ArcGIS.Geometry.Point
    ' To individually assign a value to the coordinates, use cPoint.X = x and cPoint.Y = y.
    cPoint.PutCoords(x, y)
    cPoint.M = 10
    Return cPoint
End Function

Using collections

Collections, such as point, segment, or geometry are used to create the new feature. Depending on the type of geometry that is created, a specific collection can be query interfaced (QI'd) to a geometry. To accommodate the type of geometry that is created, a switch or select case structure can be used. See the following:
 
For example, the ring object can be created and set to the point collection when creating a new multipart polygon feature. A polygon works the same way but designed for a single-part feature. The points that were previously created to define the new feature location will be inserted into a collection using the Addpoints method on the point collection. See the following code example:
 

[C#]
//After obtaining the geometry and before creating the feature, is the location
//to set the spatial reference of the new geometry to the spatial reference of the map. 
ISpatialReference spatialReference = m_editor.Map.SpatialReference;
poly.SpatialReference = spatialReference;

[VB.NET]
Dim spatialReference As ISpatialReference = m_editor.Map.SpatialReference
'Set the spatial reference of the new line.
Line.SpatialReference = spatialReference

[C#]
case esriGeometryType.esriGeometryPolyline:
  IPointCollection pointColl;
  IPolyline line = new PolylineClass();
  pointColl = line as IPointCollection;
  object Missing = Type.Missing;
  pointColl.AddPoint(lowLeft, ref Missing, ref Missing);
  pointColl.AddPoint(lowRight, ref Missing, ref Missing);
  pointColl.AddPoint(upRight, ref Missing, ref Missing);
  pointColl.AddPoint(upLeft, ref Missing, ref Missing);
  pointColl.AddPoint(lowLeft, ref Missing, ref Missing);
  IFeature lineExt = CreateFeature(featClass, pointColl as IGeometry);
  ITopologicalOperator2 topoOp2 = pointColl as ITopologicalOperator2;
  if (topoOp2.IsKnownSimple == true)
    topoOp2.Simplify();
  break;
case esriGeometryType.esriGeometryPoint:
  IFeature llfeat, lrfeat, urfeat, ulfeat;
  llfeat = CreateFeature(featClass, lowLeft);
  urfeat = CreateFeature(featClass, lowRight);
  ulfeat = CreateFeature(featClass, upRight);
  lrfeat = CreateFeature(featClass, upLeft);
  break;
case esriGeometryType.esriGeometryPolygon:
  IPolygon poly = new PolygonClass();
  pointColl = poly as IPointCollection;
  Missing = Type.Missing;
  pointColl.AddPoint(lowLeft, ref Missing, ref Missing);
  pointColl.AddPoint(lowRight, ref Missing, ref Missing);
  pointColl.AddPoint(upRight, ref Missing, ref Missing);
  pointColl.AddPoint(upLeft, ref Missing, ref Missing);
  IMAware mAware = poly as IMAware;
  mAware.MAware = true;
  poly.Close();
  topoOp2 = pointColl as ITopologicalOperator2;
  if (topoOp2.IsKnownSimple == true)
    topoOp2.Simplify();
  IFeature polyext = CreateFeature(featClass, poly as IGeometry);
  break;
}

[VB.NET]
Case esriGeometryType.esriGeometryPolygon
    Dim poly As IPolygon = New Polygon
    Dim pointColl As IPointCollection = CType(poly, IPointCollection)
    pointColl.AddPoint(lowLeft)
    pointColl.AddPoint(lowRight)
    pointColl.AddPoint(upRight)
    pointColl.AddPoint(upLeft)
    Dim maware As IMAware = CType(poly, IMAware)
    maware.MAware = True
    poly.Close()
    Dim topoOp2 As ITopologicalOperator2 = CType(pointColl, ITopologicalOperator2)
    If topoOp2.IsKnownSimple = True Then
        topoOp2.Simplify()
        Dim polyExt As IFeature = CreateFeature(featClass, poly)
    End If
Case esriGeometryType.esriGeometryLine
    Dim Line As ILine = New Line
    Dim pointColl As IPointCollection = CType(Line, IPointCollection)
    pointColl.AddPoint(lowLeft)
    pointColl.AddPoint(lowRight)
    pointColl.AddPoint(upRight)
    pointColl.AddPoint(lowRight)
    pointColl.AddPoint(lowLeft)
    
    Dim lineExt As IFeature = CreateFeature(featClass, Line)
    Dim topoOp2 As ITopologicalOperator2 = CType(pointColl, ITopologicalOperator2)
    If topoOp2.IsKnownSimple = True Then
        topoOp2.Simplify()
    End If
Case esriGeometryType.esriGeometryPoint
    Dim llfeat, lrfeat, urfeat, ulfeat As IFeature
    llfeat = CreateFeature(featClass, lowLeft)
    lrfeat = CreateFeature(featClass, lowRight)
    urfeat = CreateFeature(featClass, upRight)
    ulfeat = CreateFeature(featClass, upLeft)
Case esriGeometryType.esriGeometryPolyline
    Dim Line As IPolyline = New Polyline
    Dim pointColl As IPointCollection = CType(Line, IPointCollection)
    pointColl.AddPoint(lowLeft)
    pointColl.AddPoint(lowRight)
    pointColl.AddPoint(upRight)
    pointColl.AddPoint(upLeft)
    pointColl.AddPoint(lowLeft)
    
    Dim lineExt As IFeature = CreateFeature(featClass, Line)
    Dim topoOp2 As ITopologicalOperator2 = CType(pointColl, ITopologicalOperator2)
    If topoOp2.IsKnownSimple = True Then
        topoOp2.Simplify()
    Else
        topoOp2.IsKnownSimple_2 = True
        topoOp2.Simplify()
    End If
Case Else
    
    editWork.AbortEditOperation()
    Exit Sub
End Select

Completing the operation

After completing the edits, the operation can be finished by using the StopEditOperation and the StopEditing (Boolean save edits) functions. See the following:
 
editWork.StopEditOperation()
editWork.StopEditing(True)
 
After defining where the feature exists and the geometry of the feature, the feature is stored in the geodatabase. The following CreateFeature code example creates a new feature in the feature class, sets the shape, and stores the feature:

[VB.NET]
Private Function CreateFeature(ByVal featClass As IFeatureClass, ByVal poly As IGeometry) As IFeature
    Dim feature As IFeature = featClass.CreateFeature()
    feature.Shape = poly
    feature.Store()
    Return feature
End Function

[C#]
//CreateFeature/Store.
private IFeature CreateFeature(IFeatureClass featureClass, IGeometry poly)
{
  IFeature feature = featureClass.CreateFeature();
  feature.Shape = poly;
  feature.Store();
  return feature;
}