Index: trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java	(revision 12092)
+++ trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java	(revision 12093)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.actions.mapmode.MapMode;
 import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.imagery.OffsetBookmark;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -43,5 +44,6 @@
     private static Cursor cursor = ImageProvider.getCursor("normal", "move");
 
-    private EastNorth old;
+    private OffsetBookmark old;
+    private OffsetBookmark tempOffset;
     private EastNorth prevEastNorth;
     private transient AbstractTileSourceLayer<?> layer;
@@ -66,5 +68,18 @@
             layer.setVisible(true);
         }
-        old = layer.getDisplaySettings().getDisplacement();
+        old = layer.getDisplaySettings().getOffsetBookmark();
+        EastNorth curOff = old == null ? EastNorth.ZERO : old.getDisplacement(Main.getProjection());
+        LatLon center;
+        if (Main.isDisplayingMapView()) {
+            center = Main.getProjection().eastNorth2latlon(Main.map.mapView.getCenter());
+        } else {
+            center = LatLon.ZERO;
+        }
+        tempOffset = new OffsetBookmark(
+                Main.getProjection().toCode(),
+                layer.getInfo().getName(),
+                null,
+                curOff.east(), curOff.north(), center.lon(), center.lat());
+        layer.getDisplaySettings().setOffsetBookmark(tempOffset);
         addListeners();
         showOffsetDialog(new ImageryOffsetDialog());
