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.ArrayList; 007import java.util.HashMap; 008import java.util.HashSet; 009import java.util.List; 010import java.util.Map; 011 012import org.openstreetmap.josm.data.osm.Node; 013import org.openstreetmap.josm.data.validation.Severity; 014import org.openstreetmap.josm.data.validation.Test; 015import org.openstreetmap.josm.data.validation.TestError; 016import org.openstreetmap.josm.gui.progress.ProgressMonitor; 017 018/** 019 * Finds nodes that have the same name (might be duplicates) 020 * @since 3669 021 */ 022public class NodesWithSameName extends Test { 023 protected static final int SAME_NAME = 801; 024 025 private Map<String, List<Node>> namesToNodes; 026 027 /** 028 * Constructs a new {@code NodesWithSameName} test. 029 */ 030 public NodesWithSameName() { 031 super(tr("Nodes with same name"), 032 tr("This test finds nodes that have the same name (might be duplicates).")); 033 } 034 035 @Override 036 public void startTest(ProgressMonitor monitor) { 037 super.startTest(monitor); 038 namesToNodes = new HashMap<String, List<Node>>(); 039 } 040 041 @Override 042 public void visit(Node n) { 043 if (!n.isUsable()) return; 044 045 String name = n.get("name"); 046 String sign = n.get("traffic_sign"); 047 String highway = n.get("highway"); 048 if (name == null || ("city_limit".equals(sign)) || ("bus_stop".equals(highway))) 049 return; 050 051 List<Node> nodes = namesToNodes.get(name); 052 if (nodes == null) { 053 namesToNodes.put(name, nodes = new ArrayList<Node>()); 054 } 055 056 nodes.add(n); 057 } 058 059 @Override 060 public void endTest() { 061 for (List<Node> nodes : namesToNodes.values()) { 062 if (nodes.size() > 1) { 063 // Report the same-name nodes, unless each has a unique ref=*. 064 HashSet<String> refs = new HashSet<String>(); 065 066 for (Node n : nodes) { 067 String ref = n.get("ref"); 068 if (ref == null || !refs.add(ref)) { 069 errors.add(new TestError(this, Severity.OTHER, 070 tr("Nodes with same name"), SAME_NAME, nodes)); 071 break; 072 } 073 } 074 } 075 } 076 super.endTest(); 077 namesToNodes = null; 078 } 079}