001 package org.openstreetmap.josm.data.validation.tests; 002 003 import static org.openstreetmap.josm.tools.I18n.tr; 004 005 import java.util.Arrays; 006 import java.util.List; 007 import org.openstreetmap.josm.data.osm.Node; 008 import org.openstreetmap.josm.data.osm.OsmPrimitive; 009 import org.openstreetmap.josm.data.osm.Relation; 010 import org.openstreetmap.josm.data.osm.Way; 011 import org.openstreetmap.josm.data.validation.Severity; 012 import org.openstreetmap.josm.data.validation.Test; 013 import org.openstreetmap.josm.data.validation.TestError; 014 import org.openstreetmap.josm.gui.mappaint.ElemStyles; 015 016 public class WayConnectedToArea extends Test { 017 018 public WayConnectedToArea() { 019 super(tr("Way connected to Area"), tr("Checks for ways connected to areas.")); 020 } 021 022 @Override 023 public void visit(Way w) { 024 if (!w.isUsable() || w.isClosed() || !w.hasKey("highway")) { 025 return; 026 } 027 028 boolean hasway = false; 029 List<OsmPrimitive> r = w.firstNode().getReferrers(); 030 for (OsmPrimitive p : r) { 031 if(p != w && p.hasKey("highway")) { 032 hasway = true; 033 break; 034 } 035 } 036 if(!hasway) 037 { 038 for (OsmPrimitive p : r) { 039 testForError(w, w.firstNode(), p); 040 } 041 } 042 hasway = false; 043 r = w.lastNode().getReferrers(); 044 for (OsmPrimitive p : r) { 045 if(p != w && p.hasKey("highway")) { 046 hasway = true; 047 break; 048 } 049 } 050 if(!hasway) { 051 for (OsmPrimitive p : r) { 052 testForError(w, w.lastNode(), p); 053 } 054 } 055 } 056 057 private void testForError(Way w, Node wayNode, OsmPrimitive p) { 058 if (isArea(p)) { 059 addError(w, wayNode, p); 060 } else { 061 for (OsmPrimitive r : p.getReferrers()) { 062 if (r instanceof Relation 063 && r.hasTag("type", "multipolygon") 064 && isArea(r)) { 065 addError(w, wayNode, p); 066 break; 067 } 068 } 069 } 070 } 071 072 private boolean isArea(OsmPrimitive p) { 073 return (p.hasKey("landuse") || p.hasKey("natural")) 074 && ElemStyles.hasAreaElemStyle(p, false); 075 } 076 077 private void addError(Way w, Node wayNode, OsmPrimitive p) { 078 errors.add(new TestError(this, Severity.WARNING, 079 tr("Way terminates on Area"), 2301, 080 Arrays.asList(w, p), 081 Arrays.asList(wayNode))); 082 } 083 }