1

How can I automatically measure the angle for each corner of a polygon (in a vector GIS) using VBA and ArcObjets?

  • Note: With the corner I mean the point that joins two vertices of a polygon. – Demetris Jun 2 '11 at 5:03
  • Did you try IConstructAngle? – Kirk Kuykendall Jun 2 '11 at 14:49
  • Thanks for that. It needs some more thinking how to do it with a polygon. – Demetris Jun 2 '11 at 18:08
  • Just use maths Demetris; you need to find the gradient of the first line, then compare it to the second, etc; you don't even need the GIS, you just need to look at algorithms to find gradients of lines. It is so very easy – Hairy Jun 3 '11 at 7:04
3

As Kirk said, you can use IConstructAngle to do that.

Cast your geometry to IPointCollection and iterate over it (I did not tested this - and this should work only for simple polygons, without holes)

public class VertexAngleMeasure
{
    int _vertexId;
    double _angle;

    public int VertexId
    {
        get { return _vertexId; }
        set { _vertexId = value; }
    }

    public double Angle
    {
        get { return _angle; }
        set { _angle = value; }
    }

    public VertexAngleMeasure()
    { }

    public VertexAngleMeasure(int id, double angle)
    {
        _vertexId = id;
        _angle = angle;
    }
}

public class PolygonAngleMeasure
{
    IPolygon _polygon;
    List<VertexAngleMeasure> _measures;

    public static double RadiansToDegrees(double radians)
    {
        double degrees = radians * (180 / System.Math.PI);

        return degrees == 360 ? 0 : degrees;
    }

    public PolygonAngleMeasure(IPolygon poly)
    {
        _polygon = poly;
    }

    public void CalculateMeasures()
    {
        IGeometryEnvironment4 environment = new GeometryEnvironmentClass();
        IConstructAngle constructAngle = environment as IConstructAngle;

        IPointCollection pointCollection = _polygon as IPointCollection;

        double angle = 0;

        _measures.Clear();

        for (int i = 0; i <= pointCollection.PointCount - 1; i++)
        {
            if (i != 0 && i != pointCollection.PointCount - 1)
            {
                angle = constructAngle.ConstructThreePoint(
                    pointCollection.get_Point(i - 1),
                    pointCollection.get_Point(i),
                    pointCollection.get_Point(i + 1));
            }

            if (i == 0)
            {
                angle = constructAngle.ConstructThreePoint(
                    pointCollection.get_Point(pointCollection.PointCount - 1),
                    pointCollection.get_Point(0),
                    pointCollection.get_Point(1));
            }

            if (i == pointCollection.PointCount - 1)
            {
                angle = constructAngle.ConstructThreePoint(
                    pointCollection.get_Point(i - 1),
                    pointCollection.get_Point(i),
                    pointCollection.get_Point(0));
            }

            _measures.Add(new VertexAngleMeasure(i,RadiansToDegrees(angle)));
        }
    }
}
  • +1 This looks good, but I do wonder about the GeometryEnvironment class instantiation. The docs say it is a singleton, and this link says to use activator to instantiate singletons, but it doesn't have GeometryEnvironment in the list. Maybe a documentation error? – Kirk Kuykendall Jun 3 '11 at 16:50
  • Although I have not tried the code yet, at least I have something to base and try. Thanks for the contribution. – Demetris Jun 4 '11 at 9:00
  • I suppose that the code above is in VB.NET while I still use VBA (ArcObjects). – Demetris Jun 8 '11 at 14:36
  • I think it may be a documentation error. I had this for sometime, somewhere...I'm not sure why. Let me check it GeometryEnvironment can be instantiated. Demetris, the idea is for you see how it can be done. It can be easily translated to VBA. The point of the code it to show how to cast the polygon to a IPointCollection and iterate over it's vertices, finding out the internal angle of each vertex. – George Silva Jun 8 '11 at 16:43
2

You need to use ILine.angle property. Below is a code sample.

ILine Example

  • Although this example is useful is not the case I am asking for. Thanks – Demetris Jun 2 '11 at 18:09

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.