How to create a polygon


Summary
A polygon can be built in numerous ways depending on user input. This topic shows the most commonly used approaches to efficiently create a polygon.


Building a polygon using points

The following code shows how to build a polygon using a collection of points. This approach is preferred when you have a sequence of vertices as input. The resulting polygon ring will only contain a straight line segment.
 
[VB.NET]
Public Sub CreatePolygonByPoints()
    
    'Build a polygon from a sequence of points.
    'Add arrays of points to a geometry using the IGeometryBridge2 interface on the
    'GeometryEnvironment singleton object.
    Dim geometryBridge2 As IGeometryBridge2 = New GeometryEnvironmentClass
    Dim pointCollection4 As IPointCollection4 = New PolygonClass
    
    'TODO:
    'pointCollection4.SpatialReference = 'Define the spatial reference of the new polygon.
    
    Dim aWKSPointBuffer() As WKSPoint
    Dim cPoints As Long = 4 'The number of points in the first part.
    ReDim aWKSPointBuffer(0 To CInt(cPoints - 1))
    
    'TODO:
    'aWKSPointBuffer = 'Read cPoints into the point buffer.
    
    geometryBridge2.SetWKSPoints(pointCollection4, aWKSPointBuffer)
    
    'pointCollection4 has now been defined.
    
