Ticket #16262: 0001-Add-BuildingOutsideResidentialArea-test.patch

File 0001-Add-BuildingOutsideResidentialArea-test.patch, 5.4 KB (added by anonymous, 8 years ago)
  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

    From ff981bee8aca085ed862eaa3dd044eb291ab3259 Mon Sep 17 00:00:00 2001
    From: marxin <mliska@suse.cz>
    Date: Tue, 8 May 2018 13:30:46 +0200
    Subject: [PATCH] Add BuildingOutsideResidentialArea test.
    
    ---
     .../josm/data/validation/OsmValidator.java         |   2 +
     .../tests/BuildingOutsideResidentialArea.java      | 104 +++++++++++++++++++++
     2 files changed, 106 insertions(+)
     create mode 100644 src/org/openstreetmap/josm/data/validation/tests/BuildingOutsideResidentialArea.java
    
    diff --git a/src/org/openstreetmap/josm/data/validation/OsmValidator.java b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
    index 4c1def5ff..03bfab6ee 100644
    a b import org.openstreetmap.josm.data.validation.tests.UntaggedNode;  
    6464import org.openstreetmap.josm.data.validation.tests.UntaggedWay;
    6565import org.openstreetmap.josm.data.validation.tests.WayConnectedToArea;
    6666import org.openstreetmap.josm.data.validation.tests.WronglyOrderedWays;
     67import org.openstreetmap.josm.data.validation.tests.BuildingOutsideResidentialArea;
    6768import org.openstreetmap.josm.gui.MainApplication;
    6869import org.openstreetmap.josm.gui.layer.ValidatorLayer;
    6970import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
    public final class OsmValidator {  
    143144        PublicTransportRouteTest.class, // 3600 .. 3699
    144145        RightAngleBuildingTest.class, // 3700 .. 3799
    145146        BuildingSharingPointWith.class, // 3800 .. 3899
     147        BuildingOutsideResidentialArea.class, // 3900 .. 3999
    146148    };
    147149
    148150    /**
  • new file src/org/openstreetmap/josm/data/validation/tests/BuildingOutsideResidentialArea.java

    diff --git a/src/org/openstreetmap/josm/data/validation/tests/BuildingOutsideResidentialArea.java b/src/org/openstreetmap/josm/data/validation/tests/BuildingOutsideResidentialArea.java
    new file mode 100644
    index 000000000..e2d97874a
    - +  
     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.HashSet;
     7import java.util.List;
     8import java.util.Set;
     9import java.util.Collection;
     10import java.util.ArrayList;
     11
     12import org.openstreetmap.josm.data.osm.Node;
     13import org.openstreetmap.josm.data.osm.OsmPrimitive;
     14import org.openstreetmap.josm.data.osm.Way;
     15import org.openstreetmap.josm.data.validation.Severity;
     16import org.openstreetmap.josm.data.validation.Test;
     17import org.openstreetmap.josm.data.validation.TestError;
     18import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     19import org.openstreetmap.josm.tools.Geometry;
     20import org.openstreetmap.josm.spi.preferences.Config;
     21
     22/**
     23 * Checks for buildings that are not in a residential area.
     24 *
     25 * @since xxx
     26 */
     27public class BuildingOutsideResidentialArea extends Test {
     28  protected static final int BUILDING_OUTSIZE_RESIDENTIAL_AREA = 3901;
     29
     30    /**
     31     * Constructs a new {@code BuildingOutsideResidentialArea} test.
     32     */
     33    public BuildingOutsideResidentialArea() {
     34        super(tr("Building outside a residential area"), tr("Checks for building out of a residential area."));
     35    }
     36
     37    @Override
     38    public void visit(Collection<OsmPrimitive> selection) {
     39      double distance = Config.getPref().getDouble("validator.BuildingOutsideResidentialArea.minimalDistance", 50.0);
     40
     41      List<Way> buildings = new ArrayList<Way>();
     42      List<Way> residentialAreas = new ArrayList<Way>();
     43
     44      /*Filter out buildings and residential areas.  */
     45      for (OsmPrimitive p: selection) {
     46        if (p instanceof Way) {
     47          Way w = (Way)p;
     48          if (isBuilding(w))
     49            buildings.add(w);
     50          else if(isResidentialArea(w))
     51            residentialAreas.add(w);
     52        }
     53      }
     54
     55      /* Find all building that are not in a residential area.  */
     56      List<Way> buildingCandidates = new ArrayList<Way>();
     57
     58      for (Way b: buildings)
     59        if (!isInResidentialArea(b, residentialAreas))
     60          buildingCandidates.add(b);
     61
     62      /* Iterate all buildings and find these that are close to an other and are not
     63       * in a residential areas.  */
     64      for (Way b1: buildingCandidates) {
     65        for (Way b2: buildingCandidates)
     66          if (b1 != b2) {
     67            if (getBuildingsDistance(b1, b2) < distance) {
     68              addError(b1);
     69              break;
     70            }
     71          }
     72      }
     73    }
     74
     75    private boolean isInResidentialArea(Way building, List<Way> residentialAreas) {
     76      for (Node n: building.getNodes())
     77        for (Way r: residentialAreas)
     78          if (Geometry.nodeInsidePolygon(n, r.getNodes()))
     79            return true;
     80
     81      return false;
     82    }
     83
     84    private double getBuildingsDistance(Way b1, Way b2) {
     85      double minimalDistance = Double.MAX_VALUE;
     86
     87      for (Node n1: b1.getNodes())
     88        for (Node n2: b2.getNodes()) {
     89          double distance = n1.getEastNorth().distance(n2.getEastNorth());
     90          if (distance < minimalDistance)
     91            minimalDistance = distance;
     92        }
     93
     94      return minimalDistance;
     95    }
     96
     97    private void addError(Way building) {
     98      errors.add(TestError.builder(this, Severity.WARNING, BUILDING_OUTSIZE_RESIDENTIAL_AREA)
     99                .message(tr("Building outside a residential area"))
     100                .primitives(building)
     101                .highlight(building)
     102                .build());
     103    }
     104}