Index: trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 4249)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 4250)
@@ -92,4 +92,5 @@
     private int computeCacheMaxLineLengthUsed;
     private Color computeCacheColorUsed;
+    private boolean computeCacheColorDynamic;
     private colorModes computeCacheColored;
     private int computeCacheColorTracksTune;
@@ -421,4 +422,6 @@
         // allows to tweak line coloring for different speed levels.
         int colorTracksTune = Main.pref.getInteger("draw.rawgps.colorTracksTune", "layer "+getName(), 45);
+        boolean colorModeDynamic = Main.pref.getBoolean("draw.rawgps.colors.dynamic", "layer "+getName(), false);
+        int hdopfactor = Main.pref.getInteger("hdop.factor", 25);
 
         if(lineWidth != 0)
@@ -431,9 +434,6 @@
          ****************************************************************/
         if ((computeCacheMaxLineLengthUsed != maxLineLength) || (!neutralColor.equals(computeCacheColorUsed))
-                || (computeCacheColored != colored) || (computeCacheColorTracksTune != colorTracksTune)) {
-            // System.out.println("(re-)computing gpx line styles, reason: CCIS=" +
-            // computeCacheInSync + " CCMLLU=" + (computeCacheMaxLineLengthUsed != maxLineLength) +
-            // " CCCU=" + (!neutralColor.equals(computeCacheColorUsed)) + " CCC=" +
-            // (computeCacheColored != colored));
+                || (computeCacheColored != colored) || (computeCacheColorTracksTune != colorTracksTune)
+                || (computeCacheColorDynamic != colorModeDynamic)) {
             computeCacheMaxLineLengthUsed = maxLineLength;
             computeCacheInSync = false;
@@ -441,4 +441,5 @@
             computeCacheColored = colored;
             computeCacheColorTracksTune = colorTracksTune;
+            computeCacheColorDynamic = colorModeDynamic;
         }
 