End Sub
[C#]
public void CreatePolygonByPoints()
{
    //Build a polygon from a sequence of points. 
    //Add arrays of points to a geometry using the IGeometryBridge2 interface on the 
    //GeometryEnvironment singleton object.
    IGeometryBridge2 geometryBridge2 = new GeometryEnvironmentClass();
    IPointCollection4 pointCollection4 = new PolygonClass();

    //TODO:
    //pointCollection4.SpatialReference = 'Define the spatial reference of the new polygon.

    WKSPoint[] aWKSPointBuffer = null;
    long cPoints = 4; //The number of points in the first part.
    aWKSPointBuffer = new WKSPoint[System.Convert.ToInt32(cPoints - 1) + 1];

    //TODO:
    //aWKSPointBuffer = 'Read cPoints into the point buffer.

    geometryBridge2.SetWKSPoints(pointCollection4, ref aWKSPointBuffer);

    //pointCollection4 has now been defined.
}

Building a polygon using segments

In the following code example, the multipart polygon is built segment–by–segment. This approach gives the most control if you're using advanced construction techniques or curved segments (circular arcs, Bèzier curves, and so on).
[VB.NET]
Public Sub CreatePolygonBySegments()
    
    'Build a polygon segment-by-segment.
    Dim polygon As IPolygon = New PolygonClass
    
    'TODO:
    'polygon.SpatialReference = 'Always define the spatial reference of new top-level geometries.
    
    'Create the segments and rings. If this was a single-part polygon, segments could be
    'added directly to the polygon and the ring created internally.
    'You cannot reuse the same ring object. Also, when rings are added to the polygon, the
    'polygon takes ownership of the rings. You cannot reuse a ring to build another polygon.
    'These restrictions also apply to segments.
    
    Dim circularArc As ICircularArc = New CircularArcClass
    Dim segment1 As ISegment = CType(circularArc, ISegment)
    Dim ring1 As ISegmentCollection = New RingClass
    ring1.AddSegment(segment1)
    
    Dim bezierCurve As IBezierCurve = New BezierCurveClass
    Dim segment2 As ISegment = CType(bezierCurve, ISegment)
    Dim ring2 As ISegmentCollection = New RingClass
    ring2.AddSegment(segment2)
    
    Dim geometryCollection As IGeometryCollection = CType(polygon, IGeometryCollection)
    
    Dim geometry1 As IGeometry = CType(ring1, IGeometry)
    geometryCollection.AddGeometry(geometry1)
    
    Dim geometry2 As IGeometry = CType(ring2, IGeometry)
    geometryCollection.AddGeometry(geometry2)
    
    'At this point, a _shell_geometry has been constructed. The _shell_geometry consists of
    'one polygon containing two rings; each containing one segment.
    'However, the coordinates of those segments have not been defined.
    'Because references to those segments exist, their coordinates can be defined now.
    Dim point As IPoint = New PointClass
    point.X = -10
    point.Y = 0
    
    circularArc.PutCoordsByAngle(point, 0, 2 * 3.14159265358979, 10.0#)
    
    Dim pntArray(0 To 3) As IPoint
    Dim i As Long
    For i = 0 To 3
        pntArray(CInt(i)) = New PointClass
    Next i
    
    pntArray(0).X = 10
    pntArray(0).Y = 0
    pntArray(1).X = 10
    pntArray(1).Y = 10
    pntArray(2).X = 20
    pntArray(2).Y = 10
    pntArray(3).X = 10
    pntArray(3).Y = 0
    bezierCurve.PutCoords(4, pntArray(0))
    
    'The polygon has now been defined. When changing segment coordinates directly in this
    'way, be sure to let the top-level geometry know that things have changed underneath
    'it so that it can delete any cached properties that it maintains, such as envelope, length,
    'area, and so on.
    'When you use certain methods on the top-level geometry implementation of the
    'IGeometryCollection interface, such as AddGeometry, it automatically invalidates any
    'cached properties.
    geometryCollection.GeometriesChanged()
    
End Sub
[C#]
public void CreatePolygonBySegments()
{
    //Build a polygon segment-by-segment.
    IPolygon polygon = new PolygonClass();

    //TODO:
    //polygon.SpatialReference = 'Always define the spatial reference of new top-level geometries.

    //Create the segments and rings. If this was a single-part polygon, segments could be
    //added directly to the polygon and the ring created internally.
    //You cannot reuse the same ring object. Also, when rings are added to the polygon,
    //the polygon takes ownership of the rings. You cannot reuse a ring to build another polygon.
    //These restrictions also apply to segments.

    ICircularArc circularArc = new CircularArcClass();
    ISegment segment1 = (ISegment)circularArc;
    ISegmentCollection ring1 = new RingClass();
    object before1 = null;
    object after1 = null;
    ring1.AddSegment(segment1, ref before1, ref after1);

    IBezierCurve bezierCurve = new BezierCurveClass();
    ISegment segment2 = (ISegment)bezierCurve;
    ISegmentCollection ring2 = new RingClass();
    object before2 = null;
    object after2 = null;
    ring2.AddSegment(segment2, ref before2, ref after2);

    IGeometryCollection geometryCollection = (IGeometryCollection)polygon;

    IGeometry geometry1 = (IGeometry)ring1;
    object before1a = null;
    object after1a = null;
    geometryCollection.AddGeometry(geometry1, ref before1a, ref after1a);

    IGeometry geometry2 = (IGeometry)ring2;
    object before2a = null;
    object after2a = null;
    geometryCollection.AddGeometry(geometry2, ref before2a, ref after2a);

    //At this point, a _shell_geometry has been constructed. The _shell_geometry consists of
    //one polygon containing two rings; each containing one segment.
    //However, the coordinates of those segments have not been defined.
    //Because references to those segments exist, their coordinates can be defined now.
    IPoint point = new PointClass();
    point.X =  - 10;
    point.Y = 0;

    circularArc.PutCoordsByAngle(point, 0, 2 * 3.14159265358979, 10.0);

    IPoint[] pntArray = new IPoint[4];
    long i = 0;
    for (i = 0; i <= 3; i++)
    {
        pntArray[System.Convert.ToInt32(i)] = new PointClass();
    }

    pntArray[0].X = 10;
    pntArray[0].Y = 0;
    pntArray[1].X = 10;
    pntArray[1].Y = 10;
    pntArray[2].X = 20;
    pntArray[2].Y = 10;
    pntArray[3].X = 10;
    pntArray[3].Y = 0;
    bezierCurve.PutCoords(4, ref pntArray[0]);

    //The polygon has now been defined. When changing segment coordinates directly in this
    //way, be sure to let the top-level geometry know that things have changed underneath 
    //it so that it can delete any cached properties that it maintains, such as envelope, length, 
    //area, and so on.
    //When you use certain methods on the top-level geometry implementation of the IGeometryCollection 
    //interface, such as AddGeometry, it automatically invalidates any cached properties.
    geometryCollection.GeometriesChanged();
}

Creating a polygon using existing geometries

A polygon can be created based on a topological relationship between existing geometries. In the following code example, a polygon is generated by uniting two existing polygons:
[VB.NET]
Public Sub CreatePolygonFromExistingGeometries(ByRef polygon1 As IPolygon, ByRef polygon2 As IPolygon)
    
    'Build a new polygon by uniting two existing polygons.
    Dim topologicalOperator2 As ITopologicalOperator2 = CType(polygon1, ITopologicalOperator2)
    
    'Simplify.
    topologicalOperator2.IsKnownSimple_2 = False
    topologicalOperator2.Simplify()
    
    Dim geometry As IGeometry = topologicalOperator2.Union(polygon2)
    Dim polygonCombined As IPolygon = CType(geometry, IPolygon)
    
    'polygonCombined is the new generated polygon.
    
End Sub
[C#]
public void CreatePolygonFromExistingGeometries(ref IPolygon polygon1, ref IPolygon
    polygon2)
{
    //Build a new polygon by uniting two existing polygons.
    ITopologicalOperator2 topologicalOperator2 = (ITopologicalOperator2)polygon1;

    //Simplify.
    topologicalOperator2.IsKnownSimple_2 = false;
    topologicalOperator2.Simplify();

    IGeometry geometry = topologicalOperator2.Union(polygon2);
    IPolygon polygonCombined = (IPolygon)geometry;

    //polygonCombined is the new generated polygon.
}






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):