Index: trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java	(revision 13669)
+++ trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java	(revision 13670)
@@ -188,6 +188,7 @@
      * @return a rectifying command
      * @throws InvalidUserInputException if the selection is invalid
-     */
-    static SequenceCommand orthogonalize(Iterable<OsmPrimitive> selection) throws InvalidUserInputException {
+     * @since 13670
+     */
+    public static SequenceCommand orthogonalize(Iterable<OsmPrimitive> selection) throws InvalidUserInputException {
         final List<Node> nodeList = new ArrayList<>();
         final List<WayData> wayDataList = new ArrayList<>();
@@ -619,6 +620,7 @@
     /**
      * Exception: unsuited user input
-     */
-    protected static class InvalidUserInputException extends Exception {
+     * @since 13670
+     */
+    public static final class InvalidUserInputException extends Exception {
         InvalidUserInputException(String message) {
             super(message);
Index: trunk/src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 13669)
+++ trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 13670)
@@ -16,4 +16,5 @@
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.tools.CopyList;
+import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Utils;
@@ -780,3 +781,29 @@
         }
     }
+
+    /**
+     * Returns angles of vertices.
+     * @return angles of the way
+     * @since 13670
+     */
+    public synchronized List<Pair<Double, Node>> getAngles() {
+        List<Pair<Double, Node>> angles = new ArrayList<>();
+
+        for (int i = 1; i < nodes.length - 1; i++) {
+            Node n0 = nodes[i - 1];
+            Node n1 = nodes[i];
+            Node n2 = nodes[i + 1];
+
+            double angle = Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle(
+                    n0.getEastNorth(), n1.getEastNorth(), n2.getEastNorth()));
+            angles.add(new Pair<>(angle, n1));
+        }
+
+        angles.add(new Pair<>(Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle(
+                nodes[nodes.length - 2].getEastNorth(),
+                nodes[0].getEastNorth(),
+                nodes[1].getEastNorth())), nodes[0]));
+
+        return angles;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 13669)
+++ trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 13670)
@@ -53,4 +53,5 @@
 import org.openstreetmap.josm.data.validation.tests.PublicTransportRouteTest;
 import org.openstreetmap.josm.data.validation.tests.RelationChecker;
+import org.openstreetmap.josm.data.validation.tests.RightAngleBuildingTest;
 import org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay;
 import org.openstreetmap.josm.data.validation.tests.SimilarNamedWays;
@@ -141,4 +142,5 @@
         LongSegment.class, // 3500 .. 3599
         PublicTransportRouteTest.class, // 3600 .. 3699
+        RightAngleBuildingTest.class, // 3700 .. 3799
     };
 
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java	(revision 13670)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java	(revision 13670)
@@ -0,0 +1,81 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.validation.tests;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Collections;
+
+import org.openstreetmap.josm.actions.OrthogonalizeAction;
+import org.openstreetmap.josm.actions.OrthogonalizeAction.InvalidUserInputException;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.data.validation.Severity;
+import org.openstreetmap.josm.data.validation.Test;
+import org.openstreetmap.josm.data.validation.TestError;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.spi.preferences.Config;
+import org.openstreetmap.josm.tools.Logging;
+import org.openstreetmap.josm.tools.Pair;
+
+/**
+ * Checks for buildings with angles close to right angle.
+ *
+ * @author marxin
+ * @since 13670
+ */
+public class RightAngleBuildingTest extends Test {
+
+    /** Maximum angle difference from right angle that is considered as invalid. */
+    protected double maxAngleDelta;
+
+    /** Minimum angle difference from right angle that is considered as invalid. */
+    protected double minAngleDelta;
+
+    /**
+     * Constructs a new {@code RightAngleBuildingTest} test.
+     */
+    public RightAngleBuildingTest() {
+        super(tr("Almost right angle buildings"),
+                tr("Checks for buildings that have angles close to right angle and are not orthogonalized."));
+    }
+
+    @Override
+    public void visit(Way w) {
+        if (!w.isUsable() || !w.isClosed() || !isBuilding(w)) return;
+
+        for (Pair<Double, Node> pair: w.getAngles()) {
+            if (!checkAngle(w, pair.a, pair.b))
+                return;
+        }
+    }
+
+    @Override
+    public void startTest(ProgressMonitor monitor) {
+        super.startTest(monitor);
+        maxAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.maximumDelta", 10.0);
+        minAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.minimumDelta", 0.001);
+    }
+
+    private boolean checkAngle(Way w, double angle, Node n) {
+        double difference = Math.abs(angle - 90);
+
+        if (difference > minAngleDelta && difference < maxAngleDelta) {
+            errors.add(TestError.builder(this, Severity.WARNING, 3701)
+                    .message(tr("Building with an almost square angle"))
+                    .primitives(w)
+                    .highlight(n)
+                    .fix(() -> {
+                        try {
+                            return OrthogonalizeAction.orthogonalize(Collections.singleton(w));
+                        } catch (InvalidUserInputException e) {
+                            Logging.warn(e);
+                            return null;
+                        }
+                    })
+                    .build());
+            return false;
+        }
+
+        return true;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/tools/Geometry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 13669)
+++ trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 13670)
@@ -794,4 +794,15 @@
 
         return result;
+    }
+
+    /** 
+     * Get angles in radians and return it's value in range [0, 180].
+     *
+     * @param angle the angle in radians
+     * @return normalized angle in degrees
+     * @since 13670
+     */
+    public static double getNormalizedAngleInDegrees(double angle) {
+        return Math.abs(180 * angle / Math.PI);
     }
 
