Ticket #13086: 13086.patch

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

     
    106106        CrossingWays.Ways.class, // ID  601 ..  699
    107107        CrossingWays.Boundaries.class, // ID  601 ..  699
    108108        CrossingWays.Barrier.class, // ID  601 ..  699
     109        CrossingWays.SelfIntersection.class, // ID  601 ..  699
    109110        SimilarNamedWays.class, // ID  701 ..  799
    110111        Coastlines.class, // ID  901 ..  999
    111112        WronglyOrderedWays.class, // ID 1001 .. 1099
  • src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java

     
    6666
    6767        @Override
    6868        boolean ignoreWaySegmentCombination(Way w1, Way w2) {
     69            if (w1 == w2)
     70                return true; // handled by self-intersection test
    6971            if (!Objects.equals(getLayer(w1), getLayer(w2))) {
    7072                return true;
    7173            }
     
    123125
    124126        @Override
    125127        boolean ignoreWaySegmentCombination(Way w1, Way w2) {
     128            if (w1 == w2)
     129                return true; // handled by self-intersection test
    126130            return !Objects.equals(w1.get("boundary"), w2.get("boundary"));
    127131        }
    128132
     
    140144    }
    141145
    142146    /**
     147     * Self intersecting ways test.
     148     */
     149    public static class SelfIntersection extends CrossingWays {
     150
     151        /**
     152         * Constructs a new SelfIntersection test.
     153         */
     154        public SelfIntersection() {
     155            super(tr("Self intersection"));
     156        }
     157
     158        @Override
     159        public boolean isPrimitiveUsable(OsmPrimitive p) {
     160            return p instanceof Way;
     161        }
     162
     163        @Override
     164        boolean ignoreWaySegmentCombination(Way w1, Way w2) {
     165            return (w1 != w2); // should not happen
     166        }
     167
     168        @Override
     169        String createMessage(Way w1, Way w2) {
     170            return tr("Self-intersecting ways");
     171        }
     172    }
     173
     174    /**
    143175     * Crossing barriers ways test.
    144176     */
    145177    public static class Barrier extends CrossingWays {
     
    158190
    159191        @Override
    160192        boolean ignoreWaySegmentCombination(Way w1, Way w2) {
     193            if (w1 == w2)
     194                return true; // handled by self-intersection test
    161195            if (!Objects.equals(getLayer(w1), getLayer(w2))) {
    162196                return true;
    163197            }
     
    220254
    221255    @Override
    222256    public void visit(Way w) {
     257        if (this instanceof SelfIntersection) {
     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;
     
    265304    /**
    266305     * Returns all the cells this segment crosses.  Each cell contains the list
    267306     * of segments already processed
    268      *
     307     * @param cellSegments map with already collected way segments
    269308     * @param n1 The first EastNorth
    270309     * @param n2 The second EastNorth
    271310     * @return A list with all the cells the segment crosses
    272311     */
    273     private List<List<WaySegment>> getSegments(EastNorth n1, EastNorth n2) {
     312    public static List<List<WaySegment>> getSegments(Map<Point2D, List<WaySegment>> cellSegments, EastNorth n1, EastNorth n2) {
    274313
    275314        List<List<WaySegment>> cells = new ArrayList<>();
    276315        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}