1 | package org.openstreetmap.josm.data.validation.tests;
|
---|
2 |
|
---|
3 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
4 |
|
---|
5 | import java.util.Collection;
|
---|
6 | import java.util.LinkedList;
|
---|
7 | import java.util.List;
|
---|
8 | import org.openstreetmap.josm.data.osm.Node;
|
---|
9 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
---|
10 | import org.openstreetmap.josm.data.osm.QuadBuckets;
|
---|
11 | import org.openstreetmap.josm.data.osm.Way;
|
---|
12 | import org.openstreetmap.josm.data.validation.Severity;
|
---|
13 | import org.openstreetmap.josm.data.validation.Test;
|
---|
14 | import org.openstreetmap.josm.data.validation.TestError;
|
---|
15 | import org.openstreetmap.josm.tools.FilteredCollection;
|
---|
16 | import org.openstreetmap.josm.tools.Geometry;
|
---|
17 | import org.openstreetmap.josm.tools.Predicate;
|
---|
18 |
|
---|
19 | public class BuildingInBuilding extends Test {
|
---|
20 |
|
---|
21 | protected static int BUILDING_INSIDE_BUILDING = 2001;
|
---|
22 | protected List<OsmPrimitive> primitivesToCheck = new LinkedList<OsmPrimitive>();
|
---|
23 | protected QuadBuckets<Way> index = new QuadBuckets<Way>();
|
---|
24 |
|
---|
25 | public BuildingInBuilding() {
|
---|
26 | super(tr("Building inside building"));
|
---|
27 | }
|
---|
28 |
|
---|
29 | @Override
|
---|
30 | public void visit(Node n) {
|
---|
31 | if (n.isUsable() && isBuilding(n)) {
|
---|
32 | primitivesToCheck.add(n);
|
---|
33 | }
|
---|
34 | }
|
---|
35 |
|
---|
36 | @Override
|
---|
37 | public void visit(Way w) {
|
---|
38 | if (w.isUsable() && w.isClosed() && isBuilding(w)) {
|
---|
39 | primitivesToCheck.add(w);
|
---|
40 | index.add(w);
|
---|
41 | }
|
---|
42 | }
|
---|
43 |
|
---|
44 | private static boolean isInPolygon(Node n, List<Node> polygon) {
|
---|
45 | return Geometry.nodeInsidePolygon(n, polygon);
|
---|
46 | }
|
---|
47 |
|
---|
48 | private static boolean isInPolygon(Way w, List<Node> polygon) {
|
---|
49 | for (Node n : w.getNodes()) {
|
---|
50 | if (!isInPolygon(n, polygon)) {
|
---|
51 | return false;
|
---|
52 | }
|
---|
53 | }
|
---|
54 | return true;
|
---|
55 | }
|
---|
56 |
|
---|
57 | @Override
|
---|
58 | public void endTest() {
|
---|
59 | for (final OsmPrimitive p : primitivesToCheck) {
|
---|
60 | Collection<Way> outer = index.search(p.getBBox());
|
---|
61 | outer = new FilteredCollection<Way>(outer, new Predicate<Way>() {
|
---|
62 |
|
---|
63 | @Override
|
---|
64 | public boolean evaluate(Way object) {
|
---|
65 | if (p.equals(object)) {
|
---|
66 | return false;
|
---|
67 | } else if (p instanceof Node) {
|
---|
68 | return isInPolygon((Node) p, object.getNodes()) || object.getNodes().contains((Node) p);
|
---|
69 | } else if (p instanceof Way) {
|
---|
70 | return isInPolygon((Way) p, object.getNodes());
|
---|
71 | } else {
|
---|
72 | return false;
|
---|
73 | }
|
---|
74 | }
|
---|
75 | });
|
---|
76 | if (!outer.isEmpty()) {
|
---|
77 | errors.add(new TestError(this, Severity.WARNING,
|
---|
78 | tr("Building inside building"), BUILDING_INSIDE_BUILDING, p));
|
---|
79 | }
|
---|
80 | }
|
---|
81 | }
|
---|
82 |
|
---|
83 | private static boolean isBuilding(OsmPrimitive p) {
|
---|
84 | return "yes".equals(p.get("building"));
|
---|
85 | }
|
---|
86 | }
|
---|