source: josm/trunk/src/org/openstreetmap/josm/data/validation/tests/RelationChecker.java@ 6113

Last change on this file since 6113 was 6113, checked in by Don-vip, 11 years ago

fix some compilation warnings

  • Property svn:eol-style set to native
File size: 10.1 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.data.validation.tests;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.text.MessageFormat;
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.HashMap;
11import java.util.HashSet;
12import java.util.LinkedList;
13import java.util.Set;
14
15import org.openstreetmap.josm.command.Command;
16import org.openstreetmap.josm.command.DeleteCommand;
17import org.openstreetmap.josm.data.osm.Node;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.data.osm.Relation;
20import org.openstreetmap.josm.data.osm.RelationMember;
21import org.openstreetmap.josm.data.osm.Way;
22import org.openstreetmap.josm.data.validation.Severity;
23import org.openstreetmap.josm.data.validation.Test;
24import org.openstreetmap.josm.data.validation.TestError;
25import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
26import org.openstreetmap.josm.gui.tagging.TaggingPreset;
27import org.openstreetmap.josm.gui.tagging.TaggingPresetItem;
28import org.openstreetmap.josm.gui.tagging.TaggingPresetItems.Role;
29import org.openstreetmap.josm.gui.tagging.TaggingPresetItems.Key;
30import org.openstreetmap.josm.gui.tagging.TaggingPresetItems.Roles;
31import org.openstreetmap.josm.gui.tagging.TaggingPresetType;
32
33/**
34 * Check for wrong relations
35 *
36 */
37public class RelationChecker extends Test {
38
39 protected static final int ROLE_UNKNOWN = 1701;
40 protected static final int ROLE_EMPTY = 1702;
41 protected static final int WRONG_TYPE = 1703;
42 protected static final int HIGH_COUNT = 1704;
43 protected static final int LOW_COUNT = 1705;
44 protected static final int ROLE_MISSING = 1706;
45 protected static final int RELATION_UNKNOWN = 1707;
46 protected static final int RELATION_EMPTY = 1708;
47
48 /**
49 * Constructor
50 */
51 public RelationChecker() {
52 super(tr("Relation checker"),
53 tr("This plugin checks for errors in relations."));
54 }
55
56 @Override
57 public void initialize() {
58 initializePresets();
59 }
60
61 static Collection<TaggingPreset> relationpresets = new LinkedList<TaggingPreset>();
62
63 /**
64 * Reads the presets data.
65 *
66 */
67 public void initializePresets() {
68 Collection<TaggingPreset> presets = TaggingPresetPreference.taggingPresets;
69 if (presets != null) {
70 for (TaggingPreset p : presets) {
71 for (TaggingPresetItem i : p.data) {
72 if (i instanceof Roles) {
73 relationpresets.add(p);
74 break;
75 }
76 }
77 }
78 }
79 }
80
81 public static class RoleInfo {
82 int total = 0;
83 Collection<Node> nodes = new LinkedList<Node>();
84 Collection<Way> ways = new LinkedList<Way>();
85 Collection<Way> closedways = new LinkedList<Way>();
86 Collection<Way> openways = new LinkedList<Way>();
87 Collection<Relation> relations = new LinkedList<Relation>();
88 }
89
90 @SuppressWarnings("unchecked")
91 @Override
92 public void visit(Relation n) {
93 LinkedList<Role> allroles = new LinkedList<Role>();
94 for (TaggingPreset p : relationpresets) {
95 boolean matches = true;
96 Roles r = null;
97 for (TaggingPresetItem i : p.data) {
98 if (i instanceof Key) {
99 Key k = (Key) i;
100 if (!k.value.equals(n.get(k.key))) {
101 matches = false;
102 break;
103 }
104 } else if (i instanceof Roles) {
105 r = (Roles) i;
106 }
107 }
108 if (matches && r != null) {
109 allroles.addAll(r.roles);
110 }
111 }
112 if (allroles.isEmpty()) {
113 errors.add( new TestError(this, Severity.WARNING, tr("Relation type is unknown"),
114 RELATION_UNKNOWN, n) );
115 } else {
116 HashMap<String,RoleInfo> map = new HashMap<String, RoleInfo>();
117 for (RelationMember m : n.getMembers()) {
118 String s = "";
119 if (m.hasRole()) {
120 s = m.getRole();
121 }
122 RoleInfo ri = map.get(s);
123 if (ri == null) {
124 ri = new RoleInfo();
125 }
126 ri.total++;
127 if (m.isRelation()) {
128 ri.relations.add(m.getRelation());
129 } else if(m.isWay()) {
130 ri.ways.add(m.getWay());
131 if (m.getWay().isClosed()) {
132 ri.closedways.add(m.getWay());
133 } else {
134 ri.openways.add(m.getWay());
135 }
136 }
137 else if (m.isNode()) {
138 ri.nodes.add(m.getNode());
139 }
140 map.put(s, ri);
141 }
142 if(map.isEmpty()) {
143 errors.add( new TestError(this, Severity.ERROR, tr("Relation is empty"),
144 RELATION_EMPTY, n) );
145 } else {
146 LinkedList<String> done = new LinkedList<String>();
147 for (Role r : allroles) {
148 done.add(r.key);
149 String keyname = r.key;
150 if ("".equals(keyname)) {
151 keyname = tr("<empty>");
152 }
153 RoleInfo ri = map.get(r.key);
154 long count = (ri == null) ? 0 : ri.total;
155 long vc = r.getValidCount(count);
156 if (count != vc) {
157 if (count == 0) {
158 String s = marktr("Role {0} missing");
159 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
160 tr(s, keyname), MessageFormat.format(s, keyname), ROLE_MISSING, n));
161 }
162 else if (vc > count) {
163 String s = marktr("Number of {0} roles too low ({1})");
164 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
165 tr(s, keyname, count), MessageFormat.format(s, keyname, count), LOW_COUNT, n));
166 } else {
167 String s = marktr("Number of {0} roles too high ({1})");
168 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
169 tr(s, keyname, count), MessageFormat.format(s, keyname, count), HIGH_COUNT, n));
170 }
171 }
172 if (ri != null) {
173 Set<OsmPrimitive> wrongTypes = new HashSet<OsmPrimitive>();
174 if (r.types != null) {
175 if (!r.types.contains(TaggingPresetType.WAY)) {
176 wrongTypes.addAll(r.types.contains(TaggingPresetType.CLOSEDWAY) ? ri.openways : ri.ways);
177 }
178 if (!r.types.contains(TaggingPresetType.NODE)) {
179 wrongTypes.addAll(ri.nodes);
180 }
181 if (!r.types.contains(TaggingPresetType.RELATION)) {
182 wrongTypes.addAll(ri.relations);
183 }
184 }
185 if (r.memberExpression != null) {
186 for (Collection<OsmPrimitive> c : Arrays.asList(new Collection[]{ri.nodes, ri.ways, ri.relations})) {
187 for (OsmPrimitive p : c) {
188 if (p.isUsable() && !r.memberExpression.match(p)) {
189 wrongTypes.add(p);
190 }
191 }
192 }
193 }
194 if (!wrongTypes.isEmpty()) {
195 String s = marktr("Member for role {0} of wrong type");
196 LinkedList<OsmPrimitive> highlight = new LinkedList<OsmPrimitive>(wrongTypes);
197 highlight.addFirst(n);
198 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
199 tr(s, keyname), MessageFormat.format(s, keyname), WRONG_TYPE,
200 highlight, wrongTypes));
201 }
202 }
203 }
204 for (String key : map.keySet()) {
205 if (!done.contains(key)) {
206 if (key.length() > 0) {
207 String s = marktr("Role {0} unknown");
208 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
209 tr(s, key), MessageFormat.format(s, key), ROLE_UNKNOWN, n));
210 } else {
211 String s = marktr("Empty role found");
212 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
213 tr(s), s, ROLE_EMPTY, n));
214 }
215 }
216 }
217 }
218 }
219 }
220
221 /* (non-Javadoc)
222 * @see org.openstreetmap.josm.data.validation.Test#fixError(org.openstreetmap.josm.data.validation.TestError)
223 */
224 @Override
225 public Command fixError(TestError testError) {
226 if (isFixable(testError)) {
227 return new DeleteCommand(testError.getPrimitives());
228 }
229 return null;
230 }
231
232 /* (non-Javadoc)
233 * @see org.openstreetmap.josm.data.validation.Test#isFixable(org.openstreetmap.josm.data.validation.TestError)
234 */
235 @Override
236 public boolean isFixable(TestError testError) {
237 Collection<? extends OsmPrimitive> primitives = testError.getPrimitives();
238 return testError.getCode() == RELATION_EMPTY && !primitives.isEmpty() && primitives.iterator().next().isNew();
239 }
240}
Note: See TracBrowser for help on using the repository browser.