1

I am able to retrieve a list of polygons from the opened map layer in ArcGIS using the following C# code:

        IMxDocument pMxDoc;
        pMxDoc = (IMxDocument)ArcMap.Application.Document;
        IMap pMap;
        pMap = pMxDoc.FocusMap;

        IFeatureLayer2 pFLayer;
        pFLayer = (IFeatureLayer2)pMap.get_Layer(0);

        // Retreve the feature class.
        IFeatureClass featureClass = pFLayer.FeatureClass;

        // Retrieve the number of polygons in the map.
        IQueryFilter queryFilter = new QueryFilterClass();
        int numberOfPolygons = featureClass.FeatureCount(queryFilter);

        for (int i = 0; i < numberOfPolygons; i++)
        {
            IFeature feature = featureClass.GetFeature(i);

            // Get polygon.
            IGeometry geometry = feature.Shape;
            IPolygon polygon = (IPolygon)geometry;
        }

How to access the vertices (coordinates) of the rings of those polygons?

  • Have a look at IPointCollection for accessing the vertices of a polygon. – Hornbydd Jan 13 '18 at 12:47
  • I cannot find any method in ESRI.ArcGIS.Geometry.IPolygon and ESRI.ArcGIS.Geometry.Polygon classes that return a point collection. Do you know how to do it? Besides, I need to have access to polygon vertices for every polygon ring, but I cannot find how to access the rings as well. – Vitaliy Jan 13 '18 at 13:05
  • OK, now I am able to access the rings of a polygon using IPolygon4 polygon = feature.Shape as IPolygon4; IGeometryBag exteriorRings = polygon.ExteriorRingBag; – Vitaliy Jan 13 '18 at 13:42
2

The following c# ArcObjects code shows you how you access the individual vertices of a polygon ring.

                IPolygon4 polygon = currentFeature.Shape as IPolygon4;
                //IPolygon4.ExteriorRingBag should be used instead of IPolygon.QueryExteriorRings,
                //which does not work in .NET because of C-Style Arrays
                IGeometryBag exteriorRings = polygon.ExteriorRingBag;

                IEnumGeometry exteriorRingsEnum = exteriorRings as IEnumGeometry;
                exteriorRingsEnum.Reset();
                IRing currentExteriorRing = exteriorRingsEnum.Next() as IRing;

                //Create a point object for the Query methods
                //The point doesn't need to be created each time
                IPoint queryVertex = new PointClass();

                int counter = 1;
                System.Windows.Forms.MessageBox.Show("ExteriorRingCount = " + polygon.ExteriorRingCount);
                while (currentExteriorRing != null)
                {
                    IPointCollection pointCollection = currentExteriorRing as IPointCollection;
                    IEnumVertex enumVertex = pointCollection.EnumVertices as IEnumVertex;
                    if (enumVertex == null)
                    {
                        MessageBox.Show("NULL enumVertex!");
                        return;
                    }
                    enumVertex.Reset();

                    int partIndex;
                    int vertexIndex;

                    //Query the next vertex - have to create the point
                    //QueryNext is faster than Next, because the method doesn't have
                    //to create the point each time
                    enumVertex.QueryNext(queryVertex, out partIndex, out vertexIndex);

                    while (queryVertex != null)
                    {
                        string report = "X, Y : " + queryVertex.X + ", " + queryVertex.Y + " - Part Index : " + partIndex + " - Vertex Index : " + vertexIndex + "\n";

                        MessageBox.Show(report);
                        enumVertex.QueryNext(queryVertex, out partIndex, out vertexIndex);
                    }
                    ...
                }
  • Answers should have words in addition to code, explaining what was done and why it works. Links to documentation are not inappropriate. – Vince Jan 13 '18 at 15:19
  • For the one who has the same problem as I had I think it will be enough to look at the code in my answer. It provides a sequence of right method calls to achieve the result. As to your point "Why it works", I find it a philosophical question. – Vitaliy Jan 13 '18 at 15:29
  • Except they won't see it if the question is closed as non-reproducible. Understanding the philosophy of ArcObjects is critical to using it. If you can't explain that, it's not a good answer. – Vince Jan 13 '18 at 15:36
  • This is the answer that has solution to the problem. I think calling it not good is pedantic. Surely there are ways to improve it, but still this answer is what I was looking for and contains all information needed. – Vitaliy Jan 13 '18 at 15:42
  • 1
    It works but I think I should point out you don't need to EnumVertices from the point collection.. IPointCollection supports get_Point (index) resources.arcgis.com/en/help/arcobjects-net/componenthelp/… to access directly from the IPointCollection. Also, although it's helpful to see the exterior/interior ring code, if you don't need to get exterior/interior rings specifically you can iterate the rings from IGeometryCollection. Still, it works so it's worth a +1. – Michael Stimson Jan 16 '18 at 23:24
0

This C# code snippet allow you to loop over every vertices. Source: ArcObjects Library Reference (Geometry) IPolygon4.ExteriorRingBag Property

    public static void PolygonToString(IPolygon4 polygon)
    {
        IGeometryBag exteriorRingGeometryBag = polygon.ExteriorRingBag;
        IGeometryCollection exteriorRingGeometryCollection = exteriorRingGeometryBag as IGeometryCollection;
        Console.WriteLine("polygon.ExteriorRingCount = " + exteriorRingGeometryCollection.GeometryCount);
        for (int i = 0; i < exteriorRingGeometryCollection.GeometryCount; i++)
        {
            Console.WriteLine("polygon.ExteriorRing[" + i + "]");
            IGeometry exteriorRingGeometry = exteriorRingGeometryCollection.get_Geometry(i);
            IPointCollection exteriorRingPointCollection = exteriorRingGeometry as IPointCollection;
            for (int j = 0; j < exteriorRingPointCollection.PointCount; j++)
            {
                Console.WriteLine("Point[" + j + "] = " + PointToString(exteriorRingPointCollection.get_Point(j)));
            }
            IGeometryBag interiorRingGeometryBag = polygon.get_InteriorRingBag(exteriorRingGeometry as IRing);
            IGeometryCollection interiorRingGeometryCollection = interiorRingGeometryBag as IGeometryCollection;
            Console.WriteLine("polygon.InteriorRingCount[exteriorRing" + i + "] = " + interiorRingGeometryCollection.GeometryCount);
            for (int k = 0; k < interiorRingGeometryCollection.GeometryCount; k++)
            {
                Console.WriteLine("polygon.InteriorRing[" + k + "]");
                IGeometry interiorRingGeometry = interiorRingGeometryCollection.get_Geometry(k);
                IPointCollection interiorRingPointCollection = interiorRingGeometry as IPointCollection;
                for (int m = 0; m < interiorRingPointCollection.PointCount; m++)
                {
                    Console.WriteLine("Point[" + m + "] = " + PointToString(interiorRingPointCollection.get_Point(m)));
                }
            }
        }
    }


    private static string PointToString(IPoint point)
    {
        return (point.X + ", " + point.Y + ", " + point.Z);
    }

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.