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 }