Ticket #13086: 13086_v2.patch

File 13086_v2.patch, 10.5 KB (added by GerdP, 3 years ago)
  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

     
    104104        CrossingWays.Ways.class, // ID  601 ..  699
    105105        CrossingWays.Boundaries.class, // ID  601 ..  699
    106106        CrossingWays.Barrier.class, // ID  601 ..  699
     107        CrossingWays.SelfCrossing.class, // ID  601 ..  699
    107108        SimilarNamedWays.class, // ID  701 ..  799
    108109        Coastlines.class, // ID  901 ..  999
    109110        WronglyOrderedWays.class, // ID 1001 .. 1099
  • src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java

     
    55
    66import java.awt.geom.Point2D;
    77import java.util.ArrayList;
    8 import java.util.Arrays;
    98import java.util.HashMap;
    109import java.util.List;
    1110import java.util.Map;
     
    6665
    6766        @Override
    6867        boolean ignoreWaySegmentCombination(Way w1, Way w2) {
     68            if (w1 == w2)
     69                return false;
    6970            if (!Objects.equals(getLayer(w1), getLayer(w2))) {
    7071                return true;
    7172            }
     
    171172    }
    172173
    173174    /**
     175     * Self crossing ways test (for all the rest)
     176     */
     177    public static class SelfCrossing extends CrossingWays {
     178        CrossingWays.Ways normalTest = new Ways();
     179        CrossingWays.Barrier barrierTest = new Barrier();
     180        CrossingWays.Boundaries boundariesTest = new Boundaries();
     181
     182        /**
     183         * Constructs a new SelfIntersection test.
     184         */
     185        public SelfCrossing() {
     186            super(tr("Self crossing"));
     187        }
     188
     189        @Override
     190        public boolean isPrimitiveUsable(OsmPrimitive p) {
     191            return super.isPrimitiveUsable(p) && !(normalTest.isPrimitiveUsable(p) || barrierTest.isPrimitiveUsable(p)
     192                    || boundariesTest.isPrimitiveUsable(p));
     193        }
     194
     195        @Override
     196        boolean ignoreWaySegmentCombination(Way w1, Way w2) {
     197            return (w1 != w2); // should not happen
     198        }
     199
     200        @Override
     201        String createMessage(Way w1, Way w2) {
     202            return tr("Self-crossing ways");
     203        }
     204    }
     205
     206
     207    /**
    174208     * Constructs a new {@code CrossingWays} test.
    175209     * @param title The test title
    176210     * @since 6691
     
    220254
    221255    @Override
    222256    public void visit(Way w) {
     257        if (this instanceof SelfCrossing) {
     258            // free memory, we are not interested in previous ways
     259            cellSegments.clear();
     260            seenWays.clear();
     261        }
    223262
    224263        int nodesSize = w.getNodesCount();
    225264        for (int i = 0; i < nodesSize - 1; i++) {
     
    230269                Main.warn("Crossing ways test skipped "+es1);
    231270                continue;
    232271            }
    233             for (List<WaySegment> segments : getSegments(en1, en2)) {
     272            for (List<WaySegment> segments : getSegments(cellSegments, en1, en2)) {
    234273                for (WaySegment es2 : segments) {
    235274                    List<Way> prims;
    236275                    List<WaySegment> highlight;
     
    239278                        continue;
    240279                    }
    241280
    242                     prims = Arrays.asList(es1.way, es2.way);
     281                    prims = new ArrayList<>();
     282                    prims.add(es1.way);
     283                    if (es1.way != es2.way)
     284                        prims.add(es2.way);
    243285                    if ((highlight = seenWays.get(prims)) == null) {
    244286                        highlight = new ArrayList<>();
    245287                        highlight.add(es1);
     
    265307    /**
    266308     * Returns all the cells this segment crosses.  Each cell contains the list
    267309     * of segments already processed
    268      *
     310     * @param cellSegments map with already collected way segments
    269311     * @param n1 The first EastNorth
    270312     * @param n2 The second EastNorth
    271313     * @return A list with all the cells the segment crosses
    272314     */
    273     private List<List<WaySegment>> getSegments(EastNorth n1, EastNorth n2) {
     315    public static List<List<WaySegment>> getSegments(Map<Point2D, List<WaySegment>> cellSegments, EastNorth n1, EastNorth n2) {
    274316
    275317        List<List<WaySegment>> cells = new ArrayList<>();
    276318        for (Point2D cell : ValUtil.getSegmentCells(n1, n2, OsmValidator.griddetail)) {
  • src/org/openstreetmap/josm/data/validation/tests/SelfIntersectingWay.java

     
    3232    @Override
    3333    public void visit(Way w) {
    3434        Set<Node> nodes = new HashSet<>();
    35 
    36         for (int i = 1; i < w.getNodesCount() - 1; i++) {
     35        int last = w.getNodesCount();
     36        if (last < 2)
     37            return;
     38        if (w.firstNode() == w.lastNode())
     39            last--; // closed way, ignore last node
     40        nodes.add(w.firstNode());
     41        for (int i = 1; i < last; i++) {
    3742            Node n = w.getNode(i);
    3843            if (nodes.contains(n)) {
    3944                errors.add(new TestError(this,
  • test/unit/org/openstreetmap/josm/data/validation/tests/SelfIntersectingWayTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import java.util.ArrayList;
     5import java.util.List;
     6
     7import org.junit.Assert;
     8import org.junit.BeforeClass;
     9import org.junit.Test;
     10import org.openstreetmap.josm.JOSMFixture;
     11import org.openstreetmap.josm.data.coor.LatLon;
     12import org.openstreetmap.josm.data.osm.Node;
     13import org.openstreetmap.josm.data.osm.OsmUtils;
     14import org.openstreetmap.josm.data.osm.Way;
     15
     16/**
     17 * JUnit Test of Multipolygon validation test.
     18 */
     19public class SelfIntersectingWayTest {
     20
     21    /**
     22     * Setup test.
     23     * @throws Exception if test cannot be initialized
     24     */
     25    @BeforeClass
     26    public static void setUp() throws Exception {
     27        JOSMFixture.createUnitTestFixture().init(true);
     28    }
     29
     30    private static List<Node> createNodes() {
     31        List<Node> nodes = new ArrayList<>();
     32        for (int i = 0; i < 5; i++) {
     33            nodes.add(new Node(i+1));
     34        }
     35        nodes.get(0).setCoor(new LatLon(34.2680878298, 133.56336369008));
     36        nodes.get(1).setCoor(new LatLon(34.25096598132, 133.54891792012));
     37        nodes.get(2).setCoor(new LatLon(34.24466741332, 133.56693544639));
     38        nodes.get(3).setCoor(new LatLon(34.26815342405, 133.56066502976));
     39        nodes.get(4).setCoor(new LatLon(34.26567411471, 133.56132705125));
     40        return nodes;
     41    }
     42
     43
     44    /**
     45     * Self-Intersection at first (+ last) node of closed way
     46     */
     47    @Test
     48    public void TestClosedWay() {
     49        List<Node> nodes = createNodes();
     50
     51        Way w = (Way) OsmUtils.createPrimitive("way ");
     52        List<Node> wayNodes = new ArrayList<>();
     53        wayNodes.add(nodes.get(0));
     54        wayNodes.add(nodes.get(1));
     55        wayNodes.add(nodes.get(2));
     56        wayNodes.add(nodes.get(0)); // problem
     57        wayNodes.add(nodes.get(3));
     58        wayNodes.add(nodes.get(4));
     59        wayNodes.add(nodes.get(0));
     60        w.setNodes(wayNodes);
     61        SelfIntersectingWay test = new SelfIntersectingWay();
     62        test.visit(w);
     63        Assert.assertEquals(1, test.getErrors().size());
     64        Assert.assertTrue(test.getErrors().iterator().next().getHighlighted().contains(nodes.get(0)));
     65    }
     66
     67    /**
     68     * Self-Intersection at first node of unclosed way
     69     */
     70    @Test
     71    public void TestUnclosedWayFirst() {
     72        List<Node> nodes = createNodes();
     73
     74        Way w = (Way) OsmUtils.createPrimitive("way ");
     75        List<Node> wayNodes = new ArrayList<>();
     76        wayNodes.add(nodes.get(0));
     77        wayNodes.add(nodes.get(1));
     78        wayNodes.add(nodes.get(2));
     79        wayNodes.add(nodes.get(0)); // problem
     80        wayNodes.add(nodes.get(3));
     81        wayNodes.add(nodes.get(4));
     82        w.setNodes(wayNodes);
     83        SelfIntersectingWay test = new SelfIntersectingWay();
     84        test.visit(w);
     85        Assert.assertEquals(1, test.getErrors().size());
     86        Assert.assertTrue(test.getErrors().iterator().next().getHighlighted().contains(nodes.get(0)));
     87    }
     88
     89    /**
     90     * Self-Intersection at first node of unclosed way
     91     */
     92    @Test
     93    public void TestUnclosedWayLast() {
     94        List<Node> nodes = createNodes();
     95
     96        Way w = (Way) OsmUtils.createPrimitive("way ");
     97        List<Node> wayNodes = new ArrayList<>();
     98        wayNodes.add(nodes.get(0));
     99        wayNodes.add(nodes.get(1)); // problem
     100        wayNodes.add(nodes.get(2));
     101        wayNodes.add(nodes.get(3));
     102        wayNodes.add(nodes.get(4));
     103        wayNodes.add(nodes.get(1));
     104        w.setNodes(wayNodes);
     105        SelfIntersectingWay test = new SelfIntersectingWay();
     106        test.visit(w);
     107        Assert.assertEquals(1, test.getErrors().size());
     108        Assert.assertTrue(test.getErrors().iterator().next().getHighlighted().contains(nodes.get(1)));
     109    }
     110
     111    /**
     112     * Self-Intersection at normal node (not first / last)
     113     */
     114    @Test
     115    public void TestUnclosedWayNormal() {
     116        List<Node> nodes = createNodes();
     117
     118        Way w = (Way) OsmUtils.createPrimitive("way ");
     119        List<Node> wayNodes = new ArrayList<>();
     120        wayNodes.add(nodes.get(0));
     121        wayNodes.add(nodes.get(1));
     122        wayNodes.add(nodes.get(2));
     123        wayNodes.add(nodes.get(1)); // problem
     124        wayNodes.add(nodes.get(3));
     125        wayNodes.add(nodes.get(4));
     126        w.setNodes(wayNodes);
     127        SelfIntersectingWay test = new SelfIntersectingWay();
     128        test.visit(w);
     129        Assert.assertEquals(1, test.getErrors().size());
     130        Assert.assertTrue(test.getErrors().iterator().next().getHighlighted().contains(nodes.get(1)));
     131    }
     132
     133}