Index: trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java	(revision 13241)
+++ trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java	(revision 13243)
@@ -33,5 +33,4 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
-import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings;
 import org.openstreetmap.josm.gui.util.WindowGeometry;
 import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
@@ -86,5 +85,5 @@
                 layer.getInfo().getName(),
                 null,
-                curOff.east(), curOff.north(), center.lon(), center.lat());
+                curOff, center);
         layer.getDisplaySettings().setOffsetBookmark(tempOffset);
         addListeners();
@@ -293,8 +292,8 @@
                 // US locale to force decimal separator to be '.'
                 try (Formatter us = new Formatter(Locale.US)) {
-                    TileSourceDisplaySettings ds = layer.getDisplaySettings();
+                    EastNorth displacement = layer.getDisplaySettings().getDisplacement();
                     tOffset.setText(us.format(new StringBuilder()
                         .append("%1.").append(precision).append("f; %1.").append(precision).append('f').toString(),
-                        ds.getDx(), ds.getDy()).toString());
+                        displacement.east(), displacement.north()).toString());
                 }
             }
Index: trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java	(revision 13241)
+++ trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java	(revision 13243)
@@ -16,4 +16,5 @@
 import org.openstreetmap.josm.data.StructUtils.WriteExplicitly;
 import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.ILatLon;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.projection.Projection;
@@ -40,4 +41,9 @@
     @StructEntry private double center_lon, center_lat;
 
+    /**
+     * Test if an image is usable for the given imagery layer.
+     * @param layer The layer to use the image at
+     * @return <code>true</code> if it is usable on the projection of the layer and the imagery name matches.
+     */
     public boolean isUsable(ImageryLayer layer) {
         if (projection_code == null) return false;
@@ -55,8 +61,43 @@
     }
 
+    /**
+     * Create a new {@link OffsetBookmark} object using (0, 0) as center
+     * <p>
+     * The use of the {@link #OffsetBookmark(String, String, String, EastNorth, ILatLon)} constructor is preferred.
+     * @param projectionCode The projection for which this object was created
+     * @param imageryName The name of the imagery on the layer
+     * @param name The name of the new bookmark
+     * @param dx The x displacement
+     * @param dy The y displacement
+     */
     public OffsetBookmark(String projectionCode, String imageryName, String name, double dx, double dy) {
         this(projectionCode, imageryName, name, dx, dy, 0, 0);
     }
 
+    /**
+     * Create a new {@link OffsetBookmark} object
+     * @param projectionCode The projection for which this object was created
+     * @param imageryName The name of the imagery on the layer
+     * @param name The name of the new bookmark
+     * @param displacement The displacement in east/north space.
+     * @param center The point on earth that was used as reference to align the image.
+     * @since 13243
+     */
+    public OffsetBookmark(String projectionCode, String imageryName, String name, EastNorth displacement, ILatLon center) {
+        this(projectionCode, imageryName, name, displacement.east(), displacement.north(), center.lon(), center.lat());
+    }
+
+    /**
+     * Create a new {@link OffsetBookmark} by specifying all values.
+     * <p>
+     * The use of the {@link #OffsetBookmark(String, String, String, EastNorth, ILatLon)} constructor is preferred.
+     * @param projectionCode The projection for which this object was created
+     * @param imageryName The name of the imagery on the layer
+     * @param name The name of the new bookmark
+     * @param dx The x displacement
+     * @param dy The y displacement
+     * @param centerLon The point on earth that was used as reference to align the image.
+     * @param centerLat The point on earth that was used as reference to align the image.
+     */
     public OffsetBookmark(String projectionCode, String imageryName, String name, double dx, double dy, double centerLon, double centerLat) {
         this.projection_code = projectionCode;
@@ -69,4 +110,8 @@
     }
 
+    /**
+     * Loads an old bookmark. For backward compatibility with settings. Do not use.
+     * @param list The settings that were read
+     */
     public OffsetBookmark(Collection<String> list) {
         List<String> array = new ArrayList<>(list);
@@ -85,12 +130,24 @@
     }
 
+    /**
+     * Get the projection code for which this bookmark was created.
+     * @return The projection.
+     */
     public String getProjectionCode() {
         return projection_code;
     }
 
+    /**
+     * Get the name of this bookmark. This name can e.g. be displayed in menus.
+     * @return The name
+     */
     public String getName() {
         return name;
     }
 
+    /**
+     * Get the name of the imagery for which this bookmark was created. It is used to match the bookmark to the right layers.
+     * @return The name
+     */
     public String getImageryName() {
         return imagery_name;
@@ -149,16 +206,34 @@
     }
 
+    /**
+     * Set the projection code for which this bookmark was created
+     * @param projectionCode The projection
+     */
     public void setProjectionCode(String projectionCode) {
         this.projection_code = projectionCode;
     }
 
