Changeset 15183 in josm


Ignore:
Timestamp:
2019-06-18T11:52:25+02:00 (3 months ago)
Author:
GerdP
Message:

fix #17768: Create / Update multipolygon did not work wich touching inner rings

Location:
trunk
Files:
2 added
2 edited

Legend:

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

    r15160 r15183  
    8181    /** set when used to build a multipolygon relation */
    8282    private Relation createdRelation;
     83    /** might be set when creating a relation and touching rings were found. */
     84    private boolean repeatCheck;
    8385
    8486    /**
     
    250252            // we found no intersection or crossing between the polygons and they are closed
    251253            // now we can calculate the nesting level to verify the roles with some simple node checks
    252             checkRoles(r, allPolygons, wayMap, sharedNodes);
     254            checkOrSetRoles(r, allPolygons, wayMap, sharedNodes);
    253255        }
    254256    }
     
    461463     * @param sharedNodes all nodes shared by multiple ways of this multipolygon
    462464     */
    463     private void checkRoles(Relation r, List<PolyData> allPolygons, Map<Long, RelationMember> wayMap, Set<Node> sharedNodes) {
     465    private void checkOrSetRoles(Relation r, List<PolyData> allPolygons, Map<Long, RelationMember> wayMap, Set<Node> sharedNodes) {
    464466        PolygonLevelFinder levelFinder = new PolygonLevelFinder(sharedNodes);
    465467        List<PolygonLevel> list = levelFinder.findOuterWays(allPolygons);
     
    577579                        }
    578580                    }
    579                     if (loop == 0 || samePoly || (loop == 1 && !allInner)) {
     581                    if (r == createdRelation && loop == 1 && !allInner) {
     582                        repeatCheck = true;
     583                    } else if (loop == 0 || samePoly || (loop == 1 && !allInner)) {
    580584                        String msg = loop == 0 ? tr("Intersection between multipolygon ways")
    581585                                : samePoly ? tr("Multipolygon ring contains segments twice")
     
    922926            r.addMember(new RelationMember("", w));
    923927        }
    924         errors.clear();
    925         Multipolygon polygon = null;
    926         boolean hasRepeatedMembers = checkRepeatedWayMembers(r);
    927         if (!hasRepeatedMembers) {
    928             polygon = new Multipolygon(r);
    929             // don't check style consistency here
    930             checkGeometryAndRoles(r, polygon);
    931         }
    932         createdRelation = null;
     928        do {
     929            repeatCheck = false;
     930            errors.clear();
     931            Multipolygon polygon = null;
     932            boolean hasRepeatedMembers = checkRepeatedWayMembers(r);
     933            if (!hasRepeatedMembers) {
     934                polygon = new Multipolygon(r);
     935                // don't check style consistency here
     936                checkGeometryAndRoles(r, polygon);
     937            }
     938            createdRelation = null; // makes sure that repeatCheck is only set once
     939        } while (repeatCheck);
    933940        errors.removeIf(e->e.getSeverity() == Severity.OTHER);
    934941        return r;
  • trunk/test/unit/org/openstreetmap/josm/data/validation/tests/MultipolygonTestTest.java

    r15134 r15183  
    22package org.openstreetmap.josm.data.validation.tests;
    33
     4import static org.junit.Assert.assertEquals;
     5import static org.junit.Assert.assertTrue;
     6
     7import java.io.InputStream;
    48import java.util.stream.Collectors;
    59
    610import org.junit.Rule;
    711import org.junit.Test;
     12import org.openstreetmap.josm.TestUtils;
    813import org.openstreetmap.josm.data.osm.Relation;
     14import org.openstreetmap.josm.io.OsmReader;
    915import org.openstreetmap.josm.testutils.JOSMTestRules;
    1016
     
    1622public class MultipolygonTestTest {
    1723
    18     private static final MultipolygonTest MULTIPOLYGON_TEST = new MultipolygonTest();
    19     private static final RelationChecker RELATION_TEST = new RelationChecker();
    2024
    2125    /**
     
    2428    @Rule
    2529    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
    26     public JOSMTestRules test = new JOSMTestRules().projection().mapStyles().presets().main();
     30    public JOSMTestRules test = new JOSMTestRules().projection().mapStyles().presets().main().preferences();
    2731
    2832    /**
     
    3236    @Test
    3337    public void testMultipolygonFile() throws Exception {
     38        final MultipolygonTest MULTIPOLYGON_TEST = new MultipolygonTest();
     39        final RelationChecker RELATION_TEST = new RelationChecker();
    3440        ValidatorTestUtils.testSampleFile("data_nodist/multipolygon.osm",
    3541                ds -> ds.getRelations().stream().filter(Relation::isMultipolygon).collect(Collectors.toList()),
    3642                name -> name.startsWith("06") || name.startsWith("07") || name.startsWith("08"), MULTIPOLYGON_TEST, RELATION_TEST);
    3743    }
     44
     45    /**
     46     * Non-regression test for ticket #17768.
     47     * @throws Exception if an error occurs
     48     */
     49    @Test
     50    public void testTicket17768TouchingInner() throws Exception {
     51        try (InputStream is = TestUtils.getRegressionDataStream(17768, "touching-inner.osm")) {
     52            MultipolygonTest mpTest = new MultipolygonTest();
     53            mpTest.makeFromWays(OsmReader.parseDataSet(is, null).getWays());
     54            // inner touches inner, is considered OK in OSM
     55            assertTrue(mpTest.getErrors().isEmpty());
     56        }
     57    }
     58
     59    /**
     60     * Non-regression test for ticket #17768.
     61     * @throws Exception if an error occurs
     62     */
     63    @Test
     64    public void testTicket17768TouchingInnerOuter() throws Exception {
     65        try (InputStream is = TestUtils.getRegressionDataStream(17768, "touching-inner-outer.osm")) {
     66            MultipolygonTest mpTest = new MultipolygonTest();
     67            mpTest.makeFromWays(OsmReader.parseDataSet(is, null).getWays());
     68            // inner touches outer, should return error
     69            assertEquals(1, mpTest.getErrors().size());
     70        }
     71    }
    3872}
Note: See TracChangeset for help on using the changeset viewer.