Changeset 15839 in josm


Ignore:
Timestamp:
2020-02-10T23:58:33+01:00 (2 weeks ago)
Author:
simon04
Message:

see #18679 - Autofilter: refactoring

Location:
trunk
Files:
1 added
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java

    r15838 r15839  
    1616import java.util.TreeSet;
    1717import java.util.function.Consumer;
    18 import java.util.regex.Matcher;
    19 import java.util.regex.Pattern;
    20 import java.util.stream.IntStream;
    2118
    2219import org.openstreetmap.josm.actions.mapmode.MapMode;
     
    2623import org.openstreetmap.josm.data.osm.FilterModel;
    2724import org.openstreetmap.josm.data.osm.OsmPrimitive;
    28 import org.openstreetmap.josm.data.osm.OsmUtils;
    2925import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
    3026import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
     
    5854import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
    5955import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
    60 import org.openstreetmap.josm.tools.Logging;
    6156
    6257/**
     
    7974
    8075    /**
    81      * Property to determine if the auto filter should assume sensible defaults for values (such as layer=1 for bridge=yes).
    82      */
    83     private static final BooleanProperty PROP_AUTO_FILTER_DEFAULTS = new BooleanProperty("auto.filter.defaults", true);
    84 
    85     /**
    8676     * The unique instance.
    8777     */
     
    111101     * The currently enabled rule, if any.
    112102     */
    113     private AutoFilterRule enabledRule;
     103    AutoFilterRule enabledRule;
    114104
    115105    /**
     
    143133                && enabledRule.getMinZoomLevel() <= Selector.GeneralSelector.scale2level(map.mapView.getDist100Pixel())) {
    144134            // Retrieve the values from current rule visible on screen
    145             NavigableSet<Integer> values = getNumericValues(enabledRule.getKey());
     135            NavigableSet<Integer> values = getNumericValues();
    146136            // Make sure current auto filter button remains visible even if no data is found, to allow user to disable it
    147137            if (currentAutoFilter != null) {
     
    155145    }
    156146
    157     class CompiledFilter extends Filter implements MatchSupplier {
    158         final String key;
     147    static class CompiledFilter extends Filter implements MatchSupplier {
     148        final AutoFilterRule rule;
    159149        final int value;
    160150
    161         CompiledFilter(String key, int value) {
    162             this.key = key;
     151        CompiledFilter(AutoFilterRule rule, int value) {
     152            this.rule = rule;
    163153            this.value = value;
    164154            this.enable = true;
    165155            this.inverted = true;
    166             this.text = key + "=" + value;
     156            this.text = rule.getKey() + "=" + value;
    167157        }
    168158
     
    172162                @Override
    173163                public boolean match(OsmPrimitive osm) {
    174                     return getTagValuesForPrimitive(key, osm).anyMatch(v -> v == value);
     164                    return rule.getTagValuesForPrimitive(osm).anyMatch(v -> v == value);
    175165                }
    176166            };
     
    187177        addButton(keyButton, Integer.MIN_VALUE, i++);
    188178        for (final Integer value : values.descendingSet()) {
    189             CompiledFilter filter = new CompiledFilter(enabledRule.getKey(), value);
    190             String label = enabledRule.getValueFormatter().apply(value);
     179            CompiledFilter filter = new CompiledFilter(enabledRule, value);
     180            String label = enabledRule.formatValue(value);
    191181            AutoFilter autoFilter = new AutoFilter(label, filter.text, filter);
    192182            AutoFilterButton button = new AutoFilterButton(autoFilter);
     
    214204    }
    215205
    216     private NavigableSet<Integer> getNumericValues(String key) {
     206    private NavigableSet<Integer> getNumericValues() {
    217207        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
    218208        if (ds == null) {
     
    221211        BBox bbox = MainApplication.getMap().mapView.getState().getViewArea().getLatLonBoundsBox().toBBox();
    222212        NavigableSet<Integer> values = new TreeSet<>();
    223         Consumer<OsmPrimitive> consumer = o -> getTagValuesForPrimitive(key, o).forEach(values::add);
     213        Consumer<OsmPrimitive> consumer = o -> enabledRule.getTagValuesForPrimitive(o).forEach(values::add);
    224214        ds.searchNodes(bbox).forEach(consumer);
    225215        ds.searchWays(bbox).forEach(consumer);
    226216        ds.searchRelations(bbox).forEach(consumer);
    227217        return values;
    228     }
    229 
    230     protected IntStream getTagValuesForPrimitive(String key, OsmPrimitive osm) {
    231         if (enabledRule == null) {
    232             return IntStream.empty();
    233         }
    234         String value = osm.get(key);
    235         if (value != null) {
    236             Pattern p = Pattern.compile("(-?[0-9]+)-(-?[0-9]+)");
    237             return OsmUtils.splitMultipleValues(value).flatMapToInt(v -> {
    238                 Matcher m = p.matcher(v);
    239                 if (m.matches()) {
    240                     int a = Integer.parseInt(m.group(1));
    241                     int b = Integer.parseInt(m.group(2));
    242                     return IntStream.rangeClosed(Math.min(a, b), Math.max(a, b));
    243                 } else {
    244                     try {
    245                         return IntStream.of(enabledRule.getValueExtractor().applyAsInt(v));
    246                     } catch (NumberFormatException e) {
    247                         Logging.trace(e);
    248                         return IntStream.empty();
    249                     }
    250                 }
    251             });
    252         }
    253         return enabledRule.getDefaultValueSupplier().apply(osm);
    254218    }
    255219
  • trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java

    r15838 r15839  
    88import java.util.function.IntFunction;
    99import java.util.function.ToIntFunction;
     10import java.util.regex.Matcher;
     11import java.util.regex.Pattern;
    1012import java.util.stream.IntStream;
    1113
    1214import org.openstreetmap.josm.data.osm.OsmPrimitive;
     15import org.openstreetmap.josm.data.osm.OsmUtils;
     16import org.openstreetmap.josm.data.preferences.BooleanProperty;
     17import org.openstreetmap.josm.tools.Logging;
    1318
    1419/**
     
    2025 */
    2126public class AutoFilterRule {
     27
     28    /**
     29     * Property to determine if the auto filter should assume sensible defaults for values (such as layer=1 for bridge=yes).
     30     */
     31    private static final BooleanProperty PROP_AUTO_FILTER_DEFAULTS = new BooleanProperty("auto.filter.defaults", true);
    2232
    2333    private final String key;
     
    5868
    5969    /**
    60      * Returns the OSM value formatter that defines the associated button label.
    61      * @return the OSM value formatter that defines the associated button label (identity by default)
     70     * Formats the numeric value
     71     * @param value the numeric value to format
     72     * @return the formatted value
    6273     */
    63     public IntFunction<String> getValueFormatter() {
    64         return valueFormatter;
     74    public String formatValue(int value) {
     75        return valueFormatter.apply(value);
    6576    }
    6677
     
    7485        this.valueFormatter = Objects.requireNonNull(valueFormatter);
    7586        return this;
    76     }
    77 
    78     /**
    79      * Returns a function which yields default values for the given OSM primitive
    80      * @return a function which yields default values for the given OSM primitive
    81      */
    82     public Function<OsmPrimitive, IntStream> getDefaultValueSupplier() {
    83         return defaultValueSupplier;
    8487    }
    8588
     
    97100
    98101    /**
    99      * Returns a function which extracts a numeric value from an OSM value
    100      * @return a function which extracts a numeric value from an OSM value
    101      */
    102     public ToIntFunction<String> getValueExtractor() {
    103         return valueExtractor;
    104     }
    105 
    106     /**
    107102     * Sets the function which extracts a numeric value from an OSM value
    108103     * @param valueExtractor the function which extracts a numeric value from an OSM value
     
    113108        this.valueExtractor = Objects.requireNonNull(valueExtractor);
    114109        return this;
     110    }
     111
     112    /**
     113     * Returns the numeric values for the given OSM primitive
     114     * @param osm the primitive
     115     * @return a stream of numeric values
     116     */
     117    public IntStream getTagValuesForPrimitive(OsmPrimitive osm) {
     118        String value = osm.get(key);
     119        if (value != null) {
     120            Pattern p = Pattern.compile("(-?[0-9]+)-(-?[0-9]+)");
     121            return OsmUtils.splitMultipleValues(value).flatMapToInt(v -> {
     122                Matcher m = p.matcher(v);
     123                if (m.matches()) {
     124                    int a = Integer.parseInt(m.group(1));
     125                    int b = Integer.parseInt(m.group(2));
     126                    return IntStream.rangeClosed(Math.min(a, b), Math.max(a, b));
     127                } else {
     128                    try {
     129                        return IntStream.of(valueExtractor.applyAsInt(v));
     130                    } catch (NumberFormatException e) {
     131                        Logging.trace(e);
     132                        return IntStream.empty();
     133                    }
     134                }
     135            });
     136        }
     137        return PROP_AUTO_FILTER_DEFAULTS.get() ? defaultValueSupplier.apply(osm) : IntStream.empty();
    115138    }
    116139
Note: See TracChangeset for help on using the changeset viewer.