Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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 GIS or ArcGIS?

share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

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
share|improve this answer
2  
+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 May 28 '12 at 19:34
add comment

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;
    }
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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