Index: trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 15763)
+++ trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java	(revision 15764)
@@ -19,4 +19,5 @@
 import java.util.Optional;
 import java.util.function.Predicate;
+import java.util.function.Supplier;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -264,4 +265,15 @@
 
     /**
+     * Classes implementing this interface can provide Match instances themselves and do not rely on {@link #compile(String)}.
+     *
+     * @since 15764
+     */
+    @FunctionalInterface
+    public interface MatchSupplier extends Supplier<Match> {
+        @Override
+        Match get();
+    }
+
+    /**
      * Base class for all search criteria. If the criterion only depends on an object's tags,
      * inherit from {@link org.openstreetmap.josm.data.osm.search.SearchCompiler.TaggedMatch}.
@@ -1944,4 +1956,7 @@
      */
     public static Match compile(SearchSetting setting) throws SearchParseError {
+        if (setting instanceof MatchSupplier) {
+            return ((MatchSupplier) setting).get();
+        }
         if (setting.mapCSSSearch) {
             return compileMapCSS(setting.text);
Index: trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java	(revision 15763)
+++ trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java	(revision 15764)
@@ -20,4 +20,6 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
 
 import org.openstreetmap.josm.actions.mapmode.MapMode;
@@ -27,4 +29,5 @@
 import org.openstreetmap.josm.data.osm.FilterModel;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
 import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
@@ -38,4 +41,6 @@
 import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
 import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
+import org.openstreetmap.josm.data.osm.search.SearchCompiler;
+import org.openstreetmap.josm.data.osm.search.SearchCompiler.MatchSupplier;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.data.preferences.StringProperty;
@@ -77,4 +82,9 @@
 
     /**
+     * Property to determine if the auto filter should assume sensible defaults for values (such as layer=1 for bridge=yes).
+     */
+    private static final BooleanProperty PROP_AUTO_FILTER_DEFAULTS = new BooleanProperty("auto.filter.defaults", true);
+
+    /**
      * The unique instance.
      */
@@ -148,4 +158,27 @@
     }
 
+    static class CompiledFilter extends Filter implements MatchSupplier {
+        final String key;
+        final String value;
+
+        CompiledFilter(String key, String value) {
+            this.key = key;
+            this.value = value;
+            this.enable = true;
+            this.inverted = true;
+            this.text = key + "=" + value;
+        }
+
+        @Override
+        public SearchCompiler.Match get() {
+            return new SearchCompiler.Match() {
+                @Override
+                public boolean match(OsmPrimitive osm) {
+                    return getTagValuesForPrimitive(key, osm).anyMatch(value::equals);
+                }
+            };
+        }
+    }
+
     private synchronized void addNewButtons(NavigableSet<String> values) {
         int i = 0;
@@ -153,8 +186,5 @@
         MapView mapView = MainApplication.getMap().mapView;
         for (final String value : values.descendingSet()) {
-            Filter filter = new Filter();
-            filter.enable = true;
-            filter.inverted = true;
-            filter.text = enabledRule.getKey() + "=" + value;
+            Filter filter = new CompiledFilter(enabledRule.getKey(), value);
             String label = enabledRule.getValueFormatter().apply(value);
             AutoFilter autoFilter = new AutoFilter(label, filter.text, filter);
@@ -198,5 +228,5 @@
         if (ds != null) {
             BBox bbox = MainApplication.getMap().mapView.getState().getViewArea().getLatLonBoundsBox().toBBox();
-            Consumer<OsmPrimitive> consumer = getTagValuesConsumer(key, values);
+            Consumer<OsmPrimitive> consumer = o -> getTagValuesForPrimitive(key, o).forEach(values::add);
             ds.searchNodes(bbox).forEach(consumer);
             ds.searchWays(bbox).forEach(consumer);
@@ -206,23 +236,30 @@
     }
 
-    static Consumer<OsmPrimitive> getTagValuesConsumer(String key, Set<String> values) {
-        return o -> {
-            String value = o.get(key);
-            if (value != null) {
-                Pattern p = Pattern.compile("(-?[0-9]+)-(-?[0-9]+)");
-                for (String v : value.split(";")) {
-                    Matcher m = p.matcher(v);
-                    if (m.matches()) {
-                        int a = Integer.parseInt(m.group(1));
-                        int b = Integer.parseInt(m.group(2));
-                        for (int i = Math.min(a, b); i <= Math.max(a, b); i++) {
-                            values.add(Integer.toString(i));
-                        }
-                    } else {
-                        values.add(v);
-                    }
+    static Stream<String> getTagValuesForPrimitive(String key, OsmPrimitive osm) {
+        String value = osm.get(key);
+        if (value != null) {
+            Pattern p = Pattern.compile("(-?[0-9]+)-(-?[0-9]+)");
+            return OsmUtils.splitMultipleValues(value).flatMap(v -> {
+                Matcher m = p.matcher(v);
+                if (m.matches()) {
+                    int a = Integer.parseInt(m.group(1));
+                    int b = Integer.parseInt(m.group(2));
+                    return IntStream.rangeClosed(Math.min(a, b), Math.max(a, b))
+                            .mapToObj(Integer::toString);
+                } else {
+                    return Stream.of(v);
                 }
-            }
-        };
+            });
+        } else if (PROP_AUTO_FILTER_DEFAULTS.get() && "layer".equals(key)) {
+            // assume sensible defaults, see #17496
+            if (osm.hasTag("bridge") || osm.hasTag("power", "line") || osm.hasTag("location", "overhead")) {
+                return Stream.of("1");
+            } else if (osm.isKeyTrue("tunnel") || osm.hasTag("tunnel", "culvert") || osm.hasTag("location", "underground")) {
+                return Stream.of("-1");
+            } else if (osm.hasTag("tunnel", "building_passage") || osm.hasKey("highway", "railway", "waterway")) {
+                return Stream.of("0");
+            }
+        }
+        return Stream.empty();
     }
 
Index: trunk/test/unit/org/openstreetmap/josm/gui/autofilter/AutoFilterManagerTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/autofilter/AutoFilterManagerTest.java	(revision 15763)
+++ trunk/test/unit/org/openstreetmap/josm/gui/autofilter/AutoFilterManagerTest.java	(revision 15764)
@@ -3,13 +3,13 @@
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 
 import java.util.Arrays;
-import java.util.Set;
 import java.util.TreeSet;
-import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmUtils;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
@@ -30,11 +30,9 @@
 
     /**
-     * Unit test of {@link AutoFilterManager#getTagValuesConsumer}.
+     * Unit test of {@link AutoFilterManager#getTagValuesForPrimitive}.
      */
     @Test
-    public void testTagValuesConsumer() {
-        Set<String> values = new TreeSet<>();
-        Consumer<OsmPrimitive> consumer = AutoFilterManager.getTagValuesConsumer("level", values);
-        Arrays.asList(
+    public void testTagValuesForPrimitive() {
+        final TreeSet<String> values = Stream.of(
                 OsmUtils.createPrimitive("way level=-4--5"),
                 OsmUtils.createPrimitive("way level=-2"),
@@ -43,7 +41,30 @@
                 OsmUtils.createPrimitive("way level=2;3"),
                 OsmUtils.createPrimitive("way level=6-9"),
-                OsmUtils.createPrimitive("way level=10;12-13")
-                ).forEach(consumer);
+                OsmUtils.createPrimitive("way level=10;12-13"))
+                .flatMap(o -> AutoFilterManager.getTagValuesForPrimitive("level", o))
+                .collect(Collectors.toCollection(TreeSet::new));
         assertEquals(new TreeSet<>(Arrays.asList("-5", "-4", "-2", "0", "1", "2", "3", "6", "7", "8", "9", "10", "12", "13")), values);
+
+    }
+
+    /**
+     * Unit test of {@link AutoFilterManager#getTagValuesForPrimitive} provides sensible defaults, see #17496.
+     */
+    @Test
+    public void testTagValuesForPrimitivesDefaults() {
+        assertNull(getLayer("way foo=bar"));
+        assertEquals("1", getLayer("way bridge=yes"));
+        assertEquals("1", getLayer("way power=line"));
+        assertEquals("-1", getLayer("way tunnel=yes"));
+        assertEquals("0", getLayer("way tunnel=building_passage"));
+        assertEquals("0", getLayer("way highway=residential"));
+        assertEquals("0", getLayer("way railway=rail"));
+        assertEquals("0", getLayer("way waterway=canal"));
+    }
+
+    private String getLayer(final String assertion) {
+        return AutoFilterManager.getTagValuesForPrimitive("layer", OsmUtils.createPrimitive(assertion))
+                .findFirst()
+                .orElse(null);
     }
 }
