001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.data.validation.tests;
003    
004    import static org.openstreetmap.josm.tools.I18n.tr;
005    
006    import java.util.HashSet;
007    import java.util.Set;
008    
009    import org.openstreetmap.josm.data.osm.Node;
010    import org.openstreetmap.josm.data.osm.OsmPrimitive;
011    import org.openstreetmap.josm.data.osm.Way;
012    import org.openstreetmap.josm.data.validation.Severity;
013    import org.openstreetmap.josm.data.validation.Test;
014    import 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     */
025    public class NodesDuplicatingWayTags extends Test {
026    
027        protected static final int NODE_DUPING_PARENT_WAY_TAGS = 2401;
028    
029        public NodesDuplicatingWayTags() {
030            super(tr("Nodes duplicating way tags"),
031                    tr("Checks for nodes that have the same tags as their parent way."));
032        }
033    
034        @Override
035        public void visit(Way way) {
036            // isTagged represents interesting tags (not "source", "created_by", ...)
037            if (!way.isUsable() || !way.isTagged())
038                return;
039    
040            // Use a set so you don't report the same node of an area/loop more than once.
041            Set<OsmPrimitive> dupedWayTags = new HashSet<OsmPrimitive>();
042    
043            // Check for nodes in the way that have tags identical to the way's tags.
044            for (Node node : way.getNodes()) {
045                if (way.hasSameTags(node)) {
046                    dupedWayTags.add(node);
047                }
048            }
049    
050            if (!dupedWayTags.isEmpty()) {
051                // Add the way for the warning.
052                dupedWayTags.add(way);
053    
054                errors.add(new TestError(this, Severity.WARNING, tr("Nodes duplicating parent way tags"),
055                        NODE_DUPING_PARENT_WAY_TAGS, dupedWayTags));
056            }
057        }
058    }