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    }