+    /**
+     * Set the name of the bookmark
+     * @param name The name
+     * @see #getName()
+     */
     public void setName(String name) {
         this.name = name;
     }
 
+    /**
+     * Sets the name of the imagery
+     * @param imageryName The name
+     * @see #getImageryName()
+     */
     public void setImageryName(String imageryName) {
         this.imagery_name = imageryName;
     }
 
+    /**
+     * Update the displacement of this imagery.
+     * @param displacement The displacement
+     */
     public void setDisplacement(EastNorth displacement) {
         this.dx = displacement.east();
@@ -166,4 +241,7 @@
     }
 
+    /**
+     * Load the global list of bookmarks from preferences.
+     */
     public static void loadBookmarks() {
         List<OffsetBookmark> bookmarks = StructUtils.getListOfStructs(
@@ -184,4 +262,7 @@
     }
 
+    /**
+     * Stores the bookmakrs in the settings.
+     */
     public static void saveBookmarks() {
         StructUtils.putListOfStructs(Config.getPref(), "imagery.offsetbookmarks", allBookmarks, OffsetBookmark.class);
@@ -238,4 +319,10 @@
     }
 
+    /**
+     * Gets a bookmark that is usable on the given layer by it's name.
+     * @param layer The layer to use the bookmark at
+     * @param name The name of the bookmark
+     * @return The bookmark if found, <code>null</code> if not.
+     */
     public static OffsetBookmark getBookmarkByName(ImageryLayer layer, String name) {
         for (OffsetBookmark b : allBookmarks) {
@@ -246,5 +333,10 @@
     }
 
-    public static void bookmarkOffset(String name, AbstractTileSourceLayer layer) {
+    /**
+     * Add a bookmark for the displacement of that layer
+     * @param name The bookmark name
+     * @param layer The layer to store the bookmark for
+     */
+    public static void bookmarkOffset(String name, AbstractTileSourceLayer<?> layer) {
         LatLon center;
         if (MainApplication.isDisplayingMapView()) {
@@ -255,5 +347,5 @@
         OffsetBookmark nb = new OffsetBookmark(
                 Main.getProjection().toCode(), layer.getInfo().getName(),
-                name, layer.getDisplaySettings().getDx(), layer.getDisplaySettings().getDy(), center.lon(), center.lat());
+                name, layer.getDisplaySettings().getDisplacement(), center);
         for (ListIterator<OffsetBookmark> it = allBookmarks.listIterator(); it.hasNext();) {
             OffsetBookmark b = it.next();
Index: trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 13241)
+++ trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 13243)
@@ -660,5 +660,6 @@
             break;
         default:
-            // trigger a redraw just to be sure.
+            // e.g. displacement
+            // trigger a redraw in every case
             invalidate();
         }
@@ -1922,3 +1923,42 @@
         }
     }
