source: josm/trunk/src/org/openstreetmap/josm/data/validation/tests/UntaggedWay.java@ 12941

Last change on this file since 12941 was 12691, checked in by Don-vip, 7 years ago

see #15182 - introduce Main.getEditDataSet to avoid unneeded GUI dependence in validator tests and tagging presets

  • Property svn:eol-style set to native
File size: 6.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.validation.tests;
3
4import static org.openstreetmap.josm.data.validation.tests.CrossingWays.HIGHWAY;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.util.HashSet;
8import java.util.Map;
9import java.util.Set;
10
11import org.openstreetmap.josm.Main;
12import org.openstreetmap.josm.command.Command;
13import org.openstreetmap.josm.data.osm.DataSet;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.data.osm.Relation;
16import org.openstreetmap.josm.data.osm.RelationMember;
17import org.openstreetmap.josm.data.osm.Way;
18import org.openstreetmap.josm.data.validation.Severity;
19import org.openstreetmap.josm.data.validation.Test;
20import org.openstreetmap.josm.data.validation.TestError;
21import org.openstreetmap.josm.gui.progress.ProgressMonitor;
22
23/**
24 * Checks for untagged ways
25 *
26 * @author frsantos
27 */
28public class UntaggedWay extends Test {
29
30 // CHECKSTYLE.OFF: SingleSpaceSeparator
31 /** Empty way error */
32 protected static final int EMPTY_WAY = 301;
33 /** Untagged way error */
34 protected static final int UNTAGGED_WAY = 302;
35 /** Unnamed way error */
36 protected static final int UNNAMED_WAY = 303;
37 /** One node way error */
38 protected static final int ONE_NODE_WAY = 304;
39 /** Unnamed junction error */
40 protected static final int UNNAMED_JUNCTION = 305;
41 /** Untagged, but commented way error */
42 protected static final int COMMENTED_WAY = 306;
43 // CHECKSTYLE.ON: SingleSpaceSeparator
44
45 private Set<Way> waysUsedInRelations;
46
47 /** Ways that must have a name */
48 static final Set<String> NAMED_WAYS = new HashSet<>();
49 static {
50 NAMED_WAYS.add("motorway");
51 NAMED_WAYS.add("trunk");
52 NAMED_WAYS.add("primary");
53 NAMED_WAYS.add("secondary");
54 NAMED_WAYS.add("tertiary");
55 NAMED_WAYS.add("residential");
56 NAMED_WAYS.add("pedestrian");
57 }
58
59 /** Whitelist of roles allowed to reference an untagged way */
60 static final Set<String> WHITELIST = new HashSet<>();
61 static {
62 WHITELIST.add("outer");
63 WHITELIST.add("inner");
64 WHITELIST.add("perimeter");
65 WHITELIST.add("edge");
66 WHITELIST.add("outline");
67 }
68
69 /**
70 * Constructor
71 */
72 public UntaggedWay() {
73 super(tr("Untagged, empty and one node ways"),
74 tr("This test checks for untagged, empty and one node ways."));
75 }
76
77 @Override
78 public void visit(Way w) {
79 if (!w.isUsable())
80 return;
81
82 Map<String, String> tags = w.getKeys();
83 if (!tags.isEmpty()) {
84 String highway = tags.get(HIGHWAY);
85 if (highway != null && NAMED_WAYS.contains(highway) && !tags.containsKey("name") && !tags.containsKey("ref")
86 && !"yes".equals(tags.get("noname"))) {
87 boolean isJunction = false;
88 boolean hasName = false;
89 for (String key : tags.keySet()) {
90 hasName = key.startsWith("name:") || key.endsWith("_name") || key.endsWith("_ref");
91 if (hasName) {
92 break;
93 }
94 if ("junction".equals(key)) {
95 isJunction = true;
96 break;
97 }
98 }
99
100 if (!hasName && !isJunction) {
101 errors.add(TestError.builder(this, Severity.WARNING, UNNAMED_WAY)
102 .message(tr("Unnamed ways"))
103 .primitives(w)
104 .build());
105 } else if (isJunction) {
106 errors.add(TestError.builder(this, Severity.OTHER, UNNAMED_JUNCTION)
107 .message(tr("Unnamed junction"))
108 .primitives(w)
109 .build());
110 }
111 }
112 }
113
114 if (!w.isTagged() && !waysUsedInRelations.contains(w)) {
115 if (w.hasKeys()) {
116 errors.add(TestError.builder(this, Severity.WARNING, COMMENTED_WAY)
117 .message(tr("Untagged ways (commented)"))
118 .primitives(w)
119 .build());
120 } else {
121 errors.add(TestError.builder(this, Severity.WARNING, UNTAGGED_WAY)
122 .message(tr("Untagged ways"))
123 .primitives(w)
124 .build());
125 }
126 }
127
128 if (w.getNodesCount() == 0) {
129 errors.add(TestError.builder(this, Severity.ERROR, EMPTY_WAY)
130 .message(tr("Empty ways"))
131 .primitives(w)
132 .build());
133 } else if (w.getNodesCount() == 1) {
134 errors.add(TestError.builder(this, Severity.ERROR, ONE_NODE_WAY)
135 .message(tr("One node ways"))
136 .primitives(w)
137 .build());
138 }
139 }
140
141 @Override
142 public void startTest(ProgressMonitor monitor) {
143 super.startTest(monitor);
144 DataSet ds = Main.main.getEditDataSet();
145 if (ds == null)
146 return;
147 waysUsedInRelations = new HashSet<>();
148 for (Relation r : ds.getRelations()) {
149 if (r.isUsable()) {
150 for (RelationMember m : r.getMembers()) {
151 if (r.isMultipolygon() || WHITELIST.contains(m.getRole())) {
152 OsmPrimitive member = m.getMember();
153 if (member instanceof Way && member.isUsable() && !member.isTagged()) {
154 waysUsedInRelations.add((Way) member);
155 }
156 }
157 }
158 }
159 }
160 }
161
162 @Override
163 public void endTest() {
164 waysUsedInRelations = null;
165 super.endTest();
166 }
167
168 @Override
169 public boolean isFixable(TestError testError) {
170 if (testError.getTester() instanceof UntaggedWay)
171 return testError.getCode() == EMPTY_WAY
172 || testError.getCode() == ONE_NODE_WAY;
173
174 return false;
175 }
176
177 @Override
178 public Command fixError(TestError testError) {
179 return deletePrimitivesIfNeeded(testError.getPrimitives());
180 }
181
182 @Override
183 public boolean isPrimitiveUsable(OsmPrimitive p) {
184 return p.isUsable();
185 }
186}
Note: See TracBrowser for help on using the repository browser.