Ticket #24482: autofilter_01_repeat_on.patch

File autofilter_01_repeat_on.patch, 6.4 KB (added by tordanik, 8 months ago)
  • src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java

    diff --git a/src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java b/src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java
    index 9c35c387e9..f722122bd6 100644
    a b  
    22package org.openstreetmap.josm.gui.autofilter;
    33
    44import java.text.DecimalFormat;
    5 import java.util.Arrays;
    6 import java.util.Locale;
    7 import java.util.Objects;
    8 import java.util.Optional;
     5import java.util.*;
    96import java.util.function.Function;
    107import java.util.function.IntFunction;
    118import java.util.function.ToIntFunction;
    129import java.util.regex.Matcher;
    1310import java.util.regex.Pattern;
    1411import java.util.stream.IntStream;
     12import java.util.stream.Stream;
    1513
    1614import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1715import org.openstreetmap.josm.data.osm.OsmUtils;
    1816import org.openstreetmap.josm.data.preferences.BooleanProperty;
    1917import org.openstreetmap.josm.tools.Logging;
    2018
     19import static java.util.stream.Collectors.toList;
     20
    2121/**
    2222 * An auto filter rule determines how auto filter can be built from visible map data.
    2323 * Several rules can be registered, but only one rule is active at the same time.
    public class AutoFilterRule {  
    4242
    4343    private IntFunction<String> valueFormatter = Integer::toString;
    4444
     45    /** The union of {@link #key} and the keys provided by {@link #setExtraKeys(List)}. */
     46    private List<String> allKeys;
     47
    4548    /**
    4649     * Constructs a new {@code AutoFilterRule}.
    4750     * @param key the OSM key on which the rule applies
    public class AutoFilterRule {  
    5053    public AutoFilterRule(String key, int minZoomLevel) {
    5154        this.key = key;
    5255        this.minZoomLevel = minZoomLevel;
     56        this.allKeys = List.of(key);
    5357    }
    5458
    5559    /**
    public class AutoFilterRule {  
    111115        return this;
    112116    }
    113117
     118    /**
     119     * Sets extra OSM keys on which the rule applies in addition to the primary key ({@link #getKey()}).
     120     * This allows a filter to look at the values of more than one key at the same time.
     121     * @param extraKeys the list of extra keys, may be empty
     122     * @return {@code this}
     123     * @throws NullPointerException if {@code extraKeys} is null
     124     */
     125    public AutoFilterRule setExtraKeys(List<String> extraKeys) {
     126        Objects.requireNonNull(extraKeys);
     127        this.allKeys = Stream.concat(Stream.of(key), extraKeys.stream()).collect(toList());
     128        return this;
     129    }
     130
    114131    /**
    115132     * Returns the numeric values for the given OSM primitive
    116133     * @param osm the primitive
    117134     * @return a stream of numeric values
    118135     */
    119136    public IntStream getTagValuesForPrimitive(OsmPrimitive osm) {
     137        if (allKeys.size() == 1) {
     138            IntStream values = getTagValuesForPrimitive(osm, key);
     139            if (values != null) return values;
     140        } else {
     141            Set<Integer> allValues = new HashSet<>();
     142            for (String k : allKeys) {
     143                IntStream values = getTagValuesForPrimitive(osm, k);
     144                if (values != null) { values.forEach(allValues::add); }
     145            }
     146            if (!allValues.isEmpty()) return allValues.stream().mapToInt(it -> it).sorted();
     147        }
     148        return Boolean.TRUE.equals(PROP_AUTO_FILTER_DEFAULTS.get()) ? defaultValueSupplier.apply(osm) : IntStream.empty();
     149    }
     150
     151    private IntStream getTagValuesForPrimitive(OsmPrimitive osm, String key) {
    120152        String value = osm.get(key);
    121153        if (value != null) {
    122154            Pattern p = Pattern.compile("(-?[0-9]+)-(-?[0-9]+)");
    public class AutoFilterRule {  
    136168                }
    137169            });
    138170        }
    139         return Boolean.TRUE.equals(PROP_AUTO_FILTER_DEFAULTS.get()) ? defaultValueSupplier.apply(osm) : IntStream.empty();
     171        return null;
    140172    }
    141173
    142174    /**
    public class AutoFilterRule {  
    156188            new AutoFilterRule("layer", 16)
    157189                    .setDefaultValueSupplier(AutoFilterRule::defaultLayer),
    158190            new AutoFilterRule("level", 17)
     191                .setExtraKeys(List.of("repeat_on"))
    159192                // #17109, support values like 0.5 or 1.5 - level values are multiplied by 2 when parsing, values are divided by 2 for formatting
    160193                .setValueExtractor(s -> (int) (Double.parseDouble(s) * 2.))
    161194                .setValueFormatter(v -> DecimalFormat.getInstance(Locale.ROOT).format(v / 2.)),
  • test/unit/org/openstreetmap/josm/gui/autofilter/AutoFilterRuleTest.java

    diff --git a/test/unit/org/openstreetmap/josm/gui/autofilter/AutoFilterRuleTest.java b/test/unit/org/openstreetmap/josm/gui/autofilter/AutoFilterRuleTest.java
    index d68b4bcaec..ae1b15b909 100644
    a b import org.junit.jupiter.api.Test;  
    2222@I18n
    2323class AutoFilterRuleTest {
    2424    /**
    25      * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive}.
     25     * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive(OsmPrimitive)}.
    2626     */
    2727    @Test
    2828    void testTagValuesForPrimitive() {
    class AutoFilterRuleTest {  
    3636        assertTagValuesForPrimitive(level, "way level=6-9", 12, 13, 14, 15, 16, 17, 18);
    3737        assertTagValuesForPrimitive(level, "way level=10;12-13", 20, 24, 25, 26);
    3838        assertTagValuesForPrimitive(level, "way level=0;0.5;1;1.5;2;2.5;3", 0, 1, 2, 3, 4, 5, 6);
     39        assertTagValuesForPrimitive(level, "node level=0 repeat_on=1;2", 0, 2, 4);
     40        assertTagValuesForPrimitive(level, "way level=4 repeat_on=4;5 layer=1", 8, 10);
    3941        assertEquals("0 0.5 1 1.5 2 2.5 3",
    4042                IntStream.of(0, 1, 2, 3, 4, 5, 6).mapToObj(level::formatValue).collect(Collectors.joining(" ")));
    4143    }
    4244
    4345    /**
    44      * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive} to deal with {@code %} of key {@code incline}.
     46     * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive(OsmPrimitive)} to deal with {@code %} of key {@code incline}.
    4547     */
    4648    @Test
    4749    void testTagValuesForPrimitiveInclineUnit() {
    class AutoFilterRuleTest {  
    5254    }
    5355
    5456    /**
    55      * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive} provides sensible defaults, see #17496.
     57     * Unit test of {@link AutoFilterRule#getTagValuesForPrimitive(OsmPrimitive)} provides sensible defaults, see #17496.
    5658     */
    5759    @Test
    5860    void testTagValuesForPrimitivesDefaults() {