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.

1
1
+200

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
1
  • I actually ended up using ConstructPolygonsFromFeature class, but I think your answer is close enough. – patrick Aug 13 '13 at 0:40
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

2
  • My IPolygon.ConnectedComponentBag only contains 1 polygon, so I can't iterate over it with IEnumGeometry . – patrick Aug 6 '13 at 19:23
  • 1
    Another option would be to call the geoprocessor to run multi2singlepart, see Kirk Kuykendall answer, gis.stackexchange.com/questions/1610/… – artwork21 Aug 7 '13 at 12:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.