001 // License: GPL. See LICENSE file for details.
002 package org.openstreetmap.josm.data.validation.tests;
003
004 import static org.openstreetmap.josm.tools.I18n.marktr;
005 import static org.openstreetmap.josm.tools.I18n.tr;
006
007 import java.text.MessageFormat;
008 import java.util.Arrays;
009
010 import org.openstreetmap.josm.data.osm.OsmPrimitive;
011 import org.openstreetmap.josm.data.osm.OsmUtils;
012 import org.openstreetmap.josm.data.osm.Relation;
013 import org.openstreetmap.josm.data.osm.Way;
014 import org.openstreetmap.josm.data.validation.Severity;
015 import org.openstreetmap.josm.data.validation.Test;
016 import org.openstreetmap.josm.data.validation.TestError;
017 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
018
019 /**
020 * Check area type ways for errors
021 *
022 * @author stoecker
023 */
024 public class UnclosedWays extends Test {
025
026 /**
027 * Constructor
028 */
029 public UnclosedWays() {
030 super(tr("Unclosed Ways"), tr("This tests if ways which should be circular are closed."));
031 }
032
033 @Override
034 public void startTest(ProgressMonitor monitor) {
035 super.startTest(monitor);
036 }
037
038 @Override
039 public void endTest() {
040 super.endTest();
041 }
042
043 private String type;
044 private String etype;
045 private int mode;
046
047 public void set(int m, String text, String desc) {
048 etype = MessageFormat.format(text, desc);
049 type = tr(text, tr(desc));
050 mode = m;
051 }
052
053 public void set(int m, String text) {
054 etype = text;
055 type = tr(text);
056 mode = m;
057 }
058
059 @Override
060 public void visit(Way w) {
061 String test;
062 type = etype = null;
063 mode = 0;
064
065 if (!w.isUsable())
066 return;
067
068 test = w.get("natural");
069 if (test != null && !"coastline".equals(test) && !"cliff".equals(test) && !"tree_row".equals(test)) {
070 set(1101, marktr("natural type {0}"), test);
071 }
072 test = w.get("landuse");
073 if (test != null) {
074 set(1102, marktr("landuse type {0}"), test);
075 }
076 test = w.get("amenities");
077 if (test != null) {
078 set(1103, marktr("amenities type {0}"), test);
079 }
080 test = w.get("sport");
081 if (test != null && !test.equals("water_slide")) {
082 set(1104, marktr("sport type {0}"), test);
083 }
084 test = w.get("tourism");
085 if (test != null) {
086 set(1105, marktr("tourism type {0}"), test);
087 }
088 test = w.get("shop");
089 if (test != null) {
090 set(1106, marktr("shop type {0}"), test);
091 }
092 test = w.get("leisure");
093 if (test != null && !"track".contains(test)) {
094 set(1107, marktr("leisure type {0}"), test);
095 }
096 test = w.get("waterway");
097 if (test != null && test.equals("riverbank")) {
098 set(1108, marktr("waterway type {0}"), test);
099 }
100 Boolean btest = OsmUtils.getOsmBoolean(w.get("building"));
101 if (btest != null && btest) {
102 set(1120, marktr("building"));
103 }
104 btest = OsmUtils.getOsmBoolean(w.get("area"));
105 if (btest != null && btest) {
106 set(1130, marktr("area"));
107 }
108
109 if (type != null && !w.isArea()) {
110 for (OsmPrimitive parent: w.getReferrers()) {
111 if (parent instanceof Relation && ((Relation)parent).isMultipolygon())
112 return;
113 }
114
115 errors.add(new TestError(this, Severity.WARNING, tr("Unclosed way"),
116 type, etype, mode,
117 Arrays.asList(w),
118 // The important parts of an unclosed way are the first and
119 // the last node which should be connected, therefore we highlight them
120 Arrays.asList(w.firstNode(), w.lastNode())));
121 }
122 }
123 }