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.HashSet;
007import java.util.Set;
008
009import org.openstreetmap.josm.data.osm.Node;
010import org.openstreetmap.josm.data.osm.OsmPrimitive;
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 * Warn when a node has the same tags as its parent way. The check is rather
018 * conservative: it warns only when the tags are identical and important (i.e.,
019 * no warning for a way and a node that only have a "source=PGS" tag).
020 * <p>
021 * See JOSM ticket #7639 for the original request.
022 *
023 * @author Mrwojo
024 */
025public class NodesDuplicatingWayTags extends Test {
026
027    protected static final int NODE_DUPING_PARENT_WAY_TAGS = 2401;
028
029    /**
030     * Constructs a new {@code NodesDuplicatingWayTags} test.
031     */
032    public NodesDuplicatingWayTags() {
033        super(tr("Nodes duplicating way tags"),
034                tr("Checks for nodes that have the same tags as their parent way."));
035    }
036
037    @Override
038    public void visit(Way way) {
039        // isTagged represents interesting tags (not "source", "created_by", ...)
040        if (!way.isUsable() || !way.isTagged())
041            return;
042
043        // Use a set so you don't report the same node of an area/loop more than once.
044        Set<OsmPrimitive> dupedWayTags = new HashSet<OsmPrimitive>();
045
046        // Check for nodes in the way that have tags identical to the way's tags.
047        for (Node node : way.getNodes()) {
048            if (way.hasSameTags(node)) {
049                dupedWayTags.add(node);
050            }
051        }
052
053        if (!dupedWayTags.isEmpty()) {
054            // Add the way for the warning.
055            dupedWayTags.add(way);
056
057            errors.add(new TestError(this, Severity.WARNING, tr("Nodes duplicating parent way tags"),
058                    NODE_DUPING_PARENT_WAY_TAGS, dupedWayTags));
059        }
060    }
061}