001 package org.openstreetmap.josm.data.validation.tests; 002 003 import static org.openstreetmap.josm.tools.I18n.tr; 004 005 import java.util.ArrayList; 006 import java.util.Collection; 007 import java.util.Collections; 008 009 import org.openstreetmap.josm.data.osm.QuadBuckets; 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 import org.openstreetmap.josm.tools.Geometry; 016 import org.openstreetmap.josm.tools.Predicate; 017 import org.openstreetmap.josm.tools.Utils; 018 019 public class OverlappingAreas extends Test { 020 021 protected static final int OVERLAPPING_AREAS = 2201; 022 protected QuadBuckets<Way> index = new QuadBuckets<Way>(); 023 024 public OverlappingAreas() { 025 super(tr("Overlapping Areas"), tr("This test checks if areas overlap.")); 026 } 027 028 @Override 029 public void visit(Way w) { 030 if (w.isUsable() && w.isArea() && ElemStyles.hasAreaElemStyle(w, false)) { 031 index.add(w); 032 } 033 } 034 035 @Override 036 public void endTest() { 037 for (final Way w : index) { 038 Collection<Way> overlaps = Utils.filter( 039 index.search(w.getBBox()), 040 new Predicate<Way>() { 041 042 @Override 043 public boolean evaluate(Way wi) { 044 if (w.equals(wi)) 045 return false; 046 else 047 return Geometry.polygonIntersection(w.getNodes(), wi.getNodes()) 048 == Geometry.PolygonIntersection.CROSSING; 049 } 050 }); 051 if (!overlaps.isEmpty()) { 052 Collection<Way> overlapsWater = new ArrayList<Way>(); 053 Collection<Way> overlapsOther = new ArrayList<Way>(); 054 055 String natural1 = w.get("natural"); 056 String landuse1 = w.get("landuse"); 057 boolean isWaterArea = "water".equals(natural1) || "wetland".equals(natural1) || "coastline".equals(natural1) || "reservoir".equals(landuse1); 058 boolean isWaterArea2 = false; 059 060 for (Way wayOther : overlaps) { 061 String natural2 = wayOther.get("natural"); 062 String landuse2 = wayOther.get("landuse"); 063 boolean isWaterAreaTest = "water".equals(natural2) || "wetland".equals(natural2) || "coastline".equals(natural2) || "reservoir".equals(landuse2); 064 065 if (!isWaterArea2) { 066 isWaterArea2 = isWaterAreaTest; 067 } 068 069 if (isWaterArea && isWaterAreaTest) { 070 overlapsWater.add(wayOther); 071 } else { 072 overlapsOther.add(wayOther); 073 } 074 } 075 076 if (!overlapsWater.isEmpty()) { 077 errors.add(new TestError(this, Severity.WARNING, tr("Overlapping Water Areas"), 078 OVERLAPPING_AREAS, Collections.singletonList(w), overlapsWater)); 079 } 080 081 if (!overlapsOther.isEmpty()) { 082 errors.add(new TestError(this, Severity.OTHER, tr("Overlapping Areas"), 083 OVERLAPPING_AREAS, Collections.singletonList(w), overlapsOther)); 084 } 085 } 086 } 087 088 super.endTest(); 089 } 090 091 }