Ticket #16283: 0001-Add-new-validation-test-for-broken-circle-buildings.patch

File 0001-Add-new-validation-test-for-broken-circle-buildings.patch, 4.6 KB (added by marxin, 8 years ago)

Updated version

  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

    From 2d2ca9f808a0c0e5d68f0c92430958af905307e7 Mon Sep 17 00:00:00 2001
    From: marxin <mliska@suse.cz>
    Date: Sun, 11 Mar 2018 16:50:27 +0100
    Subject: [PATCH] Add new validation test for broken circle buildings.
    
    ---
     .../josm/data/validation/OsmValidator.java         |  2 +
     .../data/validation/tests/BrokenCircleShape.java   | 86 ++++++++++++++++++++++
     2 files changed, 88 insertions(+)
     create mode 100644 src/org/openstreetmap/josm/data/validation/tests/BrokenCircleShape.java
    
    diff --git a/src/org/openstreetmap/josm/data/validation/OsmValidator.java b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
    index a173b49ef..21aa850be 100644
    a b import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper;  
    3333import org.openstreetmap.josm.data.validation.tests.Addresses;
    3434import org.openstreetmap.josm.data.validation.tests.ApiCapabilitiesTest;
    3535import org.openstreetmap.josm.data.validation.tests.BarriersEntrances;
     36import org.openstreetmap.josm.data.validation.tests.BrokenCircleShape;
    3637import org.openstreetmap.josm.data.validation.tests.Coastlines;
    3738import org.openstreetmap.josm.data.validation.tests.ConditionalKeys;
    3839import org.openstreetmap.josm.data.validation.tests.CrossingWays;
    public final class OsmValidator {  
    144145        PublicTransportRouteTest.class, // 3600 .. 3699
    145146        RightAngleBuildingTest.class, // 3700 .. 3799
    146147        BuildingOutsideResidentialArea.class, // 3800 .. 3899
     148        BrokenCircleShape.class, // 3900 .. 3999
    147149    };
    148150
    149151    /**
  • new file src/org/openstreetmap/josm/data/validation/tests/BrokenCircleShape.java

    diff --git a/src/org/openstreetmap/josm/data/validation/tests/BrokenCircleShape.java b/src/org/openstreetmap/josm/data/validation/tests/BrokenCircleShape.java
    new file mode 100644
    index 000000000..a306c70e8
    - +  
     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 java.util.List;
     7
     8import org.openstreetmap.josm.data.coor.EastNorth;
     9import org.openstreetmap.josm.data.osm.Node;
     10import org.openstreetmap.josm.data.osm.Way;
     11import org.openstreetmap.josm.data.validation.Severity;
     12import org.openstreetmap.josm.data.validation.Test;
     13import org.openstreetmap.josm.data.validation.TestError;
     14import org.openstreetmap.josm.spi.preferences.Config;
     15import org.openstreetmap.josm.tools.Pair;
     16
     17/**
     18 * Checks for circular buildings that have a deformed shape.
     19 *
     20 * @since xxx
     21 */
     22public class BrokenCircleShape extends Test {
     23  /**
     24   * Constructs a new {@code RightAngleBuildingTest} test.
     25   */
     26  public BrokenCircleShape() {
     27    super(tr("Broken circle shape"),
     28        tr("Checks for circular buildings that have a deformed shape."));
     29  }
     30
     31  @Override
     32  public void visit(Way w) {
     33    if (!w.isUsable() || !w.isClosed() || !isBuilding(w))
     34      return;
     35
     36    int count = w.getNodesCount() - 1;
     37    if (count <= 6)
     38      return;
     39
     40    /* Identify that the shape has most of nodes organized in a circle.  */
     41    double circleAngle = 180 * (count - 2) / count;
     42
     43    int matches = 0;
     44    double maximalAngleDifference = Config.getPref().getDouble("validator.BrokenCircleShape.maximalAngleDifference", 5);
     45    for (Pair<Double, Node> pair: w.getAngles())
     46      if (Math.abs(pair.a - circleAngle) < maximalAngleDifference)
     47        matches++;
     48
     49    /* Continue if most of the angles are fine.  */
     50    if (matches < count * 0.6)
     51      return;
     52
     53    double minRatio = Config.getPref().getDouble("validator.BrokenCircleShape.minimalRatio", 0.1);
     54
     55    /* Remove the last (closing) node of way. **/
     56    List<Node> nodes = w.getNodes ();
     57    nodes.remove (nodes.size () - 1);
     58
     59    double cx = 0;
     60    double cy = 0;
     61
     62    for (Node n: nodes) {
     63      cx += n.getEastNorth().east();
     64      cy += n.getEastNorth().north();
     65    }
     66
     67    Node center = new Node (new EastNorth(cx / count, cy / count));
     68
     69    double maxDistance = 0;
     70    double minDistance = Double.MAX_VALUE;
     71
     72    for (Node n: nodes) {
     73      double distance = center.getEastNorth ().distance (n.getEastNorth ());
     74      if (distance > maxDistance)
     75        maxDistance = distance;
     76      if (distance < minDistance)
     77        minDistance = distance;
     78    }
     79
     80    if ((1.0 - minDistance / maxDistance) > minRatio)
     81      errors.add(TestError.builder(this, Severity.WARNING, 3901)
     82          .message(tr("Broken circular shape"))
     83          .primitives(w)
     84          .build());
     85  }
     86}