Index: /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/OffsetIterator.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/OffsetIterator.java	(revision 12504)
+++ /trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/OffsetIterator.java	(revision 12505)
@@ -23,5 +23,5 @@
 public class OffsetIterator implements Iterator<MapViewPoint> {
     private final MapViewState mapState;
-    private final List<Node> nodes;
+    private final List<MapViewPoint> nodes;
     private final double offset;
     private int idx;
@@ -37,4 +37,18 @@
     /**
      * Creates a new offset iterator
+     * @param nodes The nodes of the original line
+     * @param offset The offset of the line.
+     */
+    public OffsetIterator(List<MapViewPoint> nodes, double offset) {
+        if (nodes.size() < 2) {
+            throw new IllegalArgumentException("There must be at least 2 nodes.");
+        }
+        this.mapState = nodes.get(0).getMapViewState();
+        this.nodes = nodes;
+        this.offset = offset;
+    }
+
+    /**
+     * Creates a new offset iterator
      * @param mapState The map view state this iterator is for.
      * @param nodes The nodes of the original line
@@ -43,7 +57,6 @@
     public OffsetIterator(MapViewState mapState, List<Node> nodes, double offset) {
         this.mapState = mapState;
-        this.nodes = nodes.stream().filter(Node::isLatLonKnown).collect(Collectors.toList());
+        this.nodes = nodes.stream().filter(Node::isLatLonKnown).map(mapState::getPointFor).collect(Collectors.toList());
         this.offset = offset;
-        idx = 0;
     }
 
@@ -160,5 +173,5 @@
 
     private MapViewPoint getForIndex(int i) {
-        return mapState.getPointFor(nodes.get(i));
+        return nodes.get(i);
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/MapViewState.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 12504)
+++ /trunk/src/org/openstreetmap/josm/gui/MapViewState.java	(revision 12505)
@@ -419,4 +419,12 @@
      */
     public abstract class MapViewPoint {
+        /**
+         * Gets the map view state this path is used for.
+         * @return The state.
+         * @since 12505
+         */
+        public MapViewState getMapViewState() {
+            return MapViewState.this;
+        }
 
         /**
Index: /trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java	(revision 12504)
+++ /trunk/src/org/openstreetmap/josm/gui/draw/MapViewPath.java	(revision 12505)
@@ -7,7 +7,9 @@
 import java.awt.geom.Path2D;
 import java.awt.geom.PathIterator;
+import java.util.ArrayList;
 
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.ILatLon;
+import org.openstreetmap.josm.data.osm.visitor.paint.OffsetIterator;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.MapViewState;
@@ -280,4 +282,16 @@
     public double getLength() {
         return visitLine((inLineOffset, start, end, startIsOldEnd) -> { });
+    }
+
+    /**
+     * Create a new {@link MapViewPath} that is the same as the current one except that it is offset in the view.
+     * @param viewOffset The offset in view pixels
+     * @return The new path
+     * @since 12505
+     */
+    public MapViewPath offset(double viewOffset) {
+        OffsetPathVisitor visitor = new OffsetPathVisitor(state, viewOffset);
+        visitor.visit(this);
+        return visitor.getPath();
     }
 
@@ -447,3 +461,40 @@
     }
 
+    private class OffsetPathVisitor extends AbstractMapPathVisitor {
+        private final MapViewPath collector;
+        private final ArrayList<MapViewPoint> points = new ArrayList<>();
+        private final double offset;
+
+        OffsetPathVisitor(MapViewState state, double offset) {
+            this.collector = new MapViewPath(state);
+            this.offset = offset;
+        }
+
+        @Override
+        void visitMoveTo(MapViewPoint p) {
+            finishLineSegment();
+            points.add(p);
+        }
+
+        @Override
+        void visitLineTo(MapViewPoint p) {
+            points.add(p);
+        }
+
+        MapViewPath getPath() {
+            finishLineSegment();
+            return collector;
+        }
+
+        private void finishLineSegment() {
+            if (points.size() > 2) {
+                OffsetIterator iterator = new OffsetIterator(points, offset);
+                collector.moveTo(iterator.next());
+                while (iterator.hasNext()) {
+                    collector.lineTo(iterator.next());
+                }
+                points.clear();
+            }
+        }
+    }
 }
