3

I am trying to define user generated polygons with Esri's ArcGIS Engine 10.1.
Here's how it works at the moment:

  • User clicks on the map and creates points
  • User connects the points

I have a collection of line segments (IPointCollection) in memory. The map looks something like this.

enter image description here

I want to input all my line segments into an object. Then I need the object to tell me that I have 2 polygons, and one of the polygons has 5 sub polygons.

I created a ISegmentCollection with all the segments in both polygons, then I cast the ExteriorRingBag into an IGeometryCollection, and I have my 2 main polygons.

The bounty goes to whoever can tell me how to take the IPolygon on the left, and get it to return it's 5 sub polygons.

patrick
  • 2,730
  • 26
  • 50

2 Answers2

3

It sounds like you need to explode your single part polygon to multipart:

e.g. Explode polygon feature

private void button1_Click(object sender, EventArgs e)
{
    IWorkspaceFactory pwsf = new FileGDBWorkspaceFactoryClass();
    IWorkspace pws = pwsf.OpenFromFile(@"D:\temp\Yogesh\Vector_YV5612\Vector_YV5612.gdb", 0);
    IFeatureWorkspace pfeatws = pws as IFeatureWorkspace;
    IFeatureClass pFeatClassLand = pfeatws.OpenFeatureClass("RIVER_STREAM_WADI_P");
    IFeatureCursor pFeatCurLand = pFeatClassLand.Search(null, false);
    IFeature featLand = pFeatCurLand.NextFeature();
    IWorkspaceEdit pwsEdit = pws as IWorkspaceEdit;
    pwsEdit.StartEditing(true);
    pwsEdit.StartEditOperation();
    while (featLand != null)
    {
        IGeometryCollection pGeoColl = featLand.Shape as IGeometryCollection;
        IPolygon2 polygon = featLand.Shape as IPolygon2;
        IPolygon[] polygonArray = new IPolygon[polygon.ExteriorRingCount];
        IPolygon pPoly = null;
        int cntOuterRing = polygon.ExteriorRingCount;
        object mis=System.Reflection.Missing.Value;
        if (pGeoColl.GeometryCount > 0)
        {
            IPolygon4 poly4 = featLand.Shape as IPolygon4;
            IGeometryBag pGeobag = poly4.ConnectedComponentBag;
            IEnumGeometry connComenum = pGeobag as IEnumGeometry;
            connComenum.Reset();
            IPolygon po = connComenum.Next() as IPolygon; ;
            while (po != null)
            {
                IFeature pFeat = pFeatClassLand.CreateFeature();
                IGeometry pGeoNew = (igeometry)po;
                IZAware pz = pGeoNew as IZAware;
                pz.ZAware = true;
                pFeat.Shape = pGeoNew;
                pFeat.Store();
                po = connComenum.Next() as IPolygon;
            }
            featLand = pFeatCurLand.NextFeature();
        }
        pwsEdit.StopEditing(true);
        pwsEdit.StartEditOperation();
    }
}

Here is another Explode code snippet:

Explode.cs

artwork21
  • 35,114
  • 8
  • 66
  • 134
  • My IPolygon.ConnectedComponentBag only contains 1 polygon, so I can't iterate over it with IEnumGeometry . – patrick Aug 06 '13 at 19:23
  • 1
    Another option would be to call the geoprocessor to run multi2singlepart, see Kirk Kuykendall answer, http://gis.stackexchange.com/questions/1610/issues-with-geoprocessing-with-net – artwork21 Aug 07 '13 at 12:46
1

This is how you could do it in VBA using the IFeatureConstruction interface:

The code initially builds a bunch of polylines and stores them in a GeometryBag. They intersect at their ends and create a grid which converts into a set of polygons.

Public Sub Test()
' Get a handle on the first layer in map
' This is an empty polygon shapefile
Dim pMXdocument As IMxDocument
Set pMXdocument = ThisDocument
Dim pMap As IMap
Set pMap = pMXdocument.FocusMap
Dim pLayer As ILayer
Set pLayer = pMap.Layer(0)
Dim pFeatureLayer As IFeatureLayer
Set pFeatureLayer = pLayer
Dim pFeatureClass As IFeatureClass
Set pFeatureClass = pFeatureLayer.FeatureClass
Dim pSR As ISpatialReference
Dim pGD As IGeoDataset
Set pGD = pFeatureLayer
Set pSR = pGD.SpatialReference

' Create a geometry bag of polylines, this will create a grid
Dim p1 As IPoint
Dim p2 As IPoint
Dim pPolyline As IPolyline
Dim pGB As IGeometryBag
Set pGB = New GeometryBag
Set pGB.SpatialReference = pSR
Dim pGC As IGeometryCollection
Set pGC = pGB
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 0, 0
p2.PutCoords 1, 0
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 1, 0
p2.PutCoords 2, 0
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 0, 0
p2.PutCoords 0, 1
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 0, 1
p2.PutCoords 0, 2
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 0, 2
p2.PutCoords 1, 2
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 1, 2
p2.PutCoords 2, 2
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 2, 2
p2.PutCoords 2, 1
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 2, 1
p2.PutCoords 2, 0
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 1, 1
p2.PutCoords 1, 2
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 1, 1
p2.PutCoords 2, 1
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 1, 1
p2.PutCoords 1, 0
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline
Set p1 = New Point
Set p2 = New Point
p1.PutCoords 1, 1
p2.PutCoords 0, 1
Set pPolyline = New Polyline
pPolyline.FromPoint = p1
pPolyline.ToPoint = p2
pGC.AddGeometry pPolyline

' Get enumerate over Geometry bag
Dim pEnumGeometry As IEnumGeometry
Set pEnumGeometry = pGB

' create invalidate area
Dim pIA As IInvalidArea
Set pIA = New InvalidArea
Dim pSD As IScreenDisplay
Set pSD = pMXdocument.ActiveView.ScreenDisplay
Set pIA.Display = pSD

' Convert polylines into polygons
Dim pFeatureConstruction As IFeatureConstruction
Set pFeatureConstruction = New FeatureConstruction
pFeatureConstruction.ConstructPolygonsFromGeometries Nothing, pFeatureClass, Nothing, False, pEnumGeometry, pIA, 0.01

' Report how many polygons
MsgBox CStr(pFeatureClass.FeatureCount(Nothing))
End Sub
Hornbydd
  • 43,380
  • 5
  • 41
  • 81
  • I actually ended up using ConstructPolygonsFromFeature class, but I think your answer is close enough. – patrick Aug 13 '13 at 00:40