Ticket #23517: 23517.patch

File 23517.patch, 4.2 KB (added by GerdP, 2 years ago)

reorder members so that all outer rings come first and for rings with same role those with more members come first

  • src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java

     
    4646 */
    4747public class MultipolygonTest extends Test {
    4848
     49    private static final String OUTER = "outer";
     50    private static final String INNER = "inner";
     51
    4952    /** Non-Way in multipolygon */
    5053    public static final int WRONG_MEMBER_TYPE = 1601;
    5154    /** No useful role for multipolygon member */
     
    444447            return;
    445448        }
    446449        if (r == createdRelation) {
     450            // see #23517: sort rings so that outer come first
     451            list.sort((r1, r2) -> {
     452                // outer first
     453                int d = Integer.compare(r1.level % 2, r2.level % 2);
     454                if (d != 0)
     455                    return d;
     456                // ring with more members first
     457                return Integer.compare(r2.outerWay.getWayIds().size(), r1.outerWay.getWayIds().size());
     458            });
    447459            List<RelationMember> modMembers = new ArrayList<>();
    448460            for (PolygonLevel pol : list) {
    449                 final String calculatedRole = (pol.level % 2 == 0) ? "outer" : "inner";
     461                final String calculatedRole = (pol.level % 2 == 0) ? OUTER : INNER;
    450462                for (long wayId : pol.outerWay.getWayIds()) {
    451463                    RelationMember member = wayMap.get(wayId);
    452464                    modMembers.add(new RelationMember(calculatedRole, member.getMember()));
     
    456468            return;
    457469        }
    458470        for (PolygonLevel pol : list) {
    459             final String calculatedRole = (pol.level % 2 == 0) ? "outer" : "inner";
     471            final String calculatedRole = (pol.level % 2 == 0) ? OUTER : INNER;
    460472            for (long wayId : pol.outerWay.getWayIds()) {
    461473                RelationMember member = wayMap.get(wayId);
    462474                if (!calculatedRole.equals(member.getRole())) {
     
    468480                            .primitives(Arrays.asList(r, member.getMember()))
    469481                            .highlight(member.getMember())
    470482                            .build());
    471                     if (pol.level == 0 && "inner".equals(member.getRole())) {
     483                    if (pol.level == 0 && INNER.equals(member.getRole())) {
    472484                        // maybe only add this error if we found an outer ring with correct role(s) ?
    473485                        errors.add(TestError.builder(this, Severity.ERROR, INNER_WAY_OUTSIDE)
    474486                                .message(tr("Multipolygon inner way is outside"))
     
    569581     */
    570582    private void findIntersectingWaysIncomplete(Relation r) {
    571583        Set<OsmPrimitive> outerWays = r.getMembers().stream()
    572                 .filter(m -> m.getRole().isEmpty() || "outer".equals(m.getRole()))
     584                .filter(m -> m.getRole().isEmpty() || OUTER.equals(m.getRole()))
    573585                .map(RelationMember::getMember)
    574586                .collect(Collectors.toSet());
    575587        for (int loop = 0; loop < 2; loop++) {
     
    643655        boolean hasUnexpectedWayRole = false;
    644656        for (RelationMember rm : r.getMembers()) {
    645657            if (rm.isWay()) {
    646                 if (rm.hasRole() && !rm.hasRole("inner", "outer"))
     658                if (rm.hasRole() && !rm.hasRole(INNER, OUTER))
    647659                    hasUnexpectedWayRole = true;
    648                 if (!rm.hasRole("inner", "outer") || !rm.hasRole()) {
     660                if (!rm.hasRole(INNER, OUTER) || !rm.hasRole()) {
    649661                    tmpErrors.add(TestError.builder(this, Severity.ERROR, WRONG_MEMBER_ROLE)
    650662                            .message(tr("Role for multipolygon way member should be inner or outer"))
    651663                            .primitives(Arrays.asList(r, rm.getMember()))
     
    905917            }
    906918            createdRelation = null; // makes sure that repeatCheck is only set once
    907919        } while (repeatCheck);
    908         errors.removeIf(e->e.getSeverity() == Severity.OTHER);
     920        errors.removeIf(e -> e.getSeverity() == Severity.OTHER);
    909921        return r;
    910922    }
    911923