From a26a0c0074b79aed918678be8cd09691fc2206ab Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Sun, 4 Mar 2018 14:14:31 +0100
Subject: [PATCH] Implement check for buildings sharing nodes with res. area or
 ways.

---
 .../josm/data/validation/OsmValidator.java         |  2 +
 .../validation/tests/BuildingSharingPointWith.java | 91 ++++++++++++++++++++++
 2 files changed, 93 insertions(+)
 create mode 100644 src/org/openstreetmap/josm/data/validation/tests/BuildingSharingPointWith.java

diff --git a/src/org/openstreetmap/josm/data/validation/OsmValidator.java b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
index 4cf70c621..4c1def5ff 100644
--- a/src/org/openstreetmap/josm/data/validation/OsmValidator.java
+++ b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
@@ -33,6 +33,7 @@ import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper;
 import org.openstreetmap.josm.data.validation.tests.Addresses;
 import org.openstreetmap.josm.data.validation.tests.ApiCapabilitiesTest;
 import org.openstreetmap.josm.data.validation.tests.BarriersEntrances;
+import org.openstreetmap.josm.data.validation.tests.BuildingSharingPointWith;
 import org.openstreetmap.josm.data.validation.tests.Coastlines;
 import org.openstreetmap.josm.data.validation.tests.ConditionalKeys;
 import org.openstreetmap.josm.data.validation.tests.CrossingWays;
@@ -141,6 +142,7 @@ public final class OsmValidator {
         LongSegment.class, // 3500 .. 3599
         PublicTransportRouteTest.class, // 3600 .. 3699
         RightAngleBuildingTest.class, // 3700 .. 3799
+        BuildingSharingPointWith.class, // 3800 .. 3899
     };
 
     /**
diff --git a/src/org/openstreetmap/josm/data/validation/tests/BuildingSharingPointWith.java b/src/org/openstreetmap/josm/data/validation/tests/BuildingSharingPointWith.java
new file mode 100644
index 000000000..f4c0bb821
--- /dev/null
+++ b/src/org/openstreetmap/josm/data/validation/tests/BuildingSharingPointWith.java
@@ -0,0 +1,91 @@
+// 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.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+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;
+
+/**
+ * Checks for buildings that have a points shared with a different objec
+ */
+public class BuildingSharingPointWith extends Test {
+    static final String HIGHWAY = "highway";
+
+    private Set<Way> visitedWays;
+
+    /**
+     * Constructs a new {@code BuildingSharingPointWith} test.
+     */
+    public BuildingSharingPointWith() {
+        super(tr("Building sharing points"), tr("Checks for building nodes being shared."));
+    }
+
+    @Override
+    public void visit(Way w) {
+        if (!w.isUsable() || !w.isClosed() || !isBuilding(w)) return;
+
+        visitedWays.add(w);
+
+        Set<OsmPrimitive> visitedPrimitives = new HashSet<>();
+        for (Node n: w.getNodes()) {
+            List<OsmPrimitive> r = n.getReferrers();
+
+            for (OsmPrimitive p : r) {
+                if (p != w && !visitedWays.contains(p)
+                        && !visitedPrimitives.contains(p)
+                        && isConflictCandidate(p))
+                {
+                    addError(w, p, n);
+                    visitedPrimitives.add(p);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void startTest(ProgressMonitor monitor) {
+        super.startTest(monitor);
+
+        visitedWays = new HashSet<>();
+    }
+
+    @Override
+    public void endTest() {
+        super.endTest();
+
+        visitedWays = null;
+    }
+
+    private boolean isConflictCandidate(OsmPrimitive p) {
+      return isBuilding(p) || isResidentialArea(p) || p.hasTag(HIGHWAY);
+    }
+
+    private String getMessage(OsmPrimitive p) {
+      if (isBuilding(p))
+        return tr("Building sharing point with a building");
+      else if(isResidentialArea(p))
+        return tr("Building sharing point with a residential area");
+      else if (p.hasTag(HIGHWAY))
+        return tr("Building sharing point with a highway");
+      else
+        throw new IllegalArgumentException();
+    }
+
+    private void addError(Way building, OsmPrimitive conflicting, Node sharedPoint) {
+        errors.add(TestError.builder(this, Severity.WARNING, 3801)
+                .message(getMessage(conflicting))
+                .primitives(building, sharedPoint)
+                .highlight(building)
+                .build());
+    }
+}
-- 
2.16.3

