8

Now we are digitizing some buildings in specified area.

The obligatory rule for this work - in most cases buildings should have right angles.

We are using QGIS with CAD tools for this work but sometimes we make mistakes and create polygons with an irregular shape.

Does anybody know how can we find such polygons without right angles using open source GIS or ArcGIS?

2 Answers 2

5

I don't know of an existing tool to do this but you can write one in ArcPy or using GDAL/OGR along the following lines:

  • For each polygon...
    • Get the geometry
    • Follow the winding of the polygon and calculate the internal angle at each vertex
    • If any angle is not 90 degrees, add the FID/OID (or some other attribute) to a list of rejects
  • Print the list of rejects
2
  • 3
    +1 Having written similar code, I would recommend a slight modification. An angle spanned by extremely small line segments creates no (visual) problems. Also, angles very close to 90 degrees shouldn't be a problem either. This suggests computing the inner product of each edge with its predecessor. Compare the absolute value of the result to a (small positive) threshold. Flag polygons where that threshold is exceeded. This simultaneously allows largish deviations from 90 degrees for small edges as well as small deviations for large edges. As a bonus, you don't have to compute angles.
    – whuber
    Commented May 28, 2012 at 19:34
  • Anyone tried implementing the second line of @MappaGnosis answer?
    – b_jugger
    Commented Feb 21, 2020 at 13:58
2

Below is one possible approach. The function returns true or false depending if the polygon has any angles below a certain size or is within a range around a target angle. Just keep in mind this is a very simple approach and assumes straight line digitizing. I do test for a circle, but do not test for curves or other possibilities that could trip up the function.

angleTarget = desired angle (ex. 90).

edgeVariance = allowable waffle of straight line (ex. 0.5 degree direction change allowed).

angleVariance = allowable deviation of desired angle (ex. 1 if 91 degrees is OK).

Brian

private static bool AngleWithinTolerance(IPolygon pPoly, double angletarget, double edgeVariance, double angleVariance)
    {
        GeometryEnvironment geometryEnvironment = new GeometryEnvironment();
        IConstructAngle constructAngle = geometryEnvironment as IConstructAngle;
        IPointCollection ptcol = (IPointCollection)pPoly;
        double angle;

        //No circles!
        if (ptcol.PointCount < 3) return false;

        //Check angle made by last point first point and second point in the collection.
        angle = Math.Abs(constructAngle.ConstructThreePoint(ptcol.get_Point(ptcol.PointCount - 2), ptcol.get_Point(0), ptcol.get_Point(1)) * (180/3.14159250439667));
        if (angle < edgeVariance || (angle < angletarget + angleVariance & angle > angletarget - angleVariance))
        {
            //Angle at index 0 is OK - check all other points in collection.
            for (int x = 0; x != ptcol.PointCount - 2; x++)
            {
                angle = Math.Abs(constructAngle.ConstructThreePoint(ptcol.get_Point(x), ptcol.get_Point(x + 1), ptcol.get_Point(x + 2)) * (180 / 3.14159250439667));
                if (angle > edgeVariance & (angle > angletarget + angleVariance || angle < angletarget - angleVariance))
                {
                    return false;
                }
            }
        }
        else
        {
            return false;
        }
        //never failed.
        return true;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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