Index: /applications/editors/josm/plugins/livegps/src/livegps/CirclePanel.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/CirclePanel.java	(revision 36330)
+++ /applications/editors/josm/plugins/livegps/src/livegps/CirclePanel.java	(revision 36330)
@@ -0,0 +1,92 @@
+// License: Public Domain. For details, see LICENSE file.
+package livegps;
+
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+
+import java.awt.Graphics; 
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.BasicStroke;
+import java.awt.Color;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Area;
+
+import org.openstreetmap.josm.spi.preferences.Config;
+
+/**
+ * Draw a target visualization
+ */
+public class CirclePanel extends JPanel {
+
+    JLabel label = new JLabel();
+    double x = 0;
+
+    public CirclePanel(double x) {
+        add(label);
+        this.x = x;
+    }
+
+    public void setOffset(double offs) {
+        this.x = offs;
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        boolean isVisible = Config.getPref().getBoolean(LiveGPSPreferences.C_DISTANCE_VISUALISATION, false);
+
+        super.paintComponent(g);
+        if (isVisible == true) {
+            Graphics2D g2 = (Graphics2D) g;
+
+            int w = getWidth();
+            int h = getHeight();
+
+            double width = 0;
+            if (w > h) {
+                width = h*0.9;
+            } else {
+                width = w*0.9;
+            }
+
+            double y_start = (h/2.0) - (width/2); // center circle vertical
+            double x_start = (w - width) / 2; // center circle horizontal
+
+            // 3 rectangles
+            Shape rect1 = new Rectangle2D.Double(x_start, y_start, width*0.4, width);
+            Shape rect2 = new Rectangle2D.Double(x_start+width*0.4, y_start, width*0.2, width);
+            Shape rect3 = new Rectangle2D.Double(x_start+width*0.6, y_start, width*0.4, width);
+
+            // 1 circle
+            Shape circle = new Ellipse2D.Double(x_start, y_start, width, width);
+
+            // intersection
+            Area rect1Area = new Area(rect1);
+            Area rect2Area = new Area(rect2);
+            Area rect3Area = new Area(rect3);
+
+            Area circleArea1 = new Area(circle);
+            Area circleArea2 = new Area(circle);
+            Area circleArea3 = new Area(circle);
+
+            circleArea1.intersect(rect1Area);
+            circleArea2.intersect(rect2Area);
+            circleArea3.intersect(rect3Area);
+
+            g2.setStroke(new BasicStroke(2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
+
+            DrawPoint drawpoint = new DrawPoint();
+            drawpoint.draw_point(x, g2, circleArea1, circleArea2, circleArea3, label, x_start, y_start, width);
+
+            g2.draw(circleArea1);
+            g2.draw(circleArea2);
+            g2.draw(circleArea3);
+
+            // red center line
+            g2.setColor(Color.red);
+            g2.drawLine((int) (x_start+(width/2)), (int) y_start, (int) (x_start+(width/2)), (int) (y_start+width));
+        }
+    }
+}
Index: /applications/editors/josm/plugins/livegps/src/livegps/DrawPoint.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/DrawPoint.java	(revision 36330)
+++ /applications/editors/josm/plugins/livegps/src/livegps/DrawPoint.java	(revision 36330)
@@ -0,0 +1,86 @@
+// License: Public Domain. For details, see LICENSE file.
+package livegps;
+
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+
+import java.awt.Graphics2D;
+import java.awt.Color;
+import java.awt.geom.Area;
+
+import org.openstreetmap.josm.spi.preferences.Config;
+
+class DrawPoint extends JPanel {
+    public double threshold = Config.getPref().getDouble(LiveGPSPreferences.C_OFFSET_THRESHOLD, LiveGPSPreferences.DEFAULT_THRESHOLD);
+    int x_p = 0;
+    int w = getWidth();
+    int h = getHeight();
+
+    public void draw_point(double x, Graphics2D g2, Area circleArea1, Area circleArea2,
+        Area circleArea3, JLabel label, double x_start, double y_start, double width) {
+
+        // x-value of black point
+        if (x < -threshold) {
+            x_p = (int) (x_start + (width*0.4) + (x*(width/100)) - ((width*0.15)/2));
+            if (x_p < x_start) {
+                x_p = (int) x_start;
+            }
+        } else if (x > threshold) {
+            x_p = (int) (x_start + (x*(width/100)) + (width*0.6) - ((width*0.15)/2));
+            if (x_p > x_start + width) {
+                x_p = (int) (x_start + width);
+            }
+        } else if (x >= -threshold && x <= threshold) {
+            x_p = (int) (x_start + (width/2) - ((width*0.15)/2));
+        }
+
+        // fill area
+        fill(x, x_p, g2, circleArea1, circleArea2, circleArea3, label, x_start, y_start, width);
+
+        // black position point
+        g2.setColor(Color.black);
+        g2.fillOval(x_p, (int) (y_start+(width/2)-((width*0.15)/2)), (int) (width*0.15), (int) (width*0.15));
+    }
+
+    public void fill(double x, int x_p, Graphics2D g2, Area circleArea1, Area circleArea2, Area circleArea3,
+        JLabel label, double x_start, double y_start, double width) {
+
+        Color yellow;
+        Color green;
+        yellow = new Color(255, 210, 50, 255);
+        green = new Color(30, 200, 50, 255);
+
+        // Distance from point to center line, rounded to 2 decimals
+        double y = Math.round(x * 100.0) / 100.0;
+
+        if (x < 0 && -x > threshold) {
+            // left yellow + text
+            g2.setColor(yellow);
+            g2.fill(circleArea1);
+
+            if (width/3 < 60) { // if label larger than half circle, place label outside the circle
+                label.setBounds((int) (x_start - 60), (int) (y_start + width*0.3), 60, 10);
+            } else {
+                label.setBounds((int) (x_start + width*0.1), (int) (y_start + width*0.3), (int) (width/3), (int) (width/15));
+            }
+            label.setText(y+" m");
+
+        } else if ((-x <= threshold && x <= 0) || (x <= threshold && x >= 0)) {
+            // center green
+            g2.setColor(green);
+            g2.fill(circleArea2);
+            label.setText("");
+        } else if (x > 0 && x > threshold) {
+            // right yellow + text
+            g2.setColor(yellow);
+            g2.fill(circleArea3);
+
+            if (width/3 < 60) {
+                label.setBounds((int) (x_start + width*1.1), (int) (y_start + width*0.3), 60, 10);
+            } else {
+                label.setBounds((int) (x_start + width*0.7), (int) (y_start + width*0.3), (int) (width/3), (int) (width/15));
+            }
+            label.setText("+"+y+" m");
+        }
+    }
+}
Index: /applications/editors/josm/plugins/livegps/src/livegps/LiveGPSPreferences.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGPSPreferences.java	(revision 36329)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGPSPreferences.java	(revision 36330)
@@ -6,4 +6,7 @@
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+
+//import java.beans.PropertyChangeEvent;
+//import java.beans.PropertyChangeListener;
 
 import javax.swing.Box;
@@ -34,4 +37,8 @@
     /* option to use specify gpsd disabling */
     public static final String C_DISABLED = "livegps.gpsd.disabled";
+    /* option to use distance visualisation and set threshold */
+    public static final String C_DISTANCE_VISUALISATION = "livegps.distance_visualisation";
+    public static final String C_OFFSET_THRESHOLD = "livegps.offset_threshold";
+    public static final double DEFAULT_THRESHOLD = 0.3;
 
     public static final String C_LIVEGPS_COLOR_POSITION = "color.livegps.position";
@@ -61,4 +68,7 @@
     private final JCheckBox disableGPSD = new JCheckBox(tr("Disable GPSD"));
     private final JCheckBox showOffset = new JCheckBox(tr("Show Distance to nearest way"));
+    private final JCheckBox showDistanceVisualisation = new JCheckBox(tr("Show distance visualisation"));
+    private final JTextField threshold = new JTextField(5);
+    private JLabel thresholdLabel;
 
     public LiveGPSPreferences() {
@@ -96,6 +106,27 @@
         panel.add(showOffset, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 0, 0, 5));
 
+        showDistanceVisualisation.setSelected(Config.getPref().getBoolean(C_DISTANCE_VISUALISATION, false));
+        panel.add(showDistanceVisualisation, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(0, 0, 0, 5));
+
+        threshold.setText(String.valueOf(Config.getPref().getDouble(C_OFFSET_THRESHOLD, DEFAULT_THRESHOLD)));
+        threshold.setToolTipText(tr("Threshold, default is {0}", DEFAULT_THRESHOLD));
+        thresholdLabel = new JLabel(tr("Threshold"));
+        panel.add(thresholdLabel, GBC.std());
+        panel.add(threshold, GBC.eol().fill(GridBagConstraints.HORIZONTAL).insets(5, 0, 0, 5));
+        threshold.setVisible(false);
+        thresholdLabel.setVisible(false);
+
+        updateThreshold(); // beim Start
+        showDistanceVisualisation.addActionListener(e -> updateThreshold()); // wenn sich was ändert
+
         panel.add(Box.createVerticalGlue(), GBC.eol().fill(GridBagConstraints.VERTICAL));
         createPreferenceTabWithScrollPane(gui, panel);
+    }
+
+    private void updateThreshold() {
+        boolean isVisible = showDistanceVisualisation.isSelected();
+
+        threshold.setVisible(isVisible);
+        thresholdLabel.setVisible(isVisible);
     }
 
@@ -107,4 +138,11 @@
         Config.getPref().putBoolean(C_DISABLED, disableGPSD.isSelected());
         Config.getPref().putBoolean(C_WAYOFFSET, showOffset.isSelected());
+        boolean oldVal = Config.getPref().getBoolean(C_DISTANCE_VISUALISATION, false);
+        boolean newVal = showDistanceVisualisation.isSelected();
+        Config.getPref().putBoolean(C_DISTANCE_VISUALISATION, newVal);
+        Config.getPref().put(C_OFFSET_THRESHOLD, threshold.getText());
+        if (oldVal != newVal) {
+            LiveGpsDialog.updateCirclePanelVisibility();
+        }
         return false;
     }