@@ -447,5 +448,42 @@
          ****************************************************************/
         if (!computeCacheInSync) { // don't compute if the cache is good
+            Float minval = null;
+            Float maxval = null;
             WayPoint oldWp = null;
+            if (colorModeDynamic) {
+                if (colored == colorModes.velocity) {
+                    for (GpxTrack trk : data.tracks) {
+                        for (GpxTrackSegment segment : trk.getSegments()) {
+                            if(!forceLines) oldWp = null;
+                            for (WayPoint trkPnt : segment.getWayPoints()) {
+                                LatLon c = trkPnt.getCoor();
+                                if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
+                                    continue;
+                                }
+                                if (oldWp != null && trkPnt.time > oldWp.time) {
+                                    Float vel = new Float(c.greatCircleDistance(oldWp.getCoor()) / (trkPnt.time - oldWp.time));
+                                    if(maxval == null || vel > maxval) maxval = vel;
+                                    if(minval == null || vel < minval) minval = vel;
+                                }
+                                oldWp = trkPnt;
+                            }
+                        }
+                    }
+                } else if (colored == colorModes.dilution) {
+                    for (GpxTrack trk : data.tracks) {
+                        for (GpxTrackSegment segment : trk.getSegments()) {
+                            for (WayPoint trkPnt : segment.getWayPoints()) {
+                                Object val = trkPnt.attr.get("hdop");
+                                if (val != null) {
+                                    Float hdop = (Float) val;
+                                    if(maxval == null || hdop > maxval) maxval = hdop;
+                                    if(minval == null || hdop < minval) minval = hdop;
+                                }
+                            }
+                        }
+                    }
+                }
+                oldWp = null;
+            }
             for (GpxTrack trk : data.tracks) {
                 for (GpxTrackSegment segment : trk.getSegments()) {
@@ -459,4 +497,13 @@
                         }
                         trkPnt.customColoring = neutralColor;
+                        if(colored == colorModes.dilution && trkPnt.attr.get("hdop") != null) {
+                            float hdop = ((Float) trkPnt.attr.get("hdop")).floatValue();
+                            int hdoplvl = Math.round(colorModeDynamic ? ((hdop-minval)*255/(maxval-minval))
+                            : (hdop <= 0 ? 0 : hdop * hdopfactor));
+                            // High hdop is bad, but high values in colors are green.
+                            // Therefore inverse the logic
+                            int hdopcolor = 255 - (hdoplvl > 255 ? 255 : hdoplvl);
+                            trkPnt.customColoring = colors[hdopcolor];
+                        }
                         if (oldWp != null) {
                             double dist = c.greatCircleDistance(oldWp.getCoor());
@@ -465,14 +512,13 @@
                             case velocity:
                                 double dtime = trkPnt.time - oldWp.time;
-                                double vel = dist / dtime;
-                                double velColor = vel / colorTracksTune * 255;
-                                // Bad case first
-                                if (dtime <= 0 || vel < 0 || velColor > 255) {
+                                if(dtime > 0) {
+                                    float vel = (float) (dist / dtime);
+                                    int velColor = Math.round(colorModeDynamic ? ((vel-minval)*255/(maxval-minval))
+                                    : (vel <= 0 ? 0 : vel / colorTracksTune * 255));
+                                    trkPnt.customColoring = colors[velColor > 255 ? 255 : velColor];
+                                } else {
                                     trkPnt.customColoring = colors[255];
-                                } else {
-                                    trkPnt.customColoring = colors[(int) (velColor)];
                                 }
                                 break;
-
                             case direction:
                                 double dirColor = oldWp.getCoor().heading(trkPnt.getCoor()) / (2.0 * Math.PI) * 256;
@@ -482,17 +528,4 @@
                                 } else {
                                     trkPnt.customColoring = colors_cyclic[(int) (dirColor)];
-                                }
-                                break;
-                            case dilution:
-                                if (trkPnt.attr.get("hdop") != null) {
-                                    float hdop = ((Float) trkPnt.attr.get("hdop")).floatValue();
-                                    if (hdop < 0) {
-                                        hdop = 0;
-                                    }
-                                    int hdoplvl = Math.round(hdop * Main.pref.getInteger("hdop.factor", 25));
-                                    // High hdop is bad, but high values in colors are green.
-                                    // Therefore inverse the logic
-                                    int hdopcolor = 255 - (hdoplvl > 255 ? 255 : hdoplvl);
-                                    trkPnt.customColoring = colors[hdopcolor];
                                 }
                                 break;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/DrawingPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/DrawingPreference.java	(revision 4249)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/DrawingPreference.java	(revision 4250)
@@ -62,4 +62,5 @@
     private JCheckBox makeAutoMarkers = new JCheckBox(tr("Create markers when reading GPX."));
     private JCheckBox outlineOnly = new JCheckBox(tr("Draw only outlines of areas"));
+    private JCheckBox colorDynamic = new JCheckBox(tr("Dynamic color range based on data limits"));
     private JComboBox waypointLabel = new JComboBox(new String[] {tr("Auto"), /* gpx data field name */ trc("gpx_field", "Name"),
             /* gpx data field name */ trc("gpx_field", "Desc(ription)"), tr("Both"), tr("None")});
@@ -177,4 +178,10 @@
             public void stateChanged(ChangeEvent e) {
                 colorTypeVelocityTune.setEnabled(colorTypeVelocity.isSelected());
+                colorDynamic.setEnabled(colorTypeVelocity.isSelected() || colorTypeDilution.isSelected());
+            }
+        });
+        colorTypeDilution.addChangeListener(new ChangeListener(){
+            public void stateChanged(ChangeEvent e) {
+                colorDynamic.setEnabled(colorTypeVelocity.isSelected() || colorTypeDilution.isSelected());
             }
         });
@@ -214,4 +221,8 @@
         panel.add(colorTypeDirection, GBC.eol().insets(40,0,0,0));
         panel.add(colorTypeDilution, GBC.eol().insets(40,0,0,0));
+        colorDynamic.setToolTipText(tr("Draw direction arrows for lines, connecting GPS points."));
+        colorDynamic.setSelected(Main.pref.getBoolean("draw.rawgps.colors.dynamic", false));
+        colorDynamic.setEnabled(colorTypeVelocity.isSelected() || colorTypeDilution.isSelected());
+        panel.add(colorDynamic, GBC.eop().insets(40,0,0,0));
 
         // waypointLabel
@@ -302,4 +313,5 @@
         Main.pref.put("draw.rawgps.alternatedirection", drawGpsArrowsFast.isSelected());
         Main.pref.put("draw.rawgps.min-arrow-distance", drawGpsArrowsMinDist.getText());
+        Main.pref.put("draw.rawgps.colors.dynamic", colorDynamic.isSelected());
         if(colorTypeVelocity.isSelected()) {
             Main.pref.putInteger("draw.rawgps.colors", 1);