@@ -96,5 +111,5 @@
         if (offsetDialog != null) {
             if (layer != null) {
-                layer.getDisplaySettings().setDisplacement(old);
+                layer.getDisplaySettings().setOffsetBookmark(old);
             }
             hideOffsetDialog();
@@ -136,5 +151,7 @@
         if (dx != 0 || dy != 0) {
             double ppd = layer.getPPD();
-            layer.getDisplaySettings().addDisplacement(new EastNorth(dx / ppd, dy / ppd));
+            EastNorth d = tempOffset.getDisplacement().add(new EastNorth(dx / ppd, dy / ppd));
+            tempOffset.setDisplacement(d);
+            layer.getDisplaySettings().setOffsetBookmark(tempOffset);
             if (offsetDialog != null) {
                 offsetDialog.updateOffset();
@@ -163,6 +180,7 @@
         if (layer == null || prevEastNorth == null) return;
         EastNorth eastNorth = Main.map.mapView.getEastNorth(e.getX(), e.getY());
-        EastNorth d = layer.getDisplaySettings().getDisplacement().add(eastNorth).subtract(prevEastNorth);
-        layer.getDisplaySettings().setDisplacement(d);
+        EastNorth d = tempOffset.getDisplacement().add(eastNorth).subtract(prevEastNorth);
+        tempOffset.setDisplacement(d);
+        layer.getDisplaySettings().setOffsetBookmark(tempOffset);
         if (offsetDialog != null) {
             offsetDialog.updateOffset();
@@ -239,5 +257,6 @@
                     double dx = Double.parseDouble(easting);
                     double dy = Double.parseDouble(northing);
-                    layer.getDisplaySettings().setDisplacement(new EastNorth(dx, dy));
+                    tempOffset.setDisplacement(new EastNorth(dx, dy));
+                    layer.getDisplaySettings().setOffsetBookmark(tempOffset);
                 } catch (NumberFormatException nfe) {
                     // we repaint offset numbers in any case
@@ -305,5 +324,5 @@
             if (layer != null) {
                 if (getValue() != 1) {
-                    layer.getDisplaySettings().setDisplacement(old);
+                    layer.getDisplaySettings().setOffsetBookmark(old);
                 } else if (tBookmarkName.getText() != null && !tBookmarkName.getText().isEmpty()) {
                     OffsetBookmark.bookmarkOffset(tBookmarkName.getText(), layer);
Index: trunk/src/org/openstreetmap/josm/data/coor/EastNorth.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/EastNorth.java	(revision 12092)
+++ trunk/src/org/openstreetmap/josm/data/coor/EastNorth.java	(revision 12093)
@@ -15,4 +15,6 @@
 
     private static final long serialVersionUID = 1L;
+
+    public static final EastNorth ZERO = new EastNorth(0, 0);
 
     /**
Index: trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java	(revision 12092)
+++ trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java	(revision 12093)
@@ -12,9 +12,18 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Preferences.pref;
+import org.openstreetmap.josm.data.Preferences.writeExplicitly;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.Projections;
 import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
 import org.openstreetmap.josm.gui.layer.ImageryLayer;
 
+/**
+ * Class to save a displacement of background imagery as a bookmark.
+ *
+ * Known offset bookmarks will be stored in the preferences and can be
+ * restored by the user in later sessions.
+ */
 public class OffsetBookmark {
     private static final List<OffsetBookmark> allBookmarks = new ArrayList<>();
@@ -23,10 +32,10 @@
     @pref private String imagery_name;
     @pref private String name;
-    @pref private double dx, dy;
+    @pref @writeExplicitly private double dx, dy;
     @pref private double center_lon, center_lat;
 
     public boolean isUsable(ImageryLayer layer) {
         if (projection_code == null) return false;
-        if (!Main.getProjection().toCode().equals(projection_code)) return false;
+        if (!Main.getProjection().toCode().equals(projection_code) && !hasCenter()) return false;
         return layer.getInfo().getName().equals(imagery_name);
     }
@@ -83,12 +92,56 @@
     }
 
-    public EastNorth getOffset() {
+    /**
+     * Get displacement in EastNorth coordinates of the original projection.
+     *
+     * @see #getProjectionCode()
+     * @return the displacement
+     */
+    public EastNorth getDisplacement() {
         return new EastNorth(dx, dy);
     }
 
+    /**
+     * Get displacement in EastNorth coordinates of a given projection.
+     *
+     * Displacement will be converted to the given projection, with respect to the
+     * center (reference point) of this bookmark.
+     * @param proj the projection
+     * @return the displacement, converted to that projection
+     */
+    public EastNorth getDisplacement(Projection proj) {
+        if (proj.toCode().equals(projection_code)) {
+            return getDisplacement();
+        }
+        LatLon center = getCenter();
+        Projection offsetProj = Projections.getProjectionByCode(projection_code);
+        EastNorth centerEN = offsetProj.latlon2eastNorth(center);
+        EastNorth shiftedEN = centerEN.add(getDisplacement());
+        LatLon shifted = offsetProj.eastNorth2latlon(shiftedEN);
+        EastNorth centerEN2 = proj.latlon2eastNorth(center);
+        EastNorth shiftedEN2 = proj.latlon2eastNorth(shifted);
+        return shiftedEN2.subtract(centerEN2);
+    }
+
+    /**
+     * Get center/reference point of the bookmark.
+     *
+     * Basically this is the place where it was created and is valid.
+     * The center may be unrecorded (see {@link #hasCenter()), in which
+     * case a dummy center (0,0) will be returned.
+     * @return the center
+     */
     public LatLon getCenter() {
         return new LatLon(center_lat, center_lon);
     }
 
+    /**
+     * Check if bookmark has a valid center.
+     * @return true if bookmark has a valid center
+     */
+    public boolean hasCenter() {
+        return center_lat != 0 || center_lon != 0;
+    }
+
     public void setProjectionCode(String projectionCode) {
         this.projection_code = projectionCode;
@@ -103,7 +156,7 @@
     }
 
-    public void setOffset(EastNorth offset) {
-        this.dx = offset.east();
-        this.dy = offset.north();
+    public void setDisplacement(EastNorth displacement) {
+        this.dx = displacement.east();
+        this.dy = displacement.north();
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 12092)
+++ trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 12093)
@@ -81,4 +81,5 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
+import org.openstreetmap.josm.data.imagery.OffsetBookmark;
 import org.openstreetmap.josm.data.imagery.TMSCachedTileLoader;
 import org.openstreetmap.josm.data.imagery.TileLoaderFactory;
@@ -334,16 +335,6 @@
     @Override
     @Deprecated
-    public void displace(double dx, double dy) {
-        getDisplaySettings().addDisplacement(new EastNorth(dx, dy));
-    }
-
-    /**
-     * {@inheritDoc}
-     * @deprecated Use {@link TileSourceDisplaySettings}
-     */
-    @Override
-    @Deprecated
-    public void setOffset(double dx, double dy) {
-        getDisplaySettings().setDisplacement(new EastNorth(dx, dy));
+    public void setOffset(OffsetBookmark offset) {
+        getDisplaySettings().setOffsetBookmark(offset);
     }
 
@@ -1856,4 +1847,5 @@
     public void projectionChanged(Projection oldValue, Projection newValue) {
         super.projectionChanged(oldValue, newValue);
+        displaySettings.setOffsetBookmark(displaySettings.getOffsetBookmark());
         if (tileCache != null) {
             tileCache.clear();
Index: trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java	(revision 12092)
+++ trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java	(revision 12093)
@@ -31,4 +31,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.ProjectionBounds;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
 import org.openstreetmap.josm.data.imagery.OffsetBookmark;
@@ -108,21 +109,9 @@
      * Sets the displacement offset of this layer. The layer is automatically invalidated.
      * To be removed end of 2016
-     * @param dx The x offset
-     * @param dy The y offset
+     * @param offset the offset bookmark
      * @deprecated Use {@link TileSourceDisplaySettings}
      */
     @Deprecated
-    public void setOffset(double dx, double dy) {
-        // moved to AbstractTileSourceLayer/TileSourceDisplaySettings. Remains until all actions migrate.
-    }
-
-    /**
-     * To be removed end of 2016
-     * @param dx deprecated
-     * @param dy deprecated
-     * @deprecated Use {@link TileSourceDisplaySettings}
-     */
-    @Deprecated
-    public void displace(double dx, double dy) {
+    public void setOffset(OffsetBookmark offset) {
         // moved to AbstractTileSourceLayer/TileSourceDisplaySettings. Remains until all actions migrate.
     }
@@ -210,5 +199,5 @@
         @Override
         public void actionPerformed(ActionEvent ev) {
-            setOffset(b.getOffset().east(), b.getOffset().north());
+            setOffset(b);
             Main.main.menu.imageryMenu.refreshOffsetMenu();
             Main.map.repaint();
@@ -253,6 +242,6 @@
             }
             JCheckBoxMenuItem item = new JCheckBoxMenuItem(new ApplyOffsetAction(b));
-            if (Utils.equalsEpsilon(b.getOffset().east(), getDx()) &&
-                    Utils.equalsEpsilon(b.getOffset().north(), getDy())) {
+            EastNorth offset = b.getDisplacement(Main.getProjection());
+            if (Utils.equalsEpsilon(offset.east(), getDx()) && Utils.equalsEpsilon(offset.north(), getDy())) {
                 item.setSelected(true);
             }
Index: trunk/src/org/openstreetmap/josm/gui/layer/imagery/TileSourceDisplaySettings.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/imagery/TileSourceDisplaySettings.java	(revision 12092)
+++ trunk/src/org/openstreetmap/josm/gui/layer/imagery/TileSourceDisplaySettings.java	(revision 12093)
@@ -8,4 +8,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.imagery.OffsetBookmark;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
@@ -62,8 +63,10 @@
     private boolean showErrors;
 
-    /**
-     * The displacement
-     */
-    private EastNorth displacement = new EastNorth(0, 0);
+    private OffsetBookmark offsetBookmark = null;
+    /**
+     * the displacement (basically caches the displacement from the offsetBookmark
+     * in the current projection)
+     */
+    private EastNorth displacement = EastNorth.ZERO;
 
     private final CopyOnWriteArrayList<DisplaySettingsChangeListener> listeners = new CopyOnWriteArrayList<>();
@@ -189,22 +192,29 @@
 
     /**
-     * Set the displacement
-     * @param displacement The new displacement
-     * @since 10571
-     */
-    public void setDisplacement(EastNorth displacement) {
+     * Sets an offset bookmark to use.
+     * 
+     * @param offsetBookmark the offset bookmark, may be null
+     */
+    public void setOffsetBookmark(OffsetBookmark offsetBookmark) {
+        this.offsetBookmark = offsetBookmark;
+        if (offsetBookmark == null) {
+            setDisplacement(EastNorth.ZERO);
+        } else {
+            setDisplacement(offsetBookmark.getDisplacement(Main.getProjection()));
+        }
+    }
+
+    /**
+     * Gets the offset bookmark in use.
+     * @return the offset bookmark, may be null
+     */
+    public OffsetBookmark getOffsetBookmark() {
+        return this.offsetBookmark;
+    }
+
+    private void setDisplacement(EastNorth displacement) {
         CheckParameterUtil.ensureValidCoordinates(displacement, "displacement");
         this.displacement = displacement;
         fireSettingsChange(DISPLACEMENT);
-    }
-
-    /**
-     * Adds the given value to the displacement.
-     * @param displacement The value to add.
-     * @since 10571
-     */
-    public void addDisplacement(EastNorth displacement) {
-        CheckParameterUtil.ensureValidCoordinates(displacement, "displacement");
-        setDisplacement(this.displacement.add(displacement));
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java	(revision 12092)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java	(revision 12093)
@@ -912,7 +912,7 @@
                     return info.getName();
                 case 3:
-                    return info.getOffset().east();
+                    return info.getDisplacement().east();
                 case 4:
-                    return info.getOffset().north();
+                    return info.getDisplacement().north();
                 default:
                     throw new ArrayIndexOutOfBoundsException();
@@ -932,9 +932,9 @@
                 case 3:
                     double dx = Double.parseDouble((String) o);
-                    info.setOffset(new EastNorth(dx, info.getOffset().north()));
+                    info.setDisplacement(new EastNorth(dx, info.getDisplacement().north()));
                     break;
                 case 4:
                     double dy = Double.parseDouble((String) o);
-                    info.setOffset(new EastNorth(info.getOffset().east(), dy));
+                    info.setDisplacement(new EastNorth(info.getDisplacement().east(), dy));
                     break;
                 default:
