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.isClosed()) { 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 }