Using the IEnumVertex methods
- Create a multipart polyline and cast into IPointCollection.
- Get the vertex enumerator of the point collection.
- Enumerate through each vertex by calling the Next and QueryNext methods.
- Call different methods, such as Previous, QueryPrevious, SetAt, ResetToEnd, and so on for the enumeration.
- 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 for Desktop Basic | ArcGIS for Desktop Basic |
ArcGIS for Desktop Standard | ArcGIS for Desktop Standard |
ArcGIS for Desktop Advanced | ArcGIS for Desktop Advanced |
Engine Developer Kit | Engine |