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 }