Problem: When exploding donut or island polygons using ArcObjects, the inner polygon is not created


When exploding a multipart polygon using ArcObjects, the inner polygon (donut or island) is eliminated from the sketch.  This article describes how to retain the geometry of inner polygons.

Solution or Workaround

  1. Get a reference to each outer (exterior) ring, its associated inner (interior) rings, and add all these to a geometry collection.
  2. Cast that set of rings out to an IGeometry and eventually to a new Polygon object. This is done in a loop for each outer/inner ring set, each essentially represented as a 'part' in a multipart polygon. The areas of each of the constituent parts of the original multipart polygons will be correctly computed, taking into account the 'holes'.

Code (C#) - Compute areas for constituent parts of a multipart polygon

            IMap map = ArcMap.Document.FocusMap;
            ILayer layer = map.Layer[0];
            IFeatureLayer featureLayer = layer as FeatureLayer;
            IFeatureClass featureClass = featureLayer.FeatureClass;
            IFeature feature = featureClass.GetFeature(0); // Feature with holes in it
            IGeometry geometry = feature.Shape;
            IArea areaPolygon = geometry as IArea;
            double areaPolygon_value = areaPolygon.Area;
            System.Diagnostics.Debug.WriteLine("         ORIGINAL MULTIPART POLYGON               ");
            System.Diagnostics.Debug.WriteLine("areaPolygon_value = " + areaPolygon_value);
            IPolygon4 polygon4 = geometry as IPolygon4;
            IGeometryBag geometryBag = polygon4.ExteriorRingBag;
            IGeometryCollection geometryCollection_Outer = geometryBag as IGeometryCollection;
            for (int i = 0; i < geometryCollection_Outer.GeometryCount; i++) // For each EXTERIOR ring, compute area of INTERIOR rings inside that exterior ring
                geometry_OuterRing_Array[i] = geometryCollection_Outer.Geometry[i]; // get the exterior ring
                // Create a new geometry collection for each outer ring, and add to it the outer ring, and all the inner rings it contains
                Polygon polygon_OUTER_and_INNER_rings = new Polygon();
                IGeometryCollection geometryCollection_OUTER_and_INNER_rings = polygon_OUTER_and_INNER_rings as IGeometryCollection;
                System.Diagnostics.Debug.WriteLine("----------  EXTERIOR RING[" + i + "]  ------------------");
                IGeometryBag geometryBag_Inner = polygon4.get_InteriorRingBag(geometry_OuterRing_Array[i] as IRing); // get interior rings
                IGeometryCollection geometryCollection_Inner = geometryBag_Inner as IGeometryCollection;
                int interiorRingCount = polygon4.get_InteriorRingCount(geometry_OuterRing_Array[i] as IRing);
                System.Diagnostics.Debug.WriteLine("interiorRingCount = " + interiorRingCount);
                int interiorRingCount2 = geometryCollection_Inner.GeometryCount; // this is a check to make sure the two counts are equal
                System.Diagnostics.Debug.WriteLine("interiorRingCount2 = " + interiorRingCount2);
                IGeometry geometry_InnerRing = null;
                for (int j = 0; j < geometryCollection_Inner.GeometryCount; j++) // Compute Area of interior rings
                    geometry_InnerRing = geometryCollection_Inner.Geometry[j];
                    IArea area_InnerRing = geometry_InnerRing as IArea;
                    double area_InnerRing_Value = area_InnerRing.Area;
                    System.Diagnostics.Debug.WriteLine("area_InnerRing_Value[" + j + "] = " + area_InnerRing_Value);


                // construct a polygon
                IGeometry geometry_Polygon_OUTER_and_INNER_rings = geometryCollection_OUTER_and_INNER_rings as IGeometry;
                polygon_OUTER_and_INNER_rings = geometry_Polygon_OUTER_and_INNER_rings as Polygon;
                IArea area_Polygon_OUTER_and_INNER_rings = polygon_OUTER_and_INNER_rings as IArea;
                double AREA_VALUE_Polygon_OUTER_and_INNER_rings = area_Polygon_OUTER_and_INNER_rings.Area;
                System.Diagnostics.Debug.WriteLine("             MULTIPART FEATURE [" + i + "]        ");
                System.Diagnostics.Debug.WriteLine("AREA_VALUE_Polygon_OUTER_and_INNER_rings[" + i + "] = " + AREA_VALUE_Polygon_OUTER_and_INNER_rings);
                TotalAreaOfMultiPartFeature += AREA_VALUE_Polygon_OUTER_and_INNER_rings;