Ignore:
Timestamp:
2014-05-19T18:03:52+02:00 (9 years ago)
Author:
simon04
Message:

see #10037 - Improve node-inside-multipolygon matching by handling rings consisting of several ways correctly

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/tools/Geometry.java

    r7072 r7145  
    2424import org.openstreetmap.josm.data.coor.LatLon;
    2525import org.openstreetmap.josm.data.osm.BBox;
     26import org.openstreetmap.josm.data.osm.MultipolygonCreate;
    2627import org.openstreetmap.josm.data.osm.Node;
    2728import org.openstreetmap.josm.data.osm.NodePositionComparator;
     
    860861    public static boolean isPolygonInsideMultiPolygon(List<Node> nodes, Relation multiPolygon, Predicate<Way> isOuterWayAMatch) {
    861862        // Extract outer/inner members from multipolygon
    862         MultiPolygonMembers mpm = new MultiPolygonMembers(multiPolygon);
     863        final MultiPolygonMembers mpm = new MultiPolygonMembers(multiPolygon);
     864        // Construct complete rings for the inner/outer members
     865        final List<MultipolygonCreate.JoinedPolygon> outerRings;
     866        final List<MultipolygonCreate.JoinedPolygon> innerRings;
     867        try {
     868            outerRings = MultipolygonCreate.joinWays(mpm.outers);
     869            innerRings = MultipolygonCreate.joinWays(mpm.inners);
     870        } catch (MultipolygonCreate.JoinedPolygonCreationException ex) {
     871            Main.debug("Invalid multipolygon " + multiPolygon);
     872            return false;
     873        }
    863874        // Test if object is inside an outer member
    864         for (Way out : mpm.outers) {
     875        for (MultipolygonCreate.JoinedPolygon out : outerRings) {
    865876            if (nodes.size() == 1
    866877                    ? nodeInsidePolygon(nodes.get(0), out.getNodes())
     
    868879                boolean insideInner = false;
    869880                // If inside an outer, check it is not inside an inner
    870                 for (Way in : mpm.inners) {
     881                for (MultipolygonCreate.JoinedPolygon in : innerRings) {
    871882                    if (polygonIntersection(in.getNodes(), out.getNodes()) == PolygonIntersection.FIRST_INSIDE_SECOND
    872883                            && (nodes.size() == 1
     
    880891                if (!insideInner) {
    881892                    // Final check using predicate
    882                     if (isOuterWayAMatch == null || isOuterWayAMatch.evaluate(out)) {
     893                    if (isOuterWayAMatch == null || isOuterWayAMatch.evaluate(out.ways.get(0) /* TODO give a better representation of the outer ring to the predicate */)) {
    883894                        return true;
    884895                    }
Note: See TracChangeset for help on using the changeset viewer.