Ignore:
Timestamp:
2011-12-29T19:15:16+01:00 (12 years ago)
Author:
Don-vip
Message:

fix #7034 - building inside building false positives

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/BuildingInBuilding.java

    r4738 r4747  
    1010import org.openstreetmap.josm.data.osm.Node;
    1111import org.openstreetmap.josm.data.osm.OsmPrimitive;
     12import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    1213import org.openstreetmap.josm.data.osm.QuadBuckets;
     14import org.openstreetmap.josm.data.osm.Relation;
     15import org.openstreetmap.josm.data.osm.RelationMember;
    1316import org.openstreetmap.josm.data.osm.Way;
    1417import org.openstreetmap.josm.data.validation.Severity;
     
    6871        //  |_______________________|
    6972        //
    70         for (int i=0; i<w.getNodesCount(); i++) {
    71             LatLon center = null;
    72             if (i > 0) {
    73                 center = w.getNode(i).getCoor().getCenter(w.getNode(i-1).getCoor());
    74             } else if (w.isClosed()) {
    75                 center = w.getNode(i).getCoor().getCenter(w.getNode(w.getNodesCount()-2).getCoor());
    76             }
     73        for (int i=1; i<w.getNodesCount(); i++) {
     74            LatLon center = w.getNode(i).getCoor().getCenter(w.getNode(i-1).getCoor());
    7775            if (center != null && !isInPolygon(new Node(center), polygon)) {
    7876                return false;
     
    8583    public void endTest() {
    8684        for (final OsmPrimitive p : primitivesToCheck) {
    87             Collection<Way> outer = index.search(p.getBBox());
    88             outer = new FilteredCollection<Way>(outer, new Predicate<Way>() {
    89 
     85            Collection<Way> outers = new FilteredCollection<Way>(index.search(p.getBBox()), new Predicate<Way>() {
    9086                @Override
    9187                public boolean evaluate(Way object) {
     
    9591                        return isInPolygon((Node) p, object.getNodes()) || object.getNodes().contains(p);
    9692                    } else if (p instanceof Way) {
    97                         return isInPolygon((Way) p, object.getNodes());
     93                        return isInPolygon((Way) p, object.getNodes()) && !isInInnerWay((Way)p, object);
    9894                    } else {
    9995                        return false;
     
    10197                }
    10298            });
    103             if (!outer.isEmpty()) {
     99            if (!outers.isEmpty()) {
    104100                errors.add(new TestError(this, Severity.WARNING,
    105101                        tr("Building inside building"), BUILDING_INSIDE_BUILDING, p));
    106102            }
    107103        }
     104    }
     105   
     106    private boolean isInInnerWay(Way w, Way outer) {
     107        for (OsmPrimitive r : outer.getReferrers()) {
     108            if (r instanceof Relation && ((Relation)r).isMultipolygon()) {
     109                for (RelationMember m : ((Relation)r).getMembers()) {
     110                    if (m.hasRole() && m.getRole().equals("inner") && m.getType().equals(OsmPrimitiveType.WAY)) {
     111                        // Only check inner ways actually inside the current outer
     112                        Way inner = m.getWay();
     113                        if (isInPolygon(inner, outer.getNodes())) {
     114                            // If the tested way is inside this inner, outer is a false positive
     115                            if (isInPolygon(w, inner.getNodes())) {
     116                                return true;
     117                            }
     118                        }
     119                    }
     120                }
     121            }
     122        }
     123        return false;
    108124    }
    109125
Note: See TracChangeset for help on using the changeset viewer.