+
+    @Override
+    protected List<OffsetMenuEntry> getOffsetMenuEntries() {
+        return OffsetBookmark.getBookmarks()
+            .stream()
+            .filter(b -> b.isUsable(this))
+            .map(OffsetMenuBookmarkEntry::new)
+            .collect(Collectors.toList());
+    }
+
+    /**
+     * An entry for a bookmark in the offset menu.
+     * @author Michael Zangl
+     */
+    private class OffsetMenuBookmarkEntry implements OffsetMenuEntry {
+        private final OffsetBookmark bookmark;
+
+        OffsetMenuBookmarkEntry(OffsetBookmark bookmark) {
+            this.bookmark = bookmark;
+
+        }
+
+        @Override
+        public String getLabel() {
+            return bookmark.getName();
+        }
+
+        @Override
+        public boolean isActive() {
+            EastNorth offset = bookmark.getDisplacement(Main.getProjection());
+            EastNorth active = getDisplaySettings().getDisplacement();
+            return Utils.equalsEpsilon(offset.east(), active.east()) && Utils.equalsEpsilon(offset.north(), active.north());
+        }
+
+        @Override
+        public void actionPerformed() {
+            getDisplaySettings().setOffsetBookmark(bookmark);
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java	(revision 13241)
+++ trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java	(revision 13243)
@@ -31,5 +31,4 @@
 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;
@@ -45,5 +44,4 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
-import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -54,4 +52,7 @@
 public abstract class ImageryLayer extends Layer {
 
+    /**
+     * The default value for the sharpen filter for each imagery layer.
+     */
     public static final IntegerProperty PROP_SHARPEN_LEVEL = new IntegerProperty("imagery.sharpen_level", 0);
 
@@ -187,4 +188,9 @@
     }
 
+    /**
+     * Create a new imagery layer
+     * @param info The imagery info to use as base
+     * @return The created layer
+     */
     public static ImageryLayer create(ImageryInfo info) {
         switch(info.getImageryType()) {
@@ -203,16 +209,16 @@
 
     class ApplyOffsetAction extends AbstractAction {
-        private final transient OffsetBookmark b;
-
-        ApplyOffsetAction(OffsetBookmark b) {
-            super(b.getName());
-            this.b = b;
+        private final transient OffsetMenuEntry menuEntry;
+
+        ApplyOffsetAction(OffsetMenuEntry menuEntry) {
+            super(menuEntry.getLabel());
+            this.menuEntry = menuEntry;
         }
 
         @Override
         public void actionPerformed(ActionEvent ev) {
-            setOffset(b);
+            menuEntry.actionPerformed();
+            //TODO: Use some form of listeners for this.
             MainApplication.getMenu().imageryMenu.refreshOffsetMenu();
-            MainApplication.getMap().repaint();
         }
     }
@@ -235,4 +241,9 @@
     }
 
+    /**
+     * Create the menu item that should be added to the offset menu.
+     * It may have a sub menu of e.g. bookmarks added to it.
+     * @return The menu item to add to the imagery menu.
+     */
     public JMenuItem getOffsetMenuItem() {
         JMenu subMenu = new JMenu(trc("layer", "Offset"));
@@ -241,25 +252,28 @@
     }
 
+    /**
+     * Create the submenu or the menu item to set the offset of the layer.
+     *
+     * If only one menu item for this layer exists, it is returned by this method.
+     *
+     * If there are multiple, this method appends them to the subMenu and then returns the reference to the subMenu.
+     * @param subMenu The subMenu to use
+     * @return A single menu item to adjust the layer or the passed subMenu to which the menu items were appended.
+     */
     public JComponent getOffsetMenuItem(JComponent subMenu) {
         JMenuItem adjustMenuItem = new JMenuItem(getAdjustAction());
-        List<OffsetBookmark> allBookmarks = OffsetBookmark.getBookmarks();
-        if (allBookmarks.isEmpty()) return adjustMenuItem;
+        List<OffsetMenuEntry> usableBookmarks = getOffsetMenuEntries();
+        if (usableBookmarks.isEmpty()) {
+            return adjustMenuItem;
+        }
 
         subMenu.add(adjustMenuItem);
         subMenu.add(new JSeparator());
-        boolean hasBookmarks = false;
         int menuItemHeight = 0;
-        for (OffsetBookmark b : allBookmarks) {
-            if (!b.isUsable(this)) {
-                continue;
-            }
+        for (OffsetMenuEntry b : usableBookmarks) {
             JCheckBoxMenuItem item = new JCheckBoxMenuItem(new ApplyOffsetAction(b));
-            EastNorth offset = b.getDisplacement(Main.getProjection());
-            if (Utils.equalsEpsilon(offset.east(), getDx()) && Utils.equalsEpsilon(offset.north(), getDy())) {
-                item.setSelected(true);
-            }
+            item.setSelected(b.isActive());
             subMenu.add(item);
             menuItemHeight = item.getPreferredSize().height;
-            hasBookmarks = true;
         }
         if (menuItemHeight > 0) {
@@ -270,8 +284,10 @@
             }
         }
-        return hasBookmarks ? subMenu : adjustMenuItem;
+        return subMenu;
     }
 
     protected abstract Action getAdjustAction();
+
+    protected abstract List<OffsetMenuEntry> getOffsetMenuEntries();
 
     /**
@@ -340,4 +356,29 @@
     }
 
+    /**
+     * An additional menu entry in the imagery offset menu.
+     * @author Michael Zangl
+     * @since 13243
+     * @see ImageryLayer#getOffsetMenuEntries()
+     */
+    public static interface OffsetMenuEntry {
+        /**
+         * Get the label to use for this menu item
+         * @return The label to display in the menu.
+         */
+        String getLabel();
+
+        /**
+         * Test whether this bookmark is currently active
+         * @return <code>true</code> if it is active
+         */
+        boolean isActive();
+
+        /**
+         * Load this bookmark
+         */
+        void actionPerformed();
+    }
+
     @Override
     public String toString() {
Index: trunk/src/org/openstreetmap/josm/gui/layer/imagery/TileSourceDisplaySettings.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/imagery/TileSourceDisplaySettings.java	(revision 13241)
+++ trunk/src/org/openstreetmap/josm/gui/layer/imagery/TileSourceDisplaySettings.java	(revision 13243)
@@ -171,7 +171,8 @@
      * @return The displacement.
      * @since 10571
+     * @see #getDisplacement()
      */
     public double getDx() {
-        return displacement.east();
+        return getDisplacement().east();
     }
 
@@ -180,7 +181,8 @@
      * @return The displacement.
      * @since 10571
+     * @see #getDisplacement()
      */
     public double getDy() {
-        return displacement.north();
+        return getDisplacement().north();
     }
 
@@ -195,5 +197,5 @@
 
     /**
-     * Sets an offset bookmark to use.
+     * Sets an offset bookmark to use. Loads the displacement from the bookmark.
      *
      * @param offsetBookmark the offset bookmark, may be null
