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

Last change on this file since 5196 was 5196, checked in by simon04, 12 years ago

tagging presets: fix customized matching for combo elements (broken due to r5172), remove duplicated/inconsistent parsing/interpreting of preset values

  • Property svn:eol-style set to native
File size: 8.4 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.Collection;
9import java.util.HashMap;
10import java.util.LinkedList;
11
12import org.openstreetmap.josm.data.osm.Node;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.data.osm.Relation;
15import org.openstreetmap.josm.data.osm.RelationMember;
16import org.openstreetmap.josm.data.osm.Way;
17import org.openstreetmap.josm.data.validation.Severity;
18import org.openstreetmap.josm.data.validation.Test;
19import org.openstreetmap.josm.data.validation.TestError;
20import org.openstreetmap.josm.gui.preferences.map.TaggingPresetPreference;
21import org.openstreetmap.josm.gui.tagging.TaggingPreset;
22import org.openstreetmap.josm.gui.tagging.TaggingPreset.PresetType;
23
24/**
25 * Check for wrong relations
26 *
27 */
28public class RelationChecker extends Test {
29
30 protected static final int ROLE_UNKNOWN = 1701;
31 protected static final int ROLE_EMPTY = 1702;
32 protected static final int WRONG_TYPE = 1703;
33 protected static final int HIGH_COUNT = 1704;
34 protected static final int LOW_COUNT = 1705;
35 protected static final int ROLE_MISSING = 1706;
36 protected static final int RELATION_UNKNOWN = 1707;
37 protected static final int RELATION_EMPTY = 1708;
38
39 /**
40 * Constructor
41 */
42 public RelationChecker() {
43 super(tr("Relation checker"),
44 tr("This plugin checks for errors in relations."));
45 }
46
47 @Override
48 public void initialize() {
49 initializePresets();
50 }
51
52 static Collection<TaggingPreset> relationpresets = new LinkedList<TaggingPreset>();
53
54 /**
55 * Reads the presets data.
56 *
57 */
58 public void initializePresets() {
59 Collection<TaggingPreset> presets = TaggingPresetPreference.taggingPresets;
60 if (presets != null) {
61 for (TaggingPreset p : presets) {
62 for (TaggingPreset.Item i : p.data) {
63 if (i instanceof TaggingPreset.Roles) {
64 relationpresets.add(p);
65 break;
66 }
67 }
68 }
69 }
70 }
71
72 public static class RoleInfo {
73 int total = 0;
74 Collection<Node> nodes = new LinkedList<Node>();
75 Collection<Way> ways = new LinkedList<Way>();
76 Collection<Way> closedways = new LinkedList<Way>();
77 Collection<Way> openways = new LinkedList<Way>();
78 Collection<Relation> relations = new LinkedList<Relation>();
79 }
80
81 @Override
82 public void visit(Relation n) {
83 LinkedList<TaggingPreset.Role> allroles = new LinkedList<TaggingPreset.Role>();
84 for (TaggingPreset p : relationpresets) {
85 boolean matches = true;
86 TaggingPreset.Roles r = null;
87 for (TaggingPreset.Item i : p.data) {
88 if (i instanceof TaggingPreset.Key) {
89 TaggingPreset.Key k = (TaggingPreset.Key) i;
90 if (!k.value.equals(n.get(k.key))) {
91 matches = false;
92 break;
93 }
94 } else if (i instanceof TaggingPreset.Roles) {
95 r = (TaggingPreset.Roles) i;
96 }
97 }
98 if (matches && r != null) {
99 allroles.addAll(r.roles);
100 }
101 }
102 if (allroles.size() == 0) {
103 errors.add( new TestError(this, Severity.WARNING, tr("Relation type is unknown"),
104 RELATION_UNKNOWN, n) );
105 } else {
106 HashMap<String,RoleInfo> map = new HashMap<String, RoleInfo>();
107 for (RelationMember m : n.getMembers()) {
108 String s = "";
109 if (m.hasRole()) {
110 s = m.getRole();
111 }
112 RoleInfo ri = map.get(s);
113 if (ri == null) {
114 ri = new RoleInfo();
115 }
116 ri.total++;
117 if (m.isRelation()) {
118 ri.relations.add(m.getRelation());
119 } else if(m.isWay()) {
120 ri.ways.add(m.getWay());
121 if (m.getWay().isClosed()) {
122 ri.closedways.add(m.getWay());
123 } else {
124 ri.openways.add(m.getWay());
125 }
126 }
127 else if (m.isNode()) {
128 ri.nodes.add(m.getNode());
129 }
130 map.put(s, ri);
131 }
132 if(map.isEmpty()) {
133 errors.add( new TestError(this, Severity.ERROR, tr("Relation is empty"),
134 RELATION_EMPTY, n) );
135 } else {
136 LinkedList<String> done = new LinkedList<String>();
137 for (TaggingPreset.Role r : allroles) {
138 done.add(r.key);
139 String keyname = r.key;
140 if ("".equals(keyname)) {
141 keyname = tr("<empty>");
142 }
143 RoleInfo ri = map.get(r.key);
144 long count = (ri == null) ? 0 : ri.total;
145 long vc = r.getValidCount(count);
146 if (count != vc) {
147 if (count == 0) {
148 String s = marktr("Role {0} missing");
149 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
150 tr(s, keyname), MessageFormat.format(s, keyname), ROLE_MISSING, n));
151 }
152 else if (vc > count) {
153 String s = marktr("Number of {0} roles too low ({1})");
154 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
155 tr(s, keyname, count), MessageFormat.format(s, keyname, count), LOW_COUNT, n));
156 } else {
157 String s = marktr("Number of {0} roles too high ({1})");
158 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
159 tr(s, keyname, count), MessageFormat.format(s, keyname, count), HIGH_COUNT, n));
160 }
161 }
162 if (ri != null) {
163 Collection<OsmPrimitive> wrongTypes = new LinkedList<OsmPrimitive>();
164 if (!r.types.contains(PresetType.WAY)) {
165 wrongTypes.addAll(r.types.contains(PresetType.CLOSEDWAY) ? ri.openways : ri.ways);
166 }
167 if (!r.types.contains(PresetType.NODE)) {
168 wrongTypes.addAll(ri.nodes);
169 }
170 if (!r.types.contains(PresetType.RELATION)) {
171 wrongTypes.addAll(ri.relations);
172 }
173 if (!wrongTypes.isEmpty()) {
174 String s = marktr("Member for role {0} of wrong type");
175 LinkedList<OsmPrimitive> highlight = new LinkedList<OsmPrimitive>(wrongTypes);
176 highlight.addFirst(n);
177 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
178 tr(s, keyname), MessageFormat.format(s, keyname), WRONG_TYPE,
179 highlight, wrongTypes));
180 }
181 }
182 }
183 for (String key : map.keySet()) {
184 if (!done.contains(key)) {
185 if (key.length() > 0) {
186 String s = marktr("Role {0} unknown");
187 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
188 tr(s, key), MessageFormat.format(s, key), ROLE_UNKNOWN, n));
189 } else {
190 String s = marktr("Empty role found");
191 errors.add(new TestError(this, Severity.WARNING, tr("Role verification problem"),
192 tr(s), s, ROLE_EMPTY, n));
193 }
194 }
195 }
196 }
197 }
198 }
199}
Note: See TracBrowser for help on using the repository browser.