Ignore:
Timestamp:
2024-01-30T09:04:11+01:00 (18 months ago)
Author:
GerdP
Message:

fix #23397: Improve the results of partial validations

  • pass also parent ways and relations of uploaded/selected objects to the testers, child objects are already added, this allows to find e.g. overlapping polygons problems with tags in members of relations
  • let CrossingWays find a problem if at least one of the crossing ways is in the partial selection.
  • let DuplicatWays find a problem if at least one of the duplicated ways is in the partial selection
  • add code to filter the detected issues so that those issues which are clearly not related to the original list of objects are removed. A few issues from mapcss tests may remain.
  • add new preference validator.partial.add.parents to disable the addition of parent objects, default is enabled
  • add new preference validator.partial.removeIrrelevant to disable the filtering of irrelevant errors, default is enabled
  • duplicated code to call AggregatePrimitivesVisitor was moved to ValidationTask
File:
1 edited

Legend:

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

    r18850 r18960  
    77import java.util.ArrayList;
    88import java.util.Collection;
     9import java.util.Collections;
     10import java.util.HashSet;
    911import java.util.List;
     12import java.util.Set;
    1013import java.util.function.BiConsumer;
    1114import java.util.function.Consumer;
     
    1417
    1518import org.openstreetmap.josm.data.osm.OsmPrimitive;
     19import org.openstreetmap.josm.data.osm.Way;
    1620import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper;
     21import org.openstreetmap.josm.data.validation.util.AggregatePrimitivesVisitor;
    1722import org.openstreetmap.josm.gui.MainApplication;
    1823import org.openstreetmap.josm.gui.MapFrame;
     
    3136    private final Consumer<List<TestError>> onFinish;
    3237    private Collection<Test> tests;
    33     private final Collection<OsmPrimitive> validatedPrimitives;
     38    private final Collection<OsmPrimitive> initialPrimitives;
    3439    private final Collection<OsmPrimitive> formerValidatedPrimitives;
    3540    private final boolean beforeUpload;
     
    7277                false /*don't ignore exceptions */);
    7378        this.onFinish = onFinish;
    74         this.validatedPrimitives = validatedPrimitives;
     79        this.initialPrimitives = validatedPrimitives;
    7580        this.formerValidatedPrimitives = formerValidatedPrimitives;
    7681        this.tests = tests;
     
    7883    }
    7984
     85    /**
     86     * Find objects parent objects of given objects which should be checked for geometry problems
     87     * or mismatches between child tags and parent tags.
     88     * @param primitives the given objects
     89     * @return the collection of relevant parent objects
     90     */
     91    private static Set<OsmPrimitive> getRelevantParents(Collection<OsmPrimitive> primitives) {
     92        Set<OsmPrimitive> addedWays = new HashSet<>();
     93        Set<OsmPrimitive> addedRelations = new HashSet<>();
     94        for (OsmPrimitive p : primitives) {
     95            for (OsmPrimitive parent : p.getReferrers()) {
     96                if (parent.isDeleted())
     97                    continue;
     98                if (parent instanceof Way)
     99                    addedWays.add(parent);
     100                else
     101                    addedRelations.add(parent);
     102            }
     103        }
     104
     105        // allow to find invalid multipolygon relations caused by moved nodes
     106        OsmPrimitive.getParentRelations(addedWays).stream().filter(r -> r.isMultipolygon() && !r.isDeleted())
     107                .forEach(addedRelations::add);
     108        HashSet<OsmPrimitive> extendedSet = new HashSet<>();
     109        extendedSet.addAll(addedWays);
     110        extendedSet.addAll(addedRelations);
     111        return extendedSet;
     112
     113    }
    80114    protected ValidationTask(ProgressMonitor progressMonitor,
    81115            Collection<Test> tests,
     
    123157        if (Utils.isEmpty(tests))
    124158            return;
     159        int testCounter = 0;
     160        final boolean isPartial = this.beforeUpload || formerValidatedPrimitives != null;
     161        Set<OsmPrimitive> filter = null;
     162        Collection<OsmPrimitive> validatedPrimitives = initialPrimitives;
     163        if (isPartial) {
     164            Set<OsmPrimitive> other = Collections.emptySet();
     165            if (Boolean.TRUE.equals(ValidatorPrefHelper.PREF_ADD_PARENTS.get())) {
     166                other = getRelevantParents(initialPrimitives);
     167            }
     168            HashSet<OsmPrimitive> extendedSet = new HashSet<>();
     169            AggregatePrimitivesVisitor v = new AggregatePrimitivesVisitor();
     170            extendedSet.addAll(v.visit(initialPrimitives));
     171            extendedSet.addAll(other);
     172            validatedPrimitives = extendedSet;
     173            filter = new HashSet<>(initialPrimitives);
     174            filter.addAll(other);
     175        }
    125176        getProgressMonitor().setTicksCount(tests.size() * validatedPrimitives.size());
    126         int testCounter = 0;
     177
    127178        for (Test test : tests) {
    128179            if (canceled)
     
    132183            test.setBeforeUpload(this.beforeUpload);
    133184            // Pre-upload checks only run on a partial selection.
    134             test.setPartialSelection(this.beforeUpload || formerValidatedPrimitives != null);
     185            test.setPartialSelection(isPartial);
    135186            test.startTest(getProgressMonitor().createSubTaskMonitor(validatedPrimitives.size(), false));
    136187            test.visit(validatedPrimitives);
    137188            test.endTest();
     189            if (isPartial && Boolean.TRUE.equals(ValidatorPrefHelper.PREF_REMOVE_IRRELEVANT.get())) {
     190                // #23397: remove errors for objects which were not in the initial list of primitives
     191                test.removeIrrelevantErrors(filter);
     192            }
     193
    138194            errors.addAll(test.getErrors());
    139195            if (this.testConsumer != null) {
Note: See TracChangeset for help on using the changeset viewer.