001    package org.openstreetmap.josm.data.validation.tests;
002    
003    import static org.openstreetmap.josm.tools.I18n.tr;
004    
005    import java.util.Collection;
006    import java.util.Collections;
007    
008    import org.openstreetmap.josm.data.osm.QuadBuckets;
009    import org.openstreetmap.josm.data.osm.Way;
010    import org.openstreetmap.josm.data.validation.Severity;
011    import org.openstreetmap.josm.data.validation.Test;
012    import org.openstreetmap.josm.data.validation.TestError;
013    import org.openstreetmap.josm.gui.mappaint.ElemStyles;
014    import org.openstreetmap.josm.tools.Geometry;
015    import org.openstreetmap.josm.tools.Predicate;
016    import org.openstreetmap.josm.tools.Utils;
017    
018    public class OverlappingAreas extends Test {
019    
020        protected static final int OVERLAPPING_AREAS = 2201;
021        protected QuadBuckets<Way> index = new QuadBuckets<Way>();
022    
023        public OverlappingAreas() {
024            super(tr("Overlapping Areas"), tr("This test checks if areas overlap."));
025        }
026    
027        @Override
028        public void visit(Way w) {
029            if (w.isUsable() && w.isClosed() && ElemStyles.hasAreaElemStyle(w, false)) {
030                index.add(w);
031            }
032        }
033    
034        @Override
035        public void endTest() {
036            for (final Way w : index) {
037                Collection<Way> overlaps = Utils.filter(
038                        index.search(w.getBBox()),
039                        new Predicate<Way>() {
040    
041                            @Override
042                            public boolean evaluate(Way wi) {
043                                if (w.equals(wi))
044                                    return false;
045                                else
046                                    return Geometry.polygonIntersection(w.getNodes(), wi.getNodes())
047                                            == Geometry.PolygonIntersection.CROSSING;
048                            }
049                        });
050                if (!overlaps.isEmpty()) {
051                    errors.add(new TestError(this, Severity.OTHER, tr("Overlapping Areas"),
052                            OVERLAPPING_AREAS, Collections.singletonList(w), overlaps));
053                }
054            }
055    
056            super.endTest();
057        }
058    
059    }