Index: trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 4206)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 4207)
@@ -78,4 +78,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.UrlLabel;
+import org.openstreetmap.josm.tools.Utils;
 
 public class GpxLayer extends Layer {
@@ -304,5 +305,5 @@
     }
 
-    private static Color[] colors = new Color[256];
+    private final static Color[] colors = new Color[256];
     static {
         for (int i = 0; i < colors.length; i++) {
@@ -311,9 +312,44 @@
     }
 
+    private final static Color[] colors_cyclic = new Color[256];
+    static {
+        for (int i = 0; i < colors_cyclic.length; i++) {
+            //                    red   yellow  green   blue    red
+            int[] h = new int[] { 0,    59,     127,    244,    360};
+            int[] s = new int[] { 100,  84,     99,     100 };
+            int[] b = new int[] { 90,   93,     74,     83 };
+
+            float angle = 4 - i / 256f * 4;
+            int quadrant = (int) angle;
+            angle -= quadrant;
+            quadrant = Utils.mod(quadrant+1, 4);
+
+            float vh = h[quadrant] * w(angle) + h[quadrant+1] * (1 - w(angle));
+            float vs = s[quadrant] * w(angle) + s[Utils.mod(quadrant+1, 4)] * (1 - w(angle));
+            float vb = b[quadrant] * w(angle) + b[Utils.mod(quadrant+1, 4)] * (1 - w(angle));
+
+            colors_cyclic[i] = Color.getHSBColor(vh/360f, vs/100f, vb/100f);
+        }
+    }
+
+    /**
+     * transition function: 
+     *  w(0)=1, w(1)=0, 0<=w(x)<=1
+     * @param x number: 0<=x<=1
+     * @return the weighted value
+     */
+    private static float w(float x) {
+        if (x < 0.5) {
+            return 1 - 2*x*x;
+        } else {
+        return 2*(1-x)*(1-x);
+        }
+    }
+    
     // lookup array to draw arrows without doing any math
-    private static int ll0 = 9;
-    private static int sl4 = 5;
-    private static int sl9 = 3;
-    private static int[][] dir = { { +sl4, +ll0, +ll0, +sl4 }, { -sl9, +ll0, +sl9, +ll0 }, { -ll0, +sl4, -sl4, +ll0 },
+    private final static int ll0 = 9;
+    private final static int sl4 = 5;
+    private final static int sl9 = 3;
+    private final static int[][] dir = { { +sl4, +ll0, +ll0, +sl4 }, { -sl9, +ll0, +sl9, +ll0 }, { -ll0, +sl4, -sl4, +ll0 },
         { -ll0, -sl9, -ll0, +sl9 }, { -sl4, -ll0, -ll0, -sl4 }, { +sl9, -ll0, -sl9, -ll0 },
         { +ll0, -sl4, +sl4, -ll0 }, { +ll0, +sl9, +ll0, -sl9 }, { +sl4, +ll0, +ll0, +sl4 },
@@ -322,5 +358,5 @@
     // the different color modes
     enum colorModes {
-        none, velocity, dilution
+        none, velocity, dilution, direction
     }
 
@@ -430,4 +466,15 @@
                                 break;
 
+                            case direction:
+                                // unfortunately "heading" misses a cos-factor in the
+                                // longitudes to account for the convergence of meridians
+                                double dirColor = oldWp.getCoor().heading(trkPnt.getCoor()) / (2.0 * Math.PI) * 256;
+                                // Bad case first
+                                if (dirColor != dirColor || dirColor < 0.0 || dirColor >= 256.0) {
+                                    trkPnt.customColoring = colors_cyclic[0];
+                                } else {
+                                    trkPnt.customColoring = colors_cyclic[(int) (dirColor)];
+                                }
+                                break;
                             case dilution:
                                 if (trkPnt.attr.get("hdop") != null) {
@@ -647,4 +694,5 @@
         }
 
+        @Override
         public void actionPerformed(ActionEvent e) {
             JPanel msg = new JPanel(new GridBagLayout());
@@ -702,4 +750,5 @@
         }
 
+        @Override
         public void actionPerformed(ActionEvent e) {
             JPanel msg = new JPanel(new GridBagLayout());
@@ -876,4 +925,5 @@
             Main.worker.submit(
                     new Runnable() {
+                        @Override
                         public void run() {
                             try {
@@ -1087,4 +1137,5 @@
 
         Collections.sort((ArrayList<WayPoint>) waypoints, new Comparator<WayPoint>() {
+            @Override
             public int compare(WayPoint a, WayPoint b) {
                 return a.time <= b.time ? -1 : 1;
@@ -1405,4 +1456,5 @@
                 if (sel.length > 1) {
                     Arrays.sort(sel, new Comparator<File>() {
+                        @Override
                         public int compare(File a, File b) {
                             return a.lastModified() <= b.lastModified() ? -1 : 1;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/DrawingPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/DrawingPreference.java	(revision 4206)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/DrawingPreference.java	(revision 4207)
@@ -45,4 +45,5 @@
     private ButtonGroup colorGroup;
     private JRadioButton colorTypeVelocity = new JRadioButton(tr("Velocity (red = slow, green = fast)"));
+    private JRadioButton colorTypeDirection = new JRadioButton(tr("Direction (red = west, yellow = north, green = east, blue = south)"));
     private JRadioButton colorTypeDilution = new JRadioButton(tr("Dilution of Position (red = high, green = low, if available)"));
     private JRadioButton colorTypeNone = new JRadioButton(tr("Single Color (can be customized for named layers)"));
@@ -170,4 +171,5 @@
         colorGroup.add(colorTypeNone);
         colorGroup.add(colorTypeVelocity);
+        colorGroup.add(colorTypeDirection);
         colorGroup.add(colorTypeDilution);
 
@@ -188,8 +190,12 @@
             colorTypeDilution.setSelected(true);
             break;
+        case 3:
+            colorTypeDirection.setSelected(true);
+            break;
         }
 
         colorTypeNone.setToolTipText(tr("All points and track segments will have the same color. Can be customized in Layer Manager."));
         colorTypeVelocity.setToolTipText(tr("Colors points and track segments by velocity."));
+        colorTypeDirection.setToolTipText(tr("Colors points and track segments by direction."));
         colorTypeDilution.setToolTipText(tr("Colors points and track segments by dilution of position (HDOP). Your capture device needs to log that information."));
 
@@ -206,4 +212,5 @@
         panel.add(colorTypeVelocity, GBC.std().insets(40,0,0,0));
         panel.add(colorTypeVelocityTune, GBC.eop().insets(5,0,0,5));
+        panel.add(colorTypeDirection, GBC.eol().insets(40,0,0,0));
         panel.add(colorTypeDilution, GBC.eol().insets(40,0,0,0));
 
@@ -300,4 +307,6 @@
         } else if(colorTypeDilution.isSelected()) {
             Main.pref.putInteger("draw.rawgps.colors", 2);
+        } else if(colorTypeDirection.isSelected()) {
+            Main.pref.putInteger("draw.rawgps.colors", 3);
         } else {
             Main.pref.putInteger("draw.rawgps.colors", 0);
