Changeset 14437 in josm for trunk/src


Ignore:
Timestamp:
2018-11-20T17:01:47+01:00 (6 years ago)
Author:
GerdP
Message:

fix #17010 - Validator creates multiple errors/warnings for same problem

The fix reduces the noise.

  • Don't check roles again in RelationChecker when MultipolygonTest is enabled
  • remove special code that just searches for an outer way
  • correct checkMembersAndRoles, it did not find wrong roles for way members
Location:
trunk/src/org/openstreetmap/josm/data/validation/tests
Files:
2 edited

Legend:

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

    r14436 r14437  
    5454    /** Multipolygon is not closed */
    5555    public static final int NON_CLOSED_WAY = 1603;
    56     /** No outer way for multipolygon */
    57     public static final int MISSING_OUTER_WAY = 1604;
    5856    /** Multipolygon inner way is outside */
    5957    public static final int INNER_WAY_OUTSIDE = 1605;
     
    133131    public void visit(Relation r) {
    134132        if (r.isMultipolygon() && r.getMembersCount() > 0) {
    135             checkMembersAndRoles(r);
    136             checkOuterWay(r);
     133            List<TestError> tmpErrors = new ArrayList<>(30);
     134            boolean hasUnexpectedWayRoles = checkMembersAndRoles(r, tmpErrors);
    137135            boolean hasRepeatedMembers = checkRepeatedWayMembers(r);
    138136            // Rest of checks is only for complete multipolygon
    139             if (!hasRepeatedMembers && !r.hasIncompleteMembers()) {
     137            if (!hasUnexpectedWayRoles && !hasRepeatedMembers && !r.hasIncompleteMembers()) {
    140138                Multipolygon polygon = new Multipolygon(r);
    141139                checkStyleConsistency(r, polygon);
    142140                checkGeometryAndRoles(r, polygon);
    143             }
    144         }
    145     }
    146 
    147     /**
    148      * Checks that multipolygon has at least an outer way:<ul>
    149      * <li>{@link #MISSING_OUTER_WAY}: No outer way for multipolygon</li>
    150      * </ul>
    151      * @param r relation
    152      */
    153     private void checkOuterWay(Relation r) {
    154         for (RelationMember m : r.getMembers()) {
    155             if (m.isWay() && "outer".equals(m.getRole())) {
    156                 return;
    157             }
    158         }
    159         errors.add(TestError.builder(this, Severity.WARNING, MISSING_OUTER_WAY)
    160                 .message(r.isBoundary() ? tr("No outer way for boundary") : tr("No outer way for multipolygon"))
    161                 .primitives(r)
    162                 .build());
     141                // see #17010: don't report problems twice
     142                tmpErrors.removeIf(e -> e.getCode() == WRONG_MEMBER_ROLE);
     143            }
     144            errors.addAll(tmpErrors);
     145        }
    163146    }
    164147
     
    528511            for (long wayId : pol.outerWay.getWayIds()) {
    529512                RelationMember member = wayMap.get(wayId);
    530                 if (!member.getRole().equals(calculatedRole)) {
     513                if (!calculatedRole.equals(member.getRole())) {
    531514                    errors.add(TestError.builder(this, Severity.ERROR, WRONG_MEMBER_ROLE)
    532515                            .message(RelationChecker.ROLE_VERIF_PROBLEM_MSG,
     
    705688     * </ul>
    706689     * @param r relation
    707      */
    708     private void checkMembersAndRoles(Relation r) {
     690     * @param tmpErrors list that will contain found errors
     691     * @return true if ways with roles other than inner, outer or empty where found
     692     */
     693    private boolean checkMembersAndRoles(Relation r, List<TestError> tmpErrors) {
     694        boolean hasUnexpectedWayRole = false;
    709695        for (RelationMember rm : r.getMembers()) {
    710696            if (rm.isWay()) {
    711                 if (!(rm.hasRole("inner", "outer") || !rm.hasRole())) {
    712                     errors.add(TestError.builder(this, Severity.WARNING, WRONG_MEMBER_ROLE)
    713                             .message(tr("No useful role for multipolygon member"))
     697                if (rm.hasRole() && !(rm.hasRole("inner", "outer")))
     698                    hasUnexpectedWayRole = true;
     699                if (!(rm.hasRole("inner", "outer")) || !rm.hasRole()) {
     700                    tmpErrors.add(TestError.builder(this, Severity.ERROR, WRONG_MEMBER_ROLE)
     701                            .message(tr("Role for multipolygon way member should be inner or outer"))
    714702                            .primitives(Arrays.asList(r, rm.getMember()))
    715703                            .build());
     
    717705            } else {
    718706                if (!r.isBoundary() || !rm.hasRole("admin_centre", "label", "subarea", "land_area")) {
    719                     errors.add(TestError.builder(this, Severity.WARNING, WRONG_MEMBER_TYPE)
     707                    tmpErrors.add(TestError.builder(this, Severity.WARNING, WRONG_MEMBER_TYPE)
    720708                            .message(r.isBoundary() ? tr("Non-Way in boundary") : tr("Non-Way in multipolygon"))
    721709                            .primitives(Arrays.asList(r, rm.getMember()))
     
    724712            }
    725713        }
     714        return hasUnexpectedWayRole;
    726715    }
    727716
     
    749738        Map<OsmPrimitive, List<RelationMember>> seenMemberPrimitives = new HashMap<>();
    750739        for (RelationMember rm : r.getMembers()) {
     740            if (!rm.isWay())
     741                continue;
    751742            List<RelationMember> list = seenMemberPrimitives.get(rm.getMember());
    752743            if (list == null) {
  • trunk/src/org/openstreetmap/josm/data/validation/tests/RelationChecker.java

    r14436 r14437  
    1919import org.openstreetmap.josm.data.osm.Relation;
    2020import org.openstreetmap.josm.data.osm.RelationMember;
     21import org.openstreetmap.josm.data.validation.OsmValidator;
    2122import org.openstreetmap.josm.data.validation.Severity;
    2223import org.openstreetmap.josm.data.validation.Test;
    2324import org.openstreetmap.josm.data.validation.TestError;
     25import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2426import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
    2527import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItem;
     
    6163     */
    6264    public static final String ROLE_VERIF_PROBLEM_MSG = tr("Role verification problem");
     65    private boolean ignoreMultiPolygons;
    6366
    6467    /**
     
    100103
    101104    @Override
     105    public void startTest(ProgressMonitor progressMonitor) {
     106        super.startTest(progressMonitor);
     107
     108        for (Test t : OsmValidator.getEnabledTests(false)) {
     109            if (t instanceof MultipolygonTest) {
     110                ignoreMultiPolygons = true;
     111                break;
     112            }
     113        }
     114    }
     115
     116    @Override
    102117    public void visit(Relation n) {
     118        Map<String, RoleInfo> map = buildRoleInfoMap(n);
     119        if (map.isEmpty()) {
     120            errors.add(TestError.builder(this, Severity.ERROR, RELATION_EMPTY)
     121                    .message(tr("Relation is empty"))
     122                    .primitives(n)
     123                    .build());
     124        }
     125        if (ignoreMultiPolygons && n.isMultipolygon()) {
     126            // see #17010: don't report same problem twice
     127            return;
     128        }
    103129        Map<Role, String> allroles = buildAllRoles(n);
    104130        if (allroles.isEmpty() && n.hasTag("type", "route")
     
    115141        }
    116142
    117         Map<String, RoleInfo> map = buildRoleInfoMap(n);
    118         if (map.isEmpty()) {
    119             errors.add(TestError.builder(this, Severity.ERROR, RELATION_EMPTY)
    120                     .message(tr("Relation is empty"))
    121                     .primitives(n)
    122                     .build());
    123         } else if (!allroles.isEmpty()) {
     143        if (!map.isEmpty() && !allroles.isEmpty()) {
    124144            checkRoles(n, allroles, map);
    125145        }
Note: See TracChangeset for help on using the changeset viewer.