Ticket #16189: 0002-Introduce-almost-square-check-for-buildings.patch

File 0002-Introduce-almost-square-check-for-buildings.patch, 6.1 KB (added by marxin, 7 years ago)
  • src/org/openstreetmap/josm/data/osm/Way.java

    From 9a3aaeb5fd7f4473c057cce17d51f0b93b6eb8a3 Mon Sep 17 00:00:00 2001
    From: marxin <mliska@suse.cz>
    Date: Sun, 4 Mar 2018 10:25:28 +0100
    Subject: [PATCH 2/2] Introduce almost square check for buildings.
    
    ---
     src/org/openstreetmap/josm/data/osm/Way.java       | 32 +++++++++++
     .../josm/data/validation/OsmValidator.java         |  2 +
     .../validation/tests/RightAngleBuildingTest.java   | 64 ++++++++++++++++++++++
     3 files changed, 98 insertions(+)
     create mode 100644 src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java
    
    diff --git a/src/org/openstreetmap/josm/data/osm/Way.java b/src/org/openstreetmap/josm/data/osm/Way.java
    index 8fd0cef49..4203f7f71 100644
    a b import org.openstreetmap.josm.data.osm.visitor.OsmPrimitiveVisitor;  
    1515import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
    1616import org.openstreetmap.josm.spi.preferences.Config;
    1717import org.openstreetmap.josm.tools.CopyList;
     18import org.openstreetmap.josm.tools.Geometry;
     19import org.openstreetmap.josm.tools.Logging;
    1820import org.openstreetmap.josm.tools.Pair;
    1921import org.openstreetmap.josm.tools.Utils;
    2022
    public final class Way extends OsmPrimitive implements IWay {  
    805807            n.clearCachedStyle();
    806808        }
    807809    }
     810
     811    private double getNormalizedAngleInDegrees(double angle) {
     812        angle = Math.abs(180 * angle / Math.PI);
     813        return angle;
     814    }
     815
     816    public List<Pair<Double, Node>> getAngles() {
     817        List<Pair<Double, Node>> angles = new ArrayList<Pair<Double, Node>>();
     818
     819        List<Node> nodes = getNodes();
     820        int count = getNodesCount();
     821
     822        for (int i = 1; i < count - 1; i++)
     823        {
     824            Node n0 = nodes.get(i - 1);
     825            Node n1 = nodes.get(i);
     826            Node n2 = nodes.get(i + 1);
     827
     828            double angle = getNormalizedAngleInDegrees(Geometry.getCornerAngle(n0.getEastNorth(), n1.getEastNorth(),
     829                    n2.getEastNorth()));
     830            angles.add(new Pair<Double, Node>(angle, n1));
     831        }
     832
     833        angles.add(new Pair<Double, Node>(getNormalizedAngleInDegrees(Geometry.getCornerAngle(
     834                nodes.get(count - 2).getEastNorth(),
     835                nodes.get(0).getEastNorth(),
     836                nodes.get(1).getEastNorth())), nodes.get(0)));
     837
     838        return angles;
     839    }
    808840}
  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

    diff --git a/src/org/openstreetmap/josm/data/validation/OsmValidator.java b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
    index 30a2661fe..4cf70c621 100644
    a b import org.openstreetmap.josm.data.validation.tests.OverlappingWays;  
    5252import org.openstreetmap.josm.data.validation.tests.PowerLines;
    5353import org.openstreetmap.josm.data.validation.tests.PublicTransportRouteTest;
    5454import org.openstreetmap.josm.data.validation.tests.RelationChecker;
     55import org.openstreetmap.josm.data.validation.tests.RightAngleBuildingTest;
    5556import org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay;
    5657import org.openstreetmap.josm.data.validation.tests.SimilarNamedWays;
    5758import org.openstreetmap.josm.data.validation.tests.TagChecker;
    public final class OsmValidator {  
    139140        ApiCapabilitiesTest.class, // 3400 .. 3499
    140141        LongSegment.class, // 3500 .. 3599
    141142        PublicTransportRouteTest.class, // 3600 .. 3699
     143        RightAngleBuildingTest.class, // 3700 .. 3799
    142144    };
    143145
    144146    /**
  • new file src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java

    diff --git a/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java b/src/org/openstreetmap/josm/data/validation/tests/RightAngleBuildingTest.java
    new file mode 100644
    index 000000000..3779dfc84
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import org.openstreetmap.josm.data.osm.Node;
     7import org.openstreetmap.josm.data.osm.Way;
     8import org.openstreetmap.josm.data.validation.Severity;
     9import org.openstreetmap.josm.data.validation.Test;
     10import org.openstreetmap.josm.data.validation.TestError;
     11import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     12import org.openstreetmap.josm.spi.preferences.Config;
     13import org.openstreetmap.josm.tools.Pair;
     14
     15/**
     16 * Checks for buildings with angles close to right angle.
     17 */
     18public class RightAngleBuildingTest extends Test {
     19
     20    /** Maximum angle difference from right angle that is considered as invalid. */
     21    protected double maxAngleDelta;
     22
     23    /** Minimum angle difference from right angle that is considered as invalid. */
     24    protected double minAngleDelta;
     25
     26    /**
     27     * Constructs a new {@code RightAngleBuildingTest} test.
     28     */
     29    public RightAngleBuildingTest() {
     30        super(tr("Almost right angle buildings"),
     31                tr("Checks for buildings that have angles close to right angle and are not orthogonalized."));
     32    }
     33
     34    @Override
     35    public void visit(Way w) {
     36        if (!w.isUsable() || !w.isClosed() || !isBuilding(w)) return;
     37
     38        for (Pair<Double, Node> pair: w.getAngles())
     39            if (!checkAngle(w, pair.a, pair.b))
     40                return;
     41    }
     42
     43    @Override
     44    public void startTest(ProgressMonitor monitor) {
     45        super.startTest(monitor);
     46        maxAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.maximumDelta", 10.0);
     47        minAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.minimumDelta", 0.001);
     48    }
     49
     50    private boolean checkAngle(Way w, double angle, Node n) {
     51        double difference = Math.abs(angle - 90);
     52
     53        if (difference > minAngleDelta && difference < maxAngleDelta) {
     54            errors.add(TestError.builder(this, Severity.WARNING, 3701)
     55                    .message(tr("Building with an almost square angle"))
     56                    .primitives(w)
     57                    .highlight(n)
     58                    .build());
     59            return false;
     60        }
     61
     62        return true;
     63    }
     64}