Ticket #16189: 0001-Introduce-almost-square-check-for-buildings.patch
File 0001-Introduce-almost-square-check-for-buildings.patch, 10.2 KB (added by , 6 years ago) |
---|
-
src/org/openstreetmap/josm/data/osm/Way.java
From dcf3f22e5a25361fb35e4c673b95457575a66ca3 Mon Sep 17 00:00:00 2001 From: marxin <mliska@suse.cz> Date: Sun, 4 Mar 2018 10:25:28 +0100 Subject: [PATCH] Introduce almost square check for buildings. --- src/org/openstreetmap/josm/data/osm/Way.java | 36 ++++++++++++ .../josm/data/validation/OsmValidator.java | 2 + .../validation/tests/RightAngleBuildingTest.java | 66 ++++++++++++++++++++++ src/org/openstreetmap/josm/tools/Geometry.java | 10 ++++ .../org/openstreetmap/josm/data/osm/WayTest.java | 1 + .../org/openstreetmap/josm/tools/GeometryTest.java | 36 ++++++++++++ 6 files changed, 151 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..f28cef9ff 100644
a b import org.openstreetmap.josm.data.osm.visitor.OsmPrimitiveVisitor; 15 15 import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor; 16 16 import org.openstreetmap.josm.spi.preferences.Config; 17 17 import org.openstreetmap.josm.tools.CopyList; 18 import org.openstreetmap.josm.tools.Geometry; 19 import org.openstreetmap.josm.tools.Logging; 18 20 import org.openstreetmap.josm.tools.Pair; 19 21 import org.openstreetmap.josm.tools.Utils; 20 22 … … public final class Way extends OsmPrimitive implements IWay { 805 807 n.clearCachedStyle(); 806 808 } 807 809 } 810 811 /** 812 * Returns angles of vertices. 813 * 814 * @return angles of the way 815 * @since xxx 816 */ 817 public List<Pair<Double, Node>> getAngles() { 818 List<Pair<Double, Node>> angles = new ArrayList<Pair<Double, Node>>(); 819 820 List<Node> nodes = getNodes(); 821 int count = getNodesCount(); 822 823 for (int i = 0; i < count; i++) 824 Logging.info(nodes.get(i).toString()); 825 826 for (int i = 1; i < count - 1; i++) 827 { 828 Node n0 = nodes.get(i - 1); 829 Node n1 = nodes.get(i); 830 Node n2 = nodes.get(i + 1); 831 832 double angle = Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle(n0.getEastNorth(), n1.getEastNorth(), 833 n2.getEastNorth())); 834 angles.add(new Pair<Double, Node>(angle, n1)); 835 } 836 837 angles.add(new Pair<Double, Node>(Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle( 838 nodes.get(count - 2).getEastNorth(), 839 nodes.get(0).getEastNorth(), 840 nodes.get(1).getEastNorth())), nodes.get(0))); 841 842 return angles; 843 } 808 844 } -
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; 52 52 import org.openstreetmap.josm.data.validation.tests.PowerLines; 53 53 import org.openstreetmap.josm.data.validation.tests.PublicTransportRouteTest; 54 54 import org.openstreetmap.josm.data.validation.tests.RelationChecker; 55 import org.openstreetmap.josm.data.validation.tests.RightAngleBuildingTest; 55 56 import org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay; 56 57 import org.openstreetmap.josm.data.validation.tests.SimilarNamedWays; 57 58 import org.openstreetmap.josm.data.validation.tests.TagChecker; … … public final class OsmValidator { 139 140 ApiCapabilitiesTest.class, // 3400 .. 3499 140 141 LongSegment.class, // 3500 .. 3599 141 142 PublicTransportRouteTest.class, // 3600 .. 3699 143 RightAngleBuildingTest.class, // 3700 .. 3799 142 144 }; 143 145 144 146 /** -
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..15ee55250
- + 1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.data.validation.tests; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import org.openstreetmap.josm.data.osm.Node; 7 import org.openstreetmap.josm.data.osm.Way; 8 import org.openstreetmap.josm.data.validation.Severity; 9 import org.openstreetmap.josm.data.validation.Test; 10 import org.openstreetmap.josm.data.validation.TestError; 11 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 12 import org.openstreetmap.josm.spi.preferences.Config; 13 import org.openstreetmap.josm.tools.Pair; 14 15 /** 16 * Checks for buildings with angles close to right angle. 17 * 18 * @since xxx 19 */ 20 public class RightAngleBuildingTest extends Test { 21 22 /** Maximum angle difference from right angle that is considered as invalid. */ 23 protected double maxAngleDelta; 24 25 /** Minimum angle difference from right angle that is considered as invalid. */ 26 protected double minAngleDelta; 27 28 /** 29 * Constructs a new {@code RightAngleBuildingTest} test. 30 */ 31 public RightAngleBuildingTest() { 32 super(tr("Almost right angle buildings"), 33 tr("Checks for buildings that have angles close to right angle and are not orthogonalized.")); 34 } 35 36 @Override 37 public void visit(Way w) { 38 if (!w.isUsable() || !w.isClosed() || !isBuilding(w)) return; 39 40 for (Pair<Double, Node> pair: w.getAngles()) 41 if (!checkAngle(w, pair.a, pair.b)) 42 return; 43 } 44 45 @Override 46 public void startTest(ProgressMonitor monitor) { 47 super.startTest(monitor); 48 maxAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.maximumDelta", 10.0); 49 minAngleDelta = Config.getPref().getDouble("validator.RightAngleBuilding.minimumDelta", 0.001); 50 } 51 52 private boolean checkAngle(Way w, double angle, Node n) { 53 double difference = Math.abs(angle - 90); 54 55 if (difference > minAngleDelta && difference < maxAngleDelta) { 56 errors.add(TestError.builder(this, Severity.WARNING, 3701) 57 .message(tr("Building with an almost square angle")) 58 .primitives(w) 59 .highlight(n) 60 .build()); 61 return false; 62 } 63 64 return true; 65 } 66 } -
src/org/openstreetmap/josm/tools/Geometry.java
diff --git a/src/org/openstreetmap/josm/tools/Geometry.java b/src/org/openstreetmap/josm/tools/Geometry.java index 379192e92..83e1771f5 100644
a b public final class Geometry { 792 792 return result; 793 793 } 794 794 795 /** Get angles in radians and return it's value in range [0, 180]. 796 * 797 * @param angle the angle in radians 798 * @return normalized angle 799 * @since xxx 800 */ 801 public static double getNormalizedAngleInDegrees(double angle) { 802 return Math.abs(180 * angle / Math.PI); 803 } 804 795 805 /** 796 806 * Compute the centroid/barycenter of nodes 797 807 * @param nodes Nodes for which the centroid is wanted -
test/unit/org/openstreetmap/josm/data/osm/WayTest.java
diff --git a/test/unit/org/openstreetmap/josm/data/osm/WayTest.java b/test/unit/org/openstreetmap/josm/data/osm/WayTest.java index e6c63c596..bcd51cddc 100644
a b import org.junit.BeforeClass; 11 11 import org.junit.Test; 12 12 import org.openstreetmap.josm.JOSMFixture; 13 13 import org.openstreetmap.josm.data.coor.LatLon; 14 import org.openstreetmap.josm.tools.Geometry; 14 15 15 16 /** 16 17 * Unit tests of the {@code Way} class. -
test/unit/org/openstreetmap/josm/tools/GeometryTest.java
diff --git a/test/unit/org/openstreetmap/josm/tools/GeometryTest.java b/test/unit/org/openstreetmap/josm/tools/GeometryTest.java index 1581e3cbd..d364a689b 100644
a b 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.tools; 3 3 4 import static org.junit.Assert.assertEquals; 5 4 6 import java.io.FileInputStream; 5 7 import java.util.List; 6 8 … … import org.junit.Rule; 9 11 import org.junit.Test; 10 12 import org.openstreetmap.josm.TestUtils; 11 13 import org.openstreetmap.josm.data.coor.EastNorth; 14 import org.openstreetmap.josm.data.coor.LatLon; 12 15 import org.openstreetmap.josm.data.osm.DataSet; 16 import org.openstreetmap.josm.data.osm.Node; 13 17 import org.openstreetmap.josm.data.osm.Relation; 14 18 import org.openstreetmap.josm.data.osm.Way; 15 19 import org.openstreetmap.josm.data.osm.search.SearchCompiler; … … public class GeometryTest { 108 112 Assert.assertEquals(15093.201209424187, areaAndPerimeter.getPerimeter(), 1e-3); 109 113 } 110 114 } 115 116 /** 117 * Test of {@link Geometry#getNormalizedAngleInDegrees(double) method. 118 */ 119 @Test 120 public void testRightAngle() { 121 Node n1 = new Node(1); 122 Node n2 = new Node(2); 123 Node n3 = new Node(3); 124 n1.setCoor(new LatLon(10.22873540462851, 6.169719398316592)); 125 n2.setCoor(new LatLon(10.229332494162811, 6.16978130985785)); 126 n3.setCoor(new LatLon(10.22924937004949, 6.17060908367496)); 127 128 double angle = Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle(n1.getEastNorth(), 129 n2.getEastNorth(), n3.getEastNorth())); 130 Assert.assertEquals(90, angle, 1e-8); 131 angle = Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle(n1.getEastNorth(), 132 n2.getEastNorth(), n1.getEastNorth())); 133 Assert.assertEquals(0, angle, 1e-8); 134 135 n1.setCoor(new LatLon(10.2295011, 6.1693106)); 136 n2.setCoor(new LatLon(10.2294958, 6.16930635)); 137 n3.setCoor(new LatLon(10.2294895, 6.1693039)); 138 139 angle = Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle(n1.getEastNorth(), 140 n2.getEastNorth(), n3.getEastNorth())); 141 Assert.assertEquals(162.66381817961337, angle, 1e-5); 142 143 angle = Geometry.getNormalizedAngleInDegrees(Geometry.getCornerAngle(n3.getEastNorth(), 144 n2.getEastNorth(), n1.getEastNorth())); 145 Assert.assertEquals(162.66381817961337, angle, 1e-5); 146 } 111 147 }