How to use the IEnumVertex methods (ArcObjects .NET 10.6 SDK)
ArcObjects Help for .NET developers > Developing with ArcGIS > Learning ArcObjects > Managing data > Working with geometry > Working with curves, segments, and vertices > How to use the IEnumVertex methods (ArcObjects .NET 10.6 SDK)

How to use the IEnumVertex methods


Using the IEnumVertex methods

  1. Create a multipart polyline and cast into IPointCollection.
  2. Get the vertex enumerator of the point collection.
  3. Enumerate through each vertex by calling the Next and QueryNext methods.
  4. Call different methods, such as Previous, QueryPrevious, SetAt, ResetToEnd, and so on for the enumeration.
  5. Call Put_ID, Put_Z, Put_M, Put_X, and Put_Y to work on the current vertex.
The following code example shows how to use the IEnumVertex methods:
[C#]
public void IEnumVertexExample()
{
    //Get a polyline object created in CreateMultipartPolyline
    //and cast to IPointCollection.
    IPointCollection pointCollection=CreateMultipartPolyline()as IPointCollection;
    //Get the vertex enumerator.
    IEnumVertex2 enumVertex=pointCollection.EnumVertices as IEnumVertex2;
    //Create a point object for the Query methods.
    //The point doesn't need to be created each time.
    IPoint queryVertex=new PointClass();
    //Reset the enum.
    enumVertex.Reset();
    //Get the next vertex.
    IPoint outVertex;
    int partIndex;
    int vertexIndex;
    enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    String report="***** Next *****\n" + "Vertex coordinates X, Y : " +
        outVertex.X + ", " + outVertex.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    //Reset the enum.
    enumVertex.Reset();
    //Query the next vertex - have to create the point.
    //QueryNext is faster than Next, because the method doesn't have
    //to create the point each time.
    enumVertex.QueryNext(queryVertex, out partIndex, out vertexIndex);
    report=report + "***** QueryNext *****\n" + "Vertex coordinates X, Y : " +
        outVertex.X + ", " + outVertex.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    //Clone the enumerator.
    IEnumVertex clonedEnumVertex=enumVertex.Clone();
    //Get the next vertex.
    enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    enumVertex.QueryNext(queryVertex, out partIndex, out vertexIndex);
    report=report + "***** Next *****\n" + "Vertex coordinates X, Y : " +
        outVertex.X + ", " + outVertex.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    //Get the next vertex of the cloned enumerator.
    clonedEnumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    report=report + "***** Next - Cloned Enum *****\n" + 
        "Vertex coordinates X, Y : " + outVertex.X + ", " + outVertex.Y + 
        " - Part Index : " + partIndex + " - Vertex Index : " + vertexIndex + "\n";
    //Get the previous vertex.
    enumVertex.Previous(out outVertex, out partIndex, out vertexIndex);
    report=report + "***** Previous *****\n" + "Vertex coordinates X, Y : " +
        outVertex.X + ", " + outVertex.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    //Query the previous vertex.
    enumVertex.QueryPrevious(queryVertex, out partIndex, out vertexIndex);
    report=report + "***** QueryPrevious *****\n" + "Vertex coordinates X, Y : " +
        outVertex.X + ", " + outVertex.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    //Set the enumerator at Part Index=0 and Vertex Index=4 (Last vertex).
    enumVertex.SetAt(0, 4);
    report=report + "***** IsLastInPart *****" + "IsLastInPart : " +
        enumVertex.IsLastInPart();
    enumVertex.NextInPart(out outVertex, out vertexIndex);
    report=report + "***** NextInPart - Last Vertex *****\n" + 
        "Vertex coordinates X, Y : " + outVertex.X + ", " + outVertex.Y + 
        " - Part Index : " + partIndex + " - Vertex Index : " + vertexIndex + "\n";
    //Next in part will return the first vertex of the current part
    //because the enumerator is located on the last vertex on that part.
    enumVertex.NextInPart(out outVertex, out vertexIndex);
    report=report + "***** NextInPart - First Vertex *****\n" + 
        "Vertex coordinates X, Y : " + outVertex.X + ", " + outVertex.Y + 
        " - Part Index : " + partIndex + " - Vertex Index : " + vertexIndex + "\n";
    //QueryNextInPart.
    enumVertex.QueryNextInPart(outVertex, out vertexIndex);
    report=report + "***** QueryNextInPart *****\n" + "Vertex coordinates X, Y : "
        + outVertex.X + ", " + outVertex.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    //Get the previous vertex.
    enumVertex.ResetToEnd();
    enumVertex.Previous(out outVertex, out partIndex, out vertexIndex);
    report=report + "***** Previous - After ResetToEnd *****\n" + 
        "Vertex coordinates X, Y : " + outVertex.X + ", " + outVertex.Y + 
        " - Part Index : " + partIndex + " - Vertex Index : " + vertexIndex + "\n";
    //Reset the enumerator.
    enumVertex.Reset();
    //Skip two vertices forward.
    enumVertex.Skip(2);
    enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    report=report + "***** Skip forward *****\n" + "Vertex coordinates X, Y : " +
        outVertex.X + ", " + outVertex.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    //Skip two vertices backward.
    enumVertex.Skip( - 2);
    enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    report=report + "***** Skip backward *****\n" + "Vertex coordinates X, Y : " +
        outVertex.X + ", " + outVertex.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    WKSPoint outWKSPoint=new WKSPoint();
    enumVertex.WKSNext(out outWKSPoint, out partIndex, out vertexIndex);
    report=report + "***** WKSNext *****\n" + "Vertex coordinates X, Y : " +
        outWKSPoint.X + ", " + outWKSPoint.Y + " - Part Index : " + partIndex + 
        " - Vertex Index : " + vertexIndex + "\n";
    //Make the polyline Ms Aware, Zs Aware, IDsAware
    //to be able to assign Ms, Zs, IDs to its vertices.
    IMAware mAware=pointCollection as IMAware;
    mAware.MAware=true;
    IZAware zAware=pointCollection as IZAware;
    zAware.ZAware=true;
    IPointIDAware idAware=pointCollection as IPointIDAware;
    idAware.PointIDAware=true;
    enumVertex=pointCollection.EnumVertices as IEnumVertex2;
    //Set the vertex attributes.
    enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    int counter=0;
    while (outVertex != null)
    {
        enumVertex.put_M(counter);
        enumVertex.put_Z(counter);
        enumVertex.put_ID(counter);
        counter++;
        enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    }
    //Move the first point of the polyline by -10, -10.
    enumVertex.Reset();
    enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    enumVertex.put_X(outVertex.X - 10);
    enumVertex.put_Y(outVertex.Y - 10);
    //Loop over the vertices and print the values.
    enumVertex.Reset();
    enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    while (outVertex != null)
    {
        report=report + "Vertex coordinates X, Y, M, Z, ID : " + outVertex.X + 
            ", " + outVertex.Y + ", " + outVertex.M + ", " + outVertex.Z + ", " +
            outVertex.ID + "\n";
        enumVertex.Next(out outVertex, out partIndex, out vertexIndex);
    }
    System.Windows.Forms.MessageBox.Show(report);
}

//Create a polyline with 2 parts of 4 segments each.
//Each part contains 1 Line, 1 Circular Arc, 1 Elliptic Arc, 1 Bezier Curve.
private IPolyline CreateMultipartPolyline()
{
    //Create the end points for all the segments.
    IPoint[] points=new IPoint[5];
    for (int i=0; i < 5; i++)
    {
        points[i]=new PointClass();
    }
    points[0].PutCoords(10, 10);
    points[1].PutCoords(20, 10);
    points[2].PutCoords(30, 10);
    points[3].PutCoords(40, 10);
    points[4].PutCoords(50, 10);
    //Create 4 segments.
    //1 Line, 1 CircularArc, 1 EllipticArc, 1 Bezier Curve.
    ILine line=new LineClass();
    line.PutCoords(points[0], points[1]);
    ICircularArc circularArc=new CircularArcClass();
    IPoint centerPoint=new PointClass();
    centerPoint.PutCoords(25, 10);
    circularArc.PutCoords(centerPoint, points[1], points[2],
        esriArcOrientation.esriArcClockwise);
    IEllipticArc ellipticArc=new EllipticArcClass();
    IPoint ellipticArcPoint=new PointClass();
    ellipticArcPoint.PutCoords(35, 10);
    ellipticArc.PutCoordsByAngle(false, ellipticArcPoint,  - Math.PI,  - Math.PI, 0,
        5, 0.2);

    IPoint[] bezierControlPoints=new IPoint[4];
    bezierControlPoints[0]=points[3];
    bezierControlPoints[1]=new PointClass();
    bezierControlPoints[1].PutCoords(43.33, 20);
    bezierControlPoints[2]=new PointClass();
    bezierControlPoints[2].PutCoords(46.66, 0);
    bezierControlPoints[3]=points[4];
    IBezierCurveGEN bezier=new BezierCurveClass();
    bezier.PutCoords(ref bezierControlPoints);
    //Create two paths.
    ISegmentCollection segmentCollection1=new PathClass();
    ISegmentCollection segmentCollection2=new PathClass();
    //Add the segments to the path.
    object Missing=Type.Missing;
    segmentCollection1.AddSegment(line as ISegment, ref Missing, ref Missing);
    segmentCollection1.AddSegment(circularArc as ISegment, ref Missing, ref Missing);
    segmentCollection1.AddSegment(ellipticArc as ISegment, ref Missing, ref Missing);
    segmentCollection1.AddSegment(bezier as ISegment, ref Missing, ref Missing);
    //Clone the first path and move it to the right by 10.
    IClone clone=segmentCollection1 as IClone;
    segmentCollection2=clone.Clone()as ISegmentCollection;
    ITransform2D transfrom2D=segmentCollection2 as ITransform2D;
    transfrom2D.Move(50, 0);
    //Create the polyline object.
    IGeometryCollection geometryCollection=new PolylineClass();

    geometryCollection.AddGeometry(segmentCollection1 as IGeometry, ref Missing, ref
        Missing);
    geometryCollection.AddGeometry(transfrom2D as IGeometry, ref Missing, ref
        Missing);
    return geometryCollection as IPolyline;
}
[VB.NET]
Sub IEnumVertexExample()
    Dim pPointCollection As IPointCollection, pEnumVertex As IEnumVertex2
    Dim pOutVertex As IPoint, lOutPart As Long, lOutVertex As Long
    Dim pClonedEnumVertex As IEnumVertex2, pQueryVertex As IPoint
    Dim OutWKSPoint As WKSPoint, pMAware As IMAware
    Dim pZAware As IZAware, pPtIdAware As IPointIDAware, i As Long
    'Get a polyline object created in CreateMultipartPolyline
    'and QI for IPointCollection.
    pPointCollection=CreateMultipartPolyline
    'Get the vertex enumerator.
    pEnumVertex=pPointCollection.EnumVertices
    'Cocreate a point object for the Query methods.
    'The point doesn't need to be created each time.
    pQueryVertex=New Point
    'Reset the enum.
    pEnumVertex.Reset()
    'Get the next vertex.
    pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    Debug.Print("***** Next *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Reset the enum.
    pEnumVertex.Reset()
    'Query the next vertex - have to cocreate the point.
    'QueryNext is faster than Next, because the method doesn't have
    'to create the point each time.
    pEnumVertex.QueryNext(pQueryVertex, lOutPart, lOutVertex)
    Debug.Print("***** QueryNext *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Clone the enumerator.
    pClonedEnumVertex=pEnumVertex.Clone
    'Get the next vertex.
    pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    Debug.Print("***** Next *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Get the next vertex of the cloned enumerator.
    pClonedEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    Debug.Print("***** Next - Cloned Enum *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Get the previous vertex.
    pEnumVertex.Previous(pOutVertex, lOutPart, lOutVertex)
    Debug.Print("***** Previous *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    'Query the previous vertex.
    pEnumVertex.QueryPrevious(pQueryVertex, lOutPart, lOutVertex)
    Debug.Print("***** QueryPrevious *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Set the enumerator at Part Index=0 and Vertex Index=4 (Last vertex).
    pEnumVertex.SetAt(0, 4)
    Debug.Print("***** IsLastInPart *****")
    Debug.Print("IsLastInPart : " & pEnumVertex.IsLastInPart)
    pEnumVertex.NextInPart(pOutVertex, lOutVertex)
    Debug.Print("***** NextInPart - Last Vertex *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Next in part will return the first vertex of the current part
    'because the enumerator is located on the last vertex on that part.
    pEnumVertex.NextInPart(pOutVertex, lOutVertex)
    Debug.Print("***** NextInPart - First Vertex *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'QueryNextInPart.
    pEnumVertex.QueryNextInPart(pOutVertex, lOutVertex)
    Debug.Print("***** QueryNextInPart *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Get the previous vertex.
    pEnumVertex.ResetToEnd()
    pEnumVertex.Previous(pOutVertex, lOutPart, lOutVertex)
    Debug.Print("***** Previous - After ResetToEnd *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Reset the enumerator.
    pEnumVertex.Reset()
    'Skip two vertices forward.
    pEnumVertex.Skip(2)
    pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    Debug.Print("***** Skip forward *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Skip two vertices backward.
    pEnumVertex.Skip( -2)
    pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    Debug.Print("***** Skip backward *****")
    Debug.Print("Vertex coordinates X, Y : " & pOutVertex.X & ", " & pOutVertex.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    pEnumVertex.WKSNext(OutWKSPoint, lOutPart, lOutVertex)
    Debug.Print("***** WKSNext *****")
    Debug.Print("Vertex coordinates X, Y : " & OutWKSPoint.X & ", " & OutWKSPoint.Y & " - Part Index : " & lOutPart & " - Vertex Index : " & lOutVertex)
    'Make the polyline Ms Aware, Zs Aware, IDsAware
    'to be able to assign Ms, Zs, Ids to its vertices.
    pMAware=pPointCollection
    pMAware.MAware=True
    pZAware=pPointCollection
    pZAware.ZAware=True
    pPtIdAware=pPointCollection
    pPtIdAware.PointIDAware=True
    pEnumVertex=pPointCollection.EnumVertices
    'Set the vertex attributes.
    pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    While Not pOutVertex Is Nothing
        pEnumVertex.put_M(CDbl(i))
        pEnumVertex.put_Z(CDbl(i))
        pEnumVertex.put_ID(CDbl(i))
        i=i + 1
        pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    End While
    'Move the first point of the polyline by -10, -10.
    pEnumVertex.Reset()
    pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    pEnumVertex.put_X(pOutVertex.X - 10)
    pEnumVertex.put_Y(pOutVertex.Y - 10)
    'Loop over the vertices and print the values.
    pEnumVertex.Reset()
    pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    While Not pOutVertex Is Nothing
        Debug.Print("Vertex coordinates X, Y, M, Z, ID : " & pOutVertex.X & ", " & pOutVertex.Y & ", " & pOutVertex.M & ", " & pOutVertex.Z & ", " & pOutVertex.ID)
        pEnumVertex.Next(pOutVertex, lOutPart, lOutVertex)
    End While
    
End Sub

'Create a polyline with 2 parts of 4 segments each.
'Each part contains 1 Line, 1 Circular Arc, 1 Elliptic Arc, 1 Bezier Curve.

Private Function CreateMultipartPolyline() As IPolyline
    Dim pSegColl0 As ISegmentCollection, pSegColl1 As ISegmentCollection
    Dim pLine As ILine, pPoints(4) As IPoint, i As Long, dPi As Double
    Dim pCArc As ICircularArc, pCenterCArc As IPoint
    Dim pEArc As IEllipticArc, pCenterEArc As IPoint
    Dim pBezier As IBezierCurveGEN, pBezControlPoints(3) As IPoint
    Dim pGeoColl As IGeometryCollection, pClone As IClone
    Dim pTrans2D As ITransform2D
    'Create the polyline object.
    pGeoColl=New Polyline
    'Create two paths.
    pSegColl0=New Path
    'PI value.
    dPi=Math.Atan(1) * 4
    'Create the end points for all the segments.
    For i=0 To 4
        pPoints(i)=New Point
    Next
    pPoints(0).PutCoords(10, 10)
    pPoints(1).PutCoords(20, 10)
    pPoints(2).PutCoords(30, 10)
    pPoints(3).PutCoords(40, 10)
    pPoints(4).PutCoords(50, 10)
    'Create 4 segments.
    '1 Line, 1 CircularArc, 1 EllipticArc, 1 Bezier Curve.
    pLine=New Line
    pLine.PutCoords(pPoints(0), pPoints(1))
    pCArc=New CircularArc
    pCenterCArc=New Point
    pCenterCArc.PutCoords(25, 10)
    pCArc.PutCoords(pCenterCArc, pPoints(1), pPoints(2), esriArcOrientation.esriArcClockwise)
    pEArc=New EllipticArc
    pCenterEArc=New Point
    pCenterEArc.PutCoords(35, 10)
    pEArc.PutCoordsByAngle(False, pCenterEArc, - dPi, - dPi, 0, 5, 0.2)
    pBezier=New BezierCurve
    For i=0 To 3
        pBezControlPoints(i)=New Point
    Next
    pBezControlPoints(0).PutCoords(40, 10)
    pBezControlPoints(1).PutCoords(43.33, 20)
    pBezControlPoints(2).PutCoords(46.66, 0)
    pBezControlPoints(3).PutCoords(50, 10)
    pBezier.PutCoords(pBezControlPoints)
    'Add the segments to the path.
    pSegColl0.AddSegment(pLine)
    pSegColl0.AddSegment(pCArc)
    pSegColl0.AddSegment(pEArc)
    pSegColl0.AddSegment(pBezier)
    'Clone the first path and move it to the right by 10.
    pClone=pSegColl0
    pSegColl1=pClone.Clone
    pTrans2D=pSegColl1
    pTrans2D.Move(50, 0)
    pGeoColl.AddGeometry(pSegColl0)
    pGeoColl.AddGeometry(pTrans2D)
    CreateMultipartPolyline=pGeoColl
End Function






To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcGIS Desktop Basic ArcGIS Desktop Basic
ArcGIS Desktop Standard ArcGIS Desktop Standard
ArcGIS Desktop Advanced ArcGIS Desktop Advanced
Engine Developer Kit Engine