This example builds two multipart polygons in two different ways:
The first polygon is built segment by segment.
The second is built by defining its vertices as an array of WKSPoint structures.
The first way gives you the most control if you are using advanced construction techniques or curved segments (circular arcs, Bézier curves, and so on).
The second way is recommended for efficiently building polygons from bulk coordinate data that have vertices connected only with straight lines. The techniques shown here can also be applied to polyline construction. The first polygon should look something like the following illustration:
See the following code example:
[C#]
publicvoid ConstructPolygons()
{
//Build a polygon segment by segment.//Create the segments and rings. If this is a single-part polygon you can add//segments directly to the polygon and it creates the ring internally.//You cannot reuse the same ring object. Also, when rings are added to the polygon //it takes ownership of them. You cannot reuse a ring for building another polygon. //These same restrictions also apply to segments.
ICircularArc circularArc = new CircularArcClass();
IBezierCurveGEN bezierCurve = new BezierCurveClass();
ISegmentCollection ring1 = new RingClass();
ISegmentCollection ring2 = new RingClass();
object missing = Type.Missing;
ring1.AddSegment(circularArc as ISegment, ref missing, ref missing);
ring2.AddSegment(bezierCurve as ISegment, ref missing, ref missing);
IPolygon polygon = new PolygonClass();
//Always define the spatial reference of new top-level geometries.//polygon.SpatialReference = ... code skipped.
IGeometryCollection geometryCollection = polygon as IGeometryCollection;
geometryCollection.AddGeometry(ring1 as IGeometry, ref missing, ref missing);
geometryCollection.AddGeometry(ring2 as IGeometry, ref missing, ref missing);
//At this point, you have constructed a _shell_ geometry. It consists of one //polygon containing two rings, each of which contains one segment. //However, the coordinates of those segments have not been defined. //Because you still have references to those segments, you can define their //coordinates now.//Circular arc.
IPoint centerPoint = new PointClass();
centerPoint.X = -10;
centerPoint.Y = 0;
circularArc.PutCoordsByAngle(centerPoint, 0, 2 * Math.PI, 10);
//Bézier curve.
IPoint[] controlPoints = new IPoint[4];
for (int i = 0; i < controlPoints.Length; i++)
{
controlPoints[i] = new PointClass();
}
controlPoints[0].X = 10;
controlPoints[0].Y = 0;
controlPoints[1].X = 10;
controlPoints[1].Y = 10;
controlPoints[2].X = 20;
controlPoints[2].Y = 10;
controlPoints[3].X = 10;
controlPoints[3].Y = 0;
bezierCurve.PutCoords(ref controlPoints);
//The polygon has now been defined. When changing segment coordinates directly //like this, you need to be careful to let the top-level geometry know that//things have changed underneath it so that it can delete any cached properties //that it might be maintaining, such as envelope, length, area, etc.//When you use certain methods on the top-level geometry implementation //of IGeometryCollection interface, like AddGeometry, it will automatically//invalidate any cached properties.
geometryCollection.GeometriesChanged();
//Build another polygon from a bunch of points. As before, assume that //two parts (rings) need to be created. If the polygon is a single part, you can//add the points directly to the polygon without creating a ring.
IGeometryCollection pointPolygon = new PolygonClass();
//Define the spatial reference of the new pointPolygon here, code skipped.//As previously stated, the rings used for the first polygon cannot be reused.
ring1 = new RingClass();
ring2 = new RingClass();
//At 9.2, the recommended way to add arrays of points to a geometry is to use //the IGeometryBridge2 interface on the GeometryEnvironment singleton object.
IGeometryBridge2 geometryBridge = new GeometryEnvironmentClass();
WKSPoint[] wksPoints1 = new WKSPoint[ring1.SegmentCount];
geometryBridge.SetWKSPoints(ring1 as IPointCollection4, ref wksPoints1);
WKSPoint[] wksPoints2 = new WKSPoint[ring2.SegmentCount];
geometryBridge.SetWKSPoints(ring2 as IPointCollection4, ref wksPoints2);
pointPolygon.AddGeometry(ring1 as IGeometry, ref missing, ref missing);
pointPolygon.AddGeometry(ring2 as IGeometry, ref missing, ref missing);
//The point polygon is now defined.
}
[VB.NET]
PublicSub ConstructPolygons()
'Build a polygon segment by segment'Create the segments and rings. If this is a single-part polygon you can add'segments directly to the polygon and it creates the ring internally.'You cannot reuse the same ring object. Also, when rings are added to the polygon 'it takes ownership of them. You cannot reuse a ring for building another polygon. 'These same restrictions also apply to segments.Dim circularArc As ICircularArc = New CircularArcClass()
Dim bezierCurve As IBezierCurveGEN = New BezierCurveClass()
Dim ring1 As ISegmentCollection = New RingClass()
Dim ring2 As ISegmentCollection = New RingClass()
Dim missing AsObject = Type.Missing
ring1.AddSegment(circularArc, missing, missing)
ring2.AddSegment(bezierCurve, missing, missing)
Dim polygon As IPolygon = New PolygonClass()
'Always define the spatial reference of new top-level geometries.'polygon.SpatialReference = ... code skipped.Dim geometryCollection As IGeometryCollection = CType(polygon, IGeometryCollection)
geometryCollection.AddGeometry(ring1, missing, missing)
geometryCollection.AddGeometry(ring2, missing, missing)
'At this point, you have constructed a _shell_ geometry. It consists of one 'polygon containing two rings, each of which contains one segment. 'However, the coordinates of those segments have not been defined. 'Because you still have references to those segments, you can define their 'coordinates now.'Circular ArcDim centerPoint As IPoint = New PointClass()
centerPoint.X = -10
centerPoint.Y = 0
circularArc.PutCoordsByAngle(centerPoint, 0, 2 * Math.PI, 10)
'Bézier curve.Dim controlPoints(3) As IPoint
controlPoints(0) = New PointClass()
controlPoints(0).X = 10
controlPoints(0).X = 0
controlPoints(1) = New PointClass()
controlPoints(1).X = 10
controlPoints(1).X = 10
controlPoints(2) = New PointClass()
controlPoints(2).X = 20
controlPoints(2).X = 10
controlPoints(3) = New PointClass()
controlPoints(3).X = 10
controlPoints(3).X = 0
bezierCurve.PutCoords(controlPoints)
'The polygon has now been defined. When changing segment coordinates directly 'like this, you need to be careful to let the top-level geometry know that'things have changed underneath it so that it can delete any cached properties 'that it might be maintaining, such as envelope, length, area, etc.'When you use certain methods on the top-level geometry implementation 'of IGeometryCollection interface, like AddGeometry, it will automatically'invalidate any cached properties.
geometryCollection.GeometriesChanged()
'Build another polygon from a bunch of points. As before, assume that 'two parts (rings) need to be created. If the polygon is a single part, you can'add the points directly to the polygon without creating a ring.Dim pointPolygon As IGeometryCollection = New PolygonClass()
'Define the spatial reference of the new pointPolygon here, code skipped.'As previously stated, the rings used for the first polygon cannot be reused.
ring1 = New RingClass()
ring2 = New RingClass()
'At 9.2, the recommended way to add arrays of points to a geometry is to use 'the IGeometryBridge2 interface on the GeometryEnvironment singleton object.Dim geometryBridge As IGeometryBridge2 = New GeometryEnvironmentClass()
Dim segCount AsInteger = ring1.SegmentCount
Dim wksPoints1(ring1.SegmentCount) As WKSPoint
geometryBridge.SetWKSPoints(ring1, wksPoints1)
Dim wksPoints2(ring2.SegmentCount) As WKSPoint
geometryBridge.SetWKSPoints(ring2, wksPoints2)
pointPolygon.AddGeometry(ring1, missing, missing)
pointPolygon.AddGeometry(ring2, missing, missing)
'The point polygon is now defined.EndSub