diff --git a/src/org/openstreetmap/josm/Main.java b/src/org/openstreetmap/josm/Main.java
index 70d7749..adf9d46 100644
--- a/src/org/openstreetmap/josm/Main.java
+++ b/src/org/openstreetmap/josm/Main.java
@@ -60,6 +60,7 @@ import org.openstreetmap.josm.gui.GettingStarted;
 import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.io.SaveLayersDialog;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -219,6 +220,9 @@ abstract public class Main {
      */
     public final void removeLayer(final Layer layer) {
         if (map != null) {
+            if (layer instanceof NavigatableComponent.ZoomChangeListener) {
+                MapView.removeZoomChangeListener((NavigatableComponent.ZoomChangeListener) layer);
+            }
             map.mapView.removeLayer(layer);
             if (map != null && map.mapView.getAllLayers().isEmpty()) {
                 setMapFrame(null);
diff --git a/src/org/openstreetmap/josm/gui/layer/WMSLayer.java b/src/org/openstreetmap/josm/gui/layer/WMSLayer.java
index 3b7175b..97e183e 100644
--- a/src/org/openstreetmap/josm/gui/layer/WMSLayer.java
+++ b/src/org/openstreetmap/josm/gui/layer/WMSLayer.java
@@ -19,6 +19,7 @@ import java.io.FileOutputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -59,6 +60,7 @@ import org.openstreetmap.josm.data.preferences.IntegerProperty;
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.NavigatableComponent.ZoomChangeListener;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
@@ -67,13 +69,14 @@ import org.openstreetmap.josm.io.imagery.HTMLGrabber;
 import org.openstreetmap.josm.io.imagery.WMSGrabber;
 import org.openstreetmap.josm.io.imagery.WMSRequest;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Utils;
 
 
 /**
  * This is a layer that grabs the current screen from an WMS server. The data
  * fetched this way is tiled and managed to the disc to reduce server load.
  */
-public class WMSLayer extends ImageryLayer implements ImageObserver, PreferenceChangedListener {
+public class WMSLayer extends ImageryLayer implements ImageObserver, PreferenceChangedListener, ZoomChangeListener {
 
     public static class PrecacheTask {
         private final ProgressMonitor progressMonitor;
@@ -107,7 +110,8 @@ public class WMSLayer extends ImageryLayer implements ImageObserver, PreferenceC
     public static final IntegerProperty PROP_OVERLAP_NORTH = new IntegerProperty("imagery.wms.overlapNorth", 4);
 
     public int messageNum = 5; //limit for messages per layer
-    protected String resolution;
+    protected double resolution;
+    protected String resolutionText;
     protected int imageSize = 500;
     protected int dax = 10;
     protected int day = 10;
@@ -176,7 +180,8 @@ public class WMSLayer extends ImageryLayer implements ImageObserver, PreferenceC
         if(this.info.getPixelPerDegree() == 0.0) {
             this.info.setPixelPerDegree(getPPD());
         }
-        resolution = mv.getDist100PixelText();
+        resolution = mv.getDist100Pixel();
+        resolutionText = mv.getDist100PixelText();
 
         attribution.initialize(this.info);
 
@@ -184,7 +189,7 @@ public class WMSLayer extends ImageryLayer implements ImageObserver, PreferenceC
             startGrabberThreads();
         }
 
-
+        MapView.addZoomChangeListener(this);
         Main.pref.addPreferenceChangeListener(this);
 
         SwingUtilities.invokeLater(new Runnable() {
@@ -293,9 +298,9 @@ public class WMSLayer extends ImageryLayer implements ImageObserver, PreferenceC
 
     @Override public String getToolTipText() {
         if(autoDownloadEnabled)
-            return tr("WMS layer ({0}), automatically downloading in zoom {1}", getName(), resolution);
+            return tr("WMS layer ({0}), automatically downloading in zoom {1}", getName(), resolutionText);
         else
-            return tr("WMS layer ({0}), downloading in zoom {1}", getName(), resolution);
+            return tr("WMS layer ({0}), downloading in zoom {1}", getName(), resolutionText);
     }
 
     private int modulo (int a, int b) {
@@ -667,21 +672,32 @@ public class WMSLayer extends ImageryLayer implements ImageObserver, PreferenceC
         }
     }
 
-    public static class ChangeResolutionAction extends AbstractAction implements LayerAction {
-        public ChangeResolutionAction() {
-            super(tr("Change resolution"));
+    @Override
+    public void zoomChanged() {
+        for (WMSLayer l : Utils.filteredCollection(LayerListDialog.getInstance().getModel().getLayers(), WMSLayer.class)) {
+            double q = l.mv.getDist100Pixel() / l.resolution;
+            if (q > 3 || q < 1. / 3) {
+                changeResolution(l);
+            }
         }
+    }
 
-        private void changeResolution(WMSLayer layer) {
-            layer.resolution = layer.mv.getDist100PixelText();
-            layer.info.setPixelPerDegree(layer.getPPD());
-            layer.settingsChanged = true;
-            for(int x = 0; x<layer.dax; ++x) {
-                for(int y = 0; y<layer.day; ++y) {
-                    layer.images[x][y].changePosition(-1, -1);
-                }
+    private static void changeResolution(WMSLayer layer) {
+        layer.resolution = layer.mv.getDist100Pixel();
+        layer.resolutionText = layer.mv.getDist100PixelText();
+        layer.info.setPixelPerDegree(layer.getPPD());
+        layer.settingsChanged = true;
+        for (int x = 0; x < layer.dax; ++x) {
+            for (int y = 0; y < layer.day; ++y) {
+                layer.images[x][y].changePosition(-1, -1);
             }
         }
+    }
+
+    public static class ChangeResolutionAction extends AbstractAction implements LayerAction {
+        public ChangeResolutionAction() {
+            super(tr("Change resolution"));
+        }
 
         @Override
         public void actionPerformed(ActionEvent ev) {