Index: /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java	(revision 36329)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsData.java	(revision 36330)
@@ -32,4 +32,5 @@
     private WayPoint waypoint;
     private static final DecimalFormat offsetFormat = new DecimalFormat("0.00");
+    private double offs = 0;
 
     public LiveGpsData(double latitude, double longitude, float course, float speed) {
@@ -165,4 +166,12 @@
         return getClass().getSimpleName() + "[fix=" + fix + ", lat=" + latLon.lat()
         + ", long=" + latLon.lon() + ", speed=" + speed + ", course=" + course + ']';
+    }
+
+    public void setOffset(double offs) {
+        this.offs = offs;
+    }
+
+    public double getOffset() {
+        return this.offs;
     }
 
@@ -194,8 +203,8 @@
                 }
                 if (Config.getPref().getBoolean(LiveGPSPreferences.C_WAYOFFSET, false)) {
-                    double offs = Geometry.getDistanceWayNode(way, n);
+                    offs = Geometry.getDistanceWayNode(way, n);
                     WaySegment ws = Geometry.getClosestWaySegment(way, n);
                     if (!Geometry.angleIsClockwise(ws.getFirstNode(), ws.getSecondNode(), n))
-                        offs = -offs;
+                        setOffset(-offs);
                     /* I18N: side offset and way name for livegps way display with offset */
                     wayString = tr("{0} ({1})", offsetFormat.format(offs), wayString);
Index: /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java	(revision 36329)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsDialog.java	(revision 36330)
@@ -5,6 +5,10 @@
 
 import java.awt.Color;
-import java.awt.GridLayout;
+import java.awt.BorderLayout;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+
 import java.awt.event.KeyEvent;
+
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
@@ -13,4 +17,5 @@
 import javax.swing.JPanel;
 import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
 
 import org.openstreetmap.josm.data.coor.conversion.CoordinateFormatManager;
@@ -43,7 +48,12 @@
     private JLabel wayText;
     private JPanel panel;
+    private JPanel opanel;
+    private Color backgroundColor;
     private LiveGpsStatus status = new LiveGpsStatus(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
     private LiveGpsStatus nmeaStatus = new LiveGpsStatus(LiveGpsStatus.GpsStatus.CONNECTING, tr("Connecting"));
     private LiveGpsData data;
+    private CirclePanel circlePanel;
+
+    private static volatile LiveGpsDialog dialog;
 
     public LiveGpsDialog(final MapFrame mapFrame) {
@@ -51,20 +61,57 @@
         Shortcut.registerShortcut("subwindow:livegps", tr("Toggle: {0}", tr("Live GPS")),
         KeyEvent.VK_G, Shortcut.ALT_CTRL_SHIFT), 100);
+
+        dialog = this;
+
+        backgroundColor = UIManager.getColor("Panel.background");
+
+        opanel = new JPanel();
+        opanel.setLayout(new BorderLayout());
+
         panel = new JPanel();
-        panel.setLayout(new GridLayout(7, 2));
-        panel.add(statusText = new JLabel(tr("Status gpsd")));
-        panel.add(statusLabel = new JLabel());
-        panel.add(nmeaStatusText = new JLabel(tr("Status NMEA")));
-        panel.add(nmeaStatusLabel = new JLabel());
-        panel.add(wayText = new JLabel(tr("Way Info")));
-        panel.add(wayLabel = new JLabel());
-        panel.add(latText = new JLabel(tr("Latitude")));
-        panel.add(latLabel = new JLabel());
-        panel.add(longText = new JLabel(tr("Longitude")));
-        panel.add(longLabel = new JLabel());
-        panel.add(new JLabel(tr("Speed")));
-        panel.add(speedLabel = new JLabel());
-        panel.add(new JLabel(tr("Course")));
-        panel.add(courseLabel = new JLabel());
+
+        GridBagLayout layout = new GridBagLayout();
+        panel.setLayout(layout);
+        GridBagConstraints gbc = new GridBagConstraints();
+
+        // first column
+        gbc.weightx = 0.3;
+        gbc.gridx = 0;
+        gbc.anchor = GridBagConstraints.WEST;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+
+        panel.add(statusText = new JLabel("Status gpsd "), gbc);
+        panel.add(nmeaStatusText = new JLabel("Status NMEA "), gbc);
+        panel.add(wayText = new JLabel("Way Info"), gbc);
+        panel.add(latText = new JLabel("Latitude"), gbc);
+        panel.add(longText = new JLabel("Longitude"), gbc);
+        panel.add(new JLabel(tr("Speed")), gbc);
+        panel.add(new JLabel(tr("Course")), gbc);
+
+        // second column
+        gbc.weightx = 0.7;
+        gbc.gridx = 1;
+        gbc.fill = GridBagConstraints.HORIZONTAL;
+
+        panel.add(statusLabel = new JLabel(), gbc);
+        panel.add(nmeaStatusLabel = new JLabel(), gbc);
+        panel.add(wayLabel = new JLabel(), gbc);
+        panel.add(latLabel = new JLabel(), gbc);
+        panel.add(longLabel = new JLabel(), gbc);
+        panel.add(speedLabel = new JLabel(), gbc);
+        panel.add(courseLabel = new JLabel(), gbc);
+
+        opanel.add(panel, BorderLayout.NORTH);
+
+        addPropertyChangeListener(new PropertyChangeListener() {
+            @Override
+            public void propertyChange(PropertyChangeEvent evt) {
+                updateCirclePanelVisibility();
+            }
+        });
+
+        circlePanel = new CirclePanel(0);
+        opanel.add(circlePanel, BorderLayout.CENTER);
+
         setStatusVisibility(true);
         if (Config.getPref().getBoolean(LiveGPSPreferences.C_WAYOFFSET, false)) {
@@ -74,5 +121,16 @@
             wayText.setText(tr("Way Info"));
         }
-        createLayout(panel, true, null);
+        createLayout(opanel, true, null);
+    }
+
+    public static void updateCirclePanelVisibility() {
+        if (dialog != null) {
+            boolean vis = Config.getPref().getBoolean(LiveGPSPreferences.C_DISTANCE_VISUALISATION, false);
+
+            dialog.circlePanel.setVisible(vis);
+
+            dialog.circlePanel.revalidate();
+            dialog.circlePanel.repaint();
+        }
     }
 
@@ -108,5 +166,5 @@
             public void run() {
                 if (data.isFix()) {
-                    panel.setBackground(Color.WHITE);
+                    panel.setBackground(backgroundColor);
                     ICoordinateFormat mCord = CoordinateFormatManager.getDefaultFormat();
                     if (ProjectedCoordinateFormat.INSTANCE.equals(mCord)) {
@@ -126,5 +184,11 @@
                     String wayString = data.getWayInfo();
                     if (!wayString.isEmpty()) {
-                        wayLabel.setText(wayString);
+                        wayLabel.setText(tr("<html><body width={0}>{1}</html>", (int) getWidth()*0.8, wayString));
+
+                        circlePanel.setOffset(data.getOffset());
+                        circlePanel.setBackground(backgroundColor);
+                        circlePanel.validate();
+                        circlePanel.repaint();
+
                     } else {
                         wayLabel.setText(tr("unknown"));
@@ -136,4 +200,5 @@
                         wayText.setText(tr("Way Info"));
                     }
+
                 } else {
                     latLabel.setText("");
@@ -143,5 +208,7 @@
                     panel.setBackground(Color.RED);
                 }
-            } });
+            }
+
+            });
         } else if ("gpsstatus".equals(evt.getPropertyName())) {
             LiveGpsStatus oldStatus = status;
@@ -162,5 +229,5 @@
                     panel.setBackground(Color.RED);
                 } else {
-                    panel.setBackground(Color.WHITE);
+                    panel.setBackground(backgroundColor);
                 }
             } });
Index: /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java	(revision 36329)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsPlugin.java	(revision 36330)
@@ -48,4 +48,7 @@
     private LiveGpsLayer lgpslayer = null;
 
+    /**
+     * Main action to start data capture
+     */
     public class CaptureAction extends JosmAction {
         public CaptureAction() {
@@ -65,4 +68,7 @@
     }
 
+    /**
+     * Center view to newest data
+     */
     public class CenterAction extends JosmAction {
         public CenterAction() {
@@ -82,4 +88,7 @@
     }
 
+    /**
+     * Automatically center view to newest data
+     */
     public class AutoCenterAction extends JosmAction {
         public AutoCenterAction() {
Index: /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java
===================================================================
--- /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java	(revision 36329)
+++ /applications/editors/josm/plugins/livegps/src/livegps/LiveGpsStatus.java	(revision 36330)
@@ -7,4 +7,7 @@
  */
 public class LiveGpsStatus {
+    /**
+     * Possible status of LiveGPS data input
+     */
     public enum GpsStatus {
         CONNECTING, CONNECTED, DISCONNECTED, CONNECTION_FAILED
