Ticket #13805: 13805-grouped.patch

File 13805-grouped.patch, 6.8 KB (added by GerdP, 6 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java

     
    55
    66import java.awt.geom.Area;
    77import java.io.BufferedReader;
     8import java.io.File;
    89import java.io.IOException;
    910import java.io.InputStream;
    1011import java.io.Reader;
     
    1718import java.util.LinkedList;
    1819import java.util.List;
    1920import java.util.Map;
     21import java.util.Map.Entry;
    2022import java.util.Objects;
    2123import java.util.Optional;
    2224import java.util.Set;
     
    6668import org.openstreetmap.josm.tools.I18n;
    6769import org.openstreetmap.josm.tools.Logging;
    6870import org.openstreetmap.josm.tools.MultiMap;
     71import org.openstreetmap.josm.tools.Stopwatch;
    6972import org.openstreetmap.josm.tools.Utils;
    7073
    7174/**
     
    7578public class MapCSSTagChecker extends Test.TagTest {
    7679    private MapCSSStyleIndex indexData;
    7780    final Map<MapCSSRule, MapCSSTagCheckerAndRule> ruleToCheckMap = new HashMap<>();
    78     private final Set<OsmPrimitive> tested = new HashSet<>();
    7981    private static final Map<IPrimitive, Area> mpAreaCache = new HashMap<>();
    8082    static final boolean ALL_TESTS = true;
    8183    static final boolean ONLY_SELECTED_TESTS = false;
     
    762764        for (TestError e : getErrorsForPrimitive(p, ValidatorPrefHelper.PREF_OTHER.get())) {
    763765            addIfNotSimilar(e, errors);
    764766        }
    765         if (partialSelection) {
    766             tested.add(p);
    767         }
    768767    }
    769768
    770769    /**
     
    855854    public synchronized void startTest(ProgressMonitor progressMonitor) {
    856855        super.startTest(progressMonitor);
    857856        super.setShowElements(true);
    858         if (indexData == null) {
    859             indexData = createMapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), ALL_TESTS);
     857    }
     858
     859    @Override
     860    public synchronized void endTest() {
     861        // no need to keep the index, it is quickly build and doubles the memory needs
     862        indexData = null;
     863        // always clear the cache to make sure that we catch changes in geometry
     864        mpAreaCache.clear();
     865        super.endTest();
     866    }
     867
     868    @Override
     869    public void visit(Collection<OsmPrimitive> selection) {
     870        if (progressMonitor != null) {
     871            progressMonitor.setTicksCount(selection.size() * checks.size());
    860872        }
    861         tested.clear();
     873
    862874        mpAreaCache.clear();
     875
     876        Set<OsmPrimitive> surrounding = new HashSet<>();
     877        for (Entry<String, Set<TagCheck>> entry : checks.entrySet()) {
     878            if (isCanceled()) {
     879                break;
     880            }
     881            visit(entry.getKey(), entry.getValue(), selection, surrounding);
     882        }
    863883    }
    864884
    865     @Override
    866     public synchronized void endTest() {
     885    /**
     886     * Perform the checks for one check url
     887     * @param url the url for the checks
     888     * @param checksForUrl the checks to perform
     889     * @param selection collection primitives
     890     * @param surrounding surrounding primitives, evtl. filled by this routine
     891     */
     892    private void visit(String url, Set<TagCheck> checksForUrl, Collection<OsmPrimitive> selection,
     893            Set<OsmPrimitive> surrounding) {
     894        MultiMap<String, TagCheck> currentCheck = new MultiMap<>();
     895        currentCheck.putAll(url, checksForUrl);
     896        indexData = createMapCSSTagCheckerIndex(currentCheck, includeOtherSeverityChecks(), ALL_TESTS);
     897        Set<OsmPrimitive> tested = new HashSet<>();
     898
     899
     900        String source = simplifySourceName(url);
     901        if (progressMonitor != null) {
     902            progressMonitor.setExtraText(tr(" {0}", source));
     903        }
     904        long cnt = 0;
     905        Stopwatch stopwatch = Stopwatch.createStarted();
     906        for (OsmPrimitive p : selection) {
     907            if (isCanceled()) {
     908                break;
     909            }
     910            if (isPrimitiveUsable(p)) {
     911                check(p);
     912                if (partialSelection) {
     913                    tested.add(p);
     914                }
     915            }
     916            if (progressMonitor != null) {
     917                progressMonitor.worked(1);
     918                cnt++;
     919                // add frequently changing info to progress monitor so that it
     920                // doesn't seem to hang when test takes longer than 0.5 seconds
     921                if (cnt % 10000 == 0 && stopwatch.elapsed() >= 500) {
     922                    progressMonitor
     923                            .setExtraText(tr(" {0}: {1} of {2} elements done", source, cnt, selection.size()));
     924                }
     925            }
     926        }
     927
    867928        if (partialSelection && !tested.isEmpty()) {
    868929            // #14287: see https://josm.openstreetmap.de/ticket/14287#comment:15
    869930            // execute tests for objects which might contain or cross previously tested elements
     
    870931
    871932            // rebuild index with a reduced set of rules (those that use ChildOrParentSelector) and thus may have left selectors
    872933            // matching the previously tested elements
    873             indexData = createMapCSSTagCheckerIndex(checks, includeOtherSeverityChecks(), ONLY_SELECTED_TESTS);
     934            indexData = createMapCSSTagCheckerIndex(currentCheck, includeOtherSeverityChecks(), ONLY_SELECTED_TESTS);
    874935
    875             Set<OsmPrimitive> surrounding = new HashSet<>();
    876             for (OsmPrimitive p : tested) {
    877                 if (p.getDataSet() != null) {
    878                     surrounding.addAll(p.getDataSet().searchWays(p.getBBox()));
    879                     surrounding.addAll(p.getDataSet().searchRelations(p.getBBox()));
     936            if (surrounding.isEmpty()) {
     937                for (OsmPrimitive p : tested) {
     938                    if (p.getDataSet() != null) {
     939                        surrounding.addAll(p.getDataSet().searchWays(p.getBBox()));
     940                        surrounding.addAll(p.getDataSet().searchRelations(p.getBBox()));
     941                    }
    880942                }
    881943            }
     944
    882945            final boolean includeOtherSeverity = includeOtherSeverityChecks();
    883946            for (OsmPrimitive p : surrounding) {
    884947                if (tested.contains(p))
     
    889952                        addIfNotSimilar(e, errors);
    890953                }
    891954            }
    892             tested.clear();
    893955        }
    894         // no need to keep the index, it is quickly build and doubles the memory needs
    895         indexData = null;
    896         // always clear the cache to make sure that we catch changes in geometry
    897         mpAreaCache.clear();
    898         super.endTest();
    899956    }
     957
     958    private static String simplifySourceName(String source) {
     959        if (source.endsWith(".mapcss")) // do we have others?
     960            source = new File(source).getName();
     961        if (source.length() > 33) {
     962            source = "..." + source.substring(source.length() - 30);
     963        }
     964        return source;
     965    }
     966
    900967}