- Timestamp:
- 2020-02-10T23:58:33+01:00 (5 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/gui/autofilter
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java
r15838 r15839 16 16 import java.util.TreeSet; 17 17 import java.util.function.Consumer; 18 import java.util.regex.Matcher;19 import java.util.regex.Pattern;20 import java.util.stream.IntStream;21 18 22 19 import org.openstreetmap.josm.actions.mapmode.MapMode; … … 26 23 import org.openstreetmap.josm.data.osm.FilterModel; 27 24 import org.openstreetmap.josm.data.osm.OsmPrimitive; 28 import org.openstreetmap.josm.data.osm.OsmUtils;29 25 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent; 30 26 import org.openstreetmap.josm.data.osm.event.DataChangedEvent; … … 58 54 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent; 59 55 import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener; 60 import org.openstreetmap.josm.tools.Logging;61 56 62 57 /** … … 79 74 80 75 /** 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 /**86 76 * The unique instance. 87 77 */ … … 111 101 * The currently enabled rule, if any. 112 102 */ 113 privateAutoFilterRule enabledRule;103 AutoFilterRule enabledRule; 114 104 115 105 /** … … 143 133 && enabledRule.getMinZoomLevel() <= Selector.GeneralSelector.scale2level(map.mapView.getDist100Pixel())) { 144 134 // Retrieve the values from current rule visible on screen 145 NavigableSet<Integer> values = getNumericValues( enabledRule.getKey());135 NavigableSet<Integer> values = getNumericValues(); 146 136 // Make sure current auto filter button remains visible even if no data is found, to allow user to disable it 147 137 if (currentAutoFilter != null) { … … 155 145 } 156 146 157 class CompiledFilter extends Filter implements MatchSupplier {158 final String key;147 static class CompiledFilter extends Filter implements MatchSupplier { 148 final AutoFilterRule rule; 159 149 final int value; 160 150 161 CompiledFilter( String key, int value) {162 this. key = key;151 CompiledFilter(AutoFilterRule rule, int value) { 152 this.rule = rule; 163 153 this.value = value; 164 154 this.enable = true; 165 155 this.inverted = true; 166 this.text = key+ "=" + value;156 this.text = rule.getKey() + "=" + value; 167 157 } 168 158 … … 172 162 @Override 173 163 public boolean match(OsmPrimitive osm) { 174 return getTagValuesForPrimitive(key,osm).anyMatch(v -> v == value);164 return rule.getTagValuesForPrimitive(osm).anyMatch(v -> v == value); 175 165 } 176 166 }; … … 187 177 addButton(keyButton, Integer.MIN_VALUE, i++); 188 178 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); 191 181 AutoFilter autoFilter = new AutoFilter(label, filter.text, filter); 192 182 AutoFilterButton button = new AutoFilterButton(autoFilter); … … 214 204 } 215 205 216 private NavigableSet<Integer> getNumericValues( String key) {206 private NavigableSet<Integer> getNumericValues() { 217 207 DataSet ds = MainApplication.getLayerManager().getActiveDataSet(); 218 208 if (ds == null) { … … 221 211 BBox bbox = MainApplication.getMap().mapView.getState().getViewArea().getLatLonBoundsBox().toBBox(); 222 212 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); 224 214 ds.searchNodes(bbox).forEach(consumer); 225 215 ds.searchWays(bbox).forEach(consumer); 226 216 ds.searchRelations(bbox).forEach(consumer); 227 217 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);254 218 } 255 219 -
trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterRule.java
r15838 r15839 8 8 import java.util.function.IntFunction; 9 9 import java.util.function.ToIntFunction; 10 import java.util.regex.Matcher; 11 import java.util.regex.Pattern; 10 12 import java.util.stream.IntStream; 11 13 12 14 import org.openstreetmap.josm.data.osm.OsmPrimitive; 15 import org.openstreetmap.josm.data.osm.OsmUtils; 16 import org.openstreetmap.josm.data.preferences.BooleanProperty; 17 import org.openstreetmap.josm.tools.Logging; 13 18 14 19 /** … … 20 25 */ 21 26 public 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); 22 32 23 33 private final String key; … … 58 68 59 69 /** 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 62 73 */ 63 public IntFunction<String> getValueFormatter() {64 return valueFormatter ;74 public String formatValue(int value) { 75 return valueFormatter.apply(value); 65 76 } 66 77 … … 74 85 this.valueFormatter = Objects.requireNonNull(valueFormatter); 75 86 return this; 76 }77 78 /**79 * Returns a function which yields default values for the given OSM primitive80 * @return a function which yields default values for the given OSM primitive81 */82 public Function<OsmPrimitive, IntStream> getDefaultValueSupplier() {83 return defaultValueSupplier;84 87 } 85 88 … … 97 100 98 101 /** 99 * Returns a function which extracts a numeric value from an OSM value100 * @return a function which extracts a numeric value from an OSM value101 */102 public ToIntFunction<String> getValueExtractor() {103 return valueExtractor;104 }105 106 /**107 102 * Sets the function which extracts a numeric value from an OSM value 108 103 * @param valueExtractor the function which extracts a numeric value from an OSM value … … 113 108 this.valueExtractor = Objects.requireNonNull(valueExtractor); 114 109 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(); 115 138 } 116 139
Note:
See TracChangeset
for help on using the changeset viewer.