source: josm/trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java@ 3699

Last change on this file since 3699 was 3671, checked in by bastiK, 13 years ago

adapt coding style (to some degree); there shouldn't be any semantic changes in this commit

  • Property svn:eol-style set to native
File size: 11.0 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.data.validation;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.BufferedReader;
7import java.io.File;
8import java.io.FileNotFoundException;
9import java.io.FileReader;
10import java.io.FileWriter;
11import java.io.IOException;
12import java.io.PrintWriter;
13import java.util.ArrayList;
14import java.util.Collection;
15import java.util.HashMap;
16import java.util.Map;
17import java.util.TreeSet;
18import java.util.regex.Matcher;
19import java.util.regex.Pattern;
20
21import javax.swing.JOptionPane;
22
23import org.openstreetmap.josm.Main;
24import org.openstreetmap.josm.actions.ValidateAction;
25import org.openstreetmap.josm.actions.upload.ValidateUploadHook;
26import org.openstreetmap.josm.data.projection.Epsg4326;
27import org.openstreetmap.josm.data.projection.Lambert;
28import org.openstreetmap.josm.data.projection.Mercator;
29import org.openstreetmap.josm.data.validation.tests.Coastlines;
30import org.openstreetmap.josm.data.validation.tests.CrossingWays;
31import org.openstreetmap.josm.data.validation.tests.DuplicateNode;
32import org.openstreetmap.josm.data.validation.tests.DuplicateWay;
33import org.openstreetmap.josm.data.validation.tests.DuplicatedWayNodes;
34import org.openstreetmap.josm.data.validation.tests.MultipolygonTest;
35import org.openstreetmap.josm.data.validation.tests.NameMismatch;
36import org.openstreetmap.josm.data.validation.tests.NodesWithSameName;
37import org.openstreetmap.josm.data.validation.tests.OverlappingWays;
38import org.openstreetmap.josm.data.validation.tests.RelationChecker;
39import org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay;
40import org.openstreetmap.josm.data.validation.tests.SimilarNamedWays;
41import org.openstreetmap.josm.data.validation.tests.TagChecker;
42import org.openstreetmap.josm.data.validation.tests.TurnrestrictionTest;
43import org.openstreetmap.josm.data.validation.tests.UnclosedWays;
44import org.openstreetmap.josm.data.validation.tests.UnconnectedWays;
45import org.openstreetmap.josm.data.validation.tests.UntaggedNode;
46import org.openstreetmap.josm.data.validation.tests.UntaggedWay;
47import org.openstreetmap.josm.data.validation.tests.WronglyOrderedWays;
48import org.openstreetmap.josm.data.validation.util.ValUtil;
49import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
50import org.openstreetmap.josm.gui.dialogs.ValidatorDialog;
51import org.openstreetmap.josm.gui.layer.ValidatorLayer;
52import org.openstreetmap.josm.gui.layer.Layer;
53import org.openstreetmap.josm.gui.layer.OsmDataLayer;
54import org.openstreetmap.josm.gui.preferences.ValidatorPreference;
55
56/**
57 *
58 * A OSM data validator
59 *
60 * @author Francisco R. Santos <frsantos@gmail.com>
61 */
62public class OsmValidator implements LayerChangeListener {
63
64 public static ValidatorLayer errorLayer = null;
65
66 /** The validate action */
67 public ValidateAction validateAction = new ValidateAction();
68
69 /** The validation dialog */
70 ValidatorDialog validationDialog;
71
72 /** Grid detail, multiplier of east,north values for valuable cell sizing */
73 public static double griddetail;
74
75 public static Collection<String> ignoredErrors = new TreeSet<String>();
76
77 /**
78 * All available tests
79 * TODO: is there any way to find out automatically all available tests?
80 */
81 @SuppressWarnings("unchecked")
82 public static Class<Test>[] allAvailableTests = new Class[] {
83 DuplicateNode.class, // ID 1 .. 99
84 OverlappingWays.class, // ID 101 .. 199
85 UntaggedNode.class, // ID 201 .. 299
86 UntaggedWay.class, // ID 301 .. 399
87 SelfIntersectingWay.class, // ID 401 .. 499
88 DuplicatedWayNodes.class, // ID 501 .. 599
89 CrossingWays.class, // ID 601 .. 699
90 SimilarNamedWays.class, // ID 701 .. 799
91 NodesWithSameName.class, // ID 801 .. 899
92 Coastlines.class, // ID 901 .. 999
93 WronglyOrderedWays.class, // ID 1001 .. 1099
94 UnclosedWays.class, // ID 1101 .. 1199
95 TagChecker.class, // ID 1201 .. 1299
96 UnconnectedWays.class, // ID 1301 .. 1399
97 DuplicateWay.class, // ID 1401 .. 1499
98 NameMismatch.class, // ID 1501 .. 1599
99 MultipolygonTest.class, // ID 1601 .. 1699
100 RelationChecker.class, // ID 1701 .. 1799
101 TurnrestrictionTest.class, // ID 1801 .. 1899
102 };
103
104 public OsmValidator() {
105 checkPluginDir();
106 initializeGridDetail();
107 initializeTests(getTests());
108 loadIgnoredErrors(); //FIXME: load only when needed
109 }
110
111 /**
112 * Check if plugin directory exists (store ignored errors file)
113 */
114 private void checkPluginDir() {
115 try {
116 File pathDir = new File(ValUtil.getPluginDir());
117 if (!pathDir.exists()) {
118 pathDir.mkdirs();
119 }
120 } catch (Exception e){
121 e.printStackTrace();
122 }
123 }
124
125 private void loadIgnoredErrors() {
126 ignoredErrors.clear();
127 if (Main.pref.getBoolean(ValidatorPreference.PREF_USE_IGNORE, true)) {
128 try {
129 final BufferedReader in = new BufferedReader(new FileReader(ValUtil.getPluginDir() + "ignorederrors"));
130 for (String line = in.readLine(); line != null; line = in.readLine()) {
131 ignoredErrors.add(line);
132 }
133 } catch (final FileNotFoundException e) {
134 // Ignore
135 } catch (final IOException e) {
136 e.printStackTrace();
137 }
138 }
139 }
140
141 public static void addIgnoredError(String s) {
142 ignoredErrors.add(s);
143 }
144
145 public static boolean hasIgnoredError(String s) {
146 return ignoredErrors.contains(s);
147 }
148
149 public static void saveIgnoredErrors() {
150 try {
151 final PrintWriter out = new PrintWriter(new FileWriter(ValUtil.getPluginDir() + "ignorederrors"), false);
152 for (String e : ignoredErrors) {
153 out.println(e);
154 }
155 out.close();
156 } catch (final IOException e) {
157 e.printStackTrace();
158 }
159 }
160
161 private ValidateUploadHook uploadHook;
162
163// public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
164// if (newFrame != null) {
165// initializeErrorLayer();
166// if (Main.pref.hasKey(ValidatorPreference.PREF_DEBUG + ".grid"))
167// Main.main.addLayer(new GridLayer(tr("Grid")));
168// }
169// }
170
171 public static void initializeErrorLayer() {
172 if (!Main.pref.getBoolean(ValidatorPreference.PREF_LAYER, true))
173 return;
174 if (errorLayer == null) {
175 errorLayer = new ValidatorLayer();
176 Main.main.addLayer(errorLayer);
177 }
178 }
179
180 /** Gets a map from simple names to all tests. */
181 public static Map<String, Test> getAllTestsMap() {
182 Map<String, Test> tests = new HashMap<String, Test>();
183 for (Class<Test> testClass : getAllAvailableTests()) {
184 try {
185 Test test = testClass.newInstance();
186 tests.put(testClass.getSimpleName(), test);
187 } catch (Exception e) {
188 e.printStackTrace();
189 continue;
190 }
191 }
192 applyPrefs(tests, false);
193 applyPrefs(tests, true);
194 return tests;
195 }
196
197 private static void applyPrefs(Map<String, Test> tests, boolean beforeUpload) {
198 Pattern regexp = Pattern.compile("(\\w+)=(true|false),?");
199 Matcher m = regexp.matcher(Main.pref.get(beforeUpload ? ValidatorPreference.PREF_TESTS_BEFORE_UPLOAD
200 : ValidatorPreference.PREF_TESTS));
201 int pos = 0;
202 while (m.find(pos)) {
203 String testName = m.group(1);
204 Test test = tests.get(testName);
205 if (test != null) {
206 boolean enabled = Boolean.valueOf(m.group(2));
207 if (beforeUpload) {
208 test.testBeforeUpload = enabled;
209 } else {
210 test.enabled = enabled;
211 }
212 }
213 pos = m.end();
214 }
215 }
216
217 public static Collection<Test> getTests() {
218 return getAllTestsMap().values();
219 }
220
221 public static Collection<Test> getEnabledTests(boolean beforeUpload) {
222 Collection<Test> enabledTests = getTests();
223 for (Test t : new ArrayList<Test>(enabledTests)) {
224 if (beforeUpload ? t.testBeforeUpload : t.enabled) {
225 continue;
226 }
227 enabledTests.remove(t);
228 }
229 return enabledTests;
230 }
231
232 /**
233 * Gets the list of all available test classes
234 *
235 * @return An array of the test classes
236 */
237 public static Class<Test>[] getAllAvailableTests() {
238 return allAvailableTests;
239 }
240
241 /**
242 * Initialize grid details based on current projection system. Values based on
243 * the original value fixed for EPSG:4326 (10000) using heuristics (that is, test&error
244 * until most bugs were discovered while keeping the processing time reasonable)
245 */
246 public void initializeGridDetail() {
247 if (Main.proj.toString().equals(new Epsg4326().toString())) {
248 OsmValidator.griddetail = 10000;
249 } else if (Main.proj.toString().equals(new Mercator().toString())) {
250 OsmValidator.griddetail = 100000;
251 } else if (Main.proj.toString().equals(new Lambert().toString())) {
252 OsmValidator.griddetail = 0.1;
253 }
254 }
255
256 /**
257 * Initializes all tests
258 * @param allTests The tests to initialize
259 */
260 public static void initializeTests(Collection<Test> allTests) {
261 for (Test test : allTests) {
262 try {
263 if (test.enabled) {
264 test.initialize();
265 }
266 } catch (Exception e) {
267 e.printStackTrace();
268 JOptionPane.showMessageDialog(Main.parent,
269 tr("Error initializing test {0}:\n {1}", test.getClass()
270 .getSimpleName(), e),
271 tr("Error"),
272 JOptionPane.ERROR_MESSAGE);
273 }
274 }
275 }
276
277 /* -------------------------------------------------------------------------- */
278 /* interface LayerChangeListener */
279 /* -------------------------------------------------------------------------- */
280 @Override
281 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
282 }
283
284 @Override
285 public void layerAdded(Layer newLayer) {
286 }
287
288 @Override
289 public void layerRemoved(Layer oldLayer) {
290 if (oldLayer instanceof OsmDataLayer && Main.map.mapView.getActiveLayer() == oldLayer) {
291 Main.map.validatorDialog.tree.setErrorList(new ArrayList<TestError>());
292 }
293 if (oldLayer == errorLayer) {
294 errorLayer = null;
295 return;
296 }
297 if (Main.map.mapView.getLayersOfType(OsmDataLayer.class).isEmpty()) {
298 if (errorLayer != null) {
299 Main.map.mapView.removeLayer(errorLayer);
300 }
301 }
302 }
303}
Note: See TracBrowser for help on using the repository browser.