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