001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.validation.tests;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.util.Arrays;
007import java.util.HashSet;
008import java.util.Set;
009
010import org.openstreetmap.josm.data.osm.Node;
011import org.openstreetmap.josm.data.osm.Way;
012import org.openstreetmap.josm.data.validation.Severity;
013import org.openstreetmap.josm.data.validation.Test;
014import org.openstreetmap.josm.data.validation.TestError;
015
016/**
017 * Checks for self-intersecting ways.
018 */
019public class SelfIntersectingWay extends Test {
020
021    protected static final int SELF_INTERSECT = 401;
022
023    /**
024     * Constructs a new {@code SelfIntersectingWay} test.
025     */
026    public SelfIntersectingWay() {
027        super(tr("Self-intersecting ways"),
028                tr("This test checks for ways " +
029                        "that contain some of their nodes more than once."));
030    }
031
032    @Override
033    public void visit(Way w) {
034        Set<Node> nodes = new HashSet<>();
035
036        for (int i = 1; i < w.getNodesCount() - 1; i++) {
037            Node n = w.getNode(i);
038            if (nodes.contains(n)) {
039                errors.add(new TestError(this,
040                        Severity.WARNING, tr("Self-intersecting ways"), SELF_INTERSECT,
041                        Arrays.asList(w), Arrays.asList(n)));
042                break;
043            } else {
044                nodes.add(n);
045            }
046        }
047    }
048}