Index: /trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 11450)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 11451)
@@ -743,5 +743,5 @@
 
         // alpha value is based on zoom and line with combined with global layer alpha
-        float theLineAlpha = Math.min(Math.max((0.50f/(float) zoomScale)/(globalLineWidth + 1), 0.001f), 0.50f) * layerAlpha;
+        float theLineAlpha = Math.min(Math.max((0.50f/(float) zoomScale)/(globalLineWidth + 1), 0.01f), 0.50f) * layerAlpha;
         final int theLineWith = (int) (lineWidth / zoomScale) + 1;
 
@@ -834,5 +834,5 @@
 
             // alpha with pre-offset, first color -> full transparent
-            alpha = i > 0 ? (75 + alpha) : 0;
+            alpha = i > 0 ? (10 + alpha) : 0;
 
             // shrink to maximum bound
@@ -852,4 +852,19 @@
         // transform into lookup table
         return colorTable;
+    }
+
+    /**
+     * Creates a darker color
+     * @param in        Color object
+     * @param adjust    darker adjustment amount
+     * @return          new Color
+     */
+    protected static Color darkerColor(Color in, float adjust) {
+
+        final float r = ((float) in.getRed()/255);
+        final float g = ((float) in.getGreen()/255);
+        final float b = ((float) in.getBlue()/255);
+
+        return new Color(r*adjust, g*adjust, b*adjust);
     }
 
@@ -900,4 +915,9 @@
             colorList.add(Color.BLACK);
             colorList.add(Color.WHITE);
+        } else {
+            // add additional darker elements to end of list
+            final Color lastColor = colorList.get(colorList.size() - 1);
+            colorList.add(darkerColor(lastColor, 0.975f));
+            colorList.add(darkerColor(lastColor, 0.950f));
         }
 
@@ -925,9 +945,15 @@
         gB.setStroke(backStroke); gB.setComposite(backComp);
 
-        // for all points, draw single lines by using optimize drawing
+        // get last point in list
+        final WayPoint lastPnt = !listSegm.isEmpty() ? listSegm.get(listSegm.size() - 1) : null;
+
+        // for all points, draw single lines by using optimized drawing
         for (WayPoint trkPnt : listSegm) {
 
-            // something to paint or color changed (new segment needed, decrease performance ;-()
-            if (!trkPnt.drawLine && !heatMapPolyX.isEmpty()) {
+            // get transformed coordinates
+            final Point paintPnt = mv.getPoint(trkPnt.getEastNorth());
+
+            // end of line segment or end of list reached
+            if (!trkPnt.drawLine || (lastPnt == trkPnt)) {
 
                 // convert to primitive type
@@ -946,16 +972,11 @@
                 }
 
-                // drop used pints
+                // drop used points
                 heatMapPolyX.clear(); heatMapPolyY.clear();
-
-            } else {
-
-                // get transformed coordinates
-                final Point paintPnt = mv.getPoint(trkPnt.getEastNorth());
-
-                // store only the integer part (make sense because pixel is 1:1 here)
-                heatMapPolyX.add((int) paintPnt.getX());
-                heatMapPolyY.add((int) paintPnt.getY());
-            }
+            }
+
+            // store only the integer part (make sense because pixel is 1:1 here)
+            heatMapPolyX.add((int) paintPnt.getX());
+            heatMapPolyY.add((int) paintPnt.getY());
         }
     }
@@ -966,15 +987,25 @@
      * @param imgGray         gray scale input image
      * @param sampleRaster    the line with for drawing
-     */
-    private void drawHeatMapGrayMap(Graphics2D g, BufferedImage imgGray, int sampleRaster) {
+     * @param outlineWidth     line width for outlines
+     */
+    private void drawHeatMapGrayMap(Graphics2D g, BufferedImage imgGray, int sampleRaster, int outlineWidth) {
 
         final int[] imgPixels = ((DataBufferInt) imgGray.getRaster().getDataBuffer()).getData();
 
         // samples offset and bounds are scaled with line width derived from zoom level
-        final int offX = Math.max(1, sampleRaster / 2);
-        final int offY = Math.max(1, sampleRaster / 2);
+        final int offX = Math.max(1, sampleRaster);
+        final int offY = Math.max(1, sampleRaster);
 
         final int maxPixelX = imgGray.getWidth();
         final int maxPixelY = imgGray.getHeight();
+
+        // always full or outlines at big samples rasters
+        final boolean drawOutlines = (outlineWidth > 0) && ((0 == sampleRaster) || (sampleRaster > 8));
+
+        // backup stroke
+        final Stroke oldStroke = g.getStroke();
+
+        // use basic stroke for outlines and default transparency
+        g.setStroke(new BasicStroke(outlineWidth));
 
         int lastPixelY = 0;
@@ -1001,26 +1032,34 @@
                 // restart -> use initial sample
                 if (0 == y) {
-                    lastPixelY = 0; lastPixelColor = thePixelColor;
-                }
-
-                // different color to last one ?
-                if (Math.abs(lastPixelColor - thePixelColor) > 1) {
-
-                    // draw only foreground pixels, skip small variations
-                    if (lastPixelColor > 1+1) {
+                    lastPixelY = 0; lastPixelColor = thePixelColor - 1;
+                }
+
+                boolean bDrawIt = false;
+
+                // when one of segment is mapped to black
+                bDrawIt = bDrawIt || (lastPixelColor == 0) || (thePixelColor == 0);
+
+                // different color
+                bDrawIt = bDrawIt || (Math.abs(lastPixelColor-thePixelColor) > 0);
+
+                // when line is finished draw always
+                bDrawIt = bDrawIt || (y >= (maxPixelY-offY));
+
+                if (bDrawIt) {
+
+                    // draw only foreground pixels
+                    if (lastPixelColor > 0) {
 
                         // gray to RGB mapping
                         g.setColor(heatMapLutColor[ lastPixelColor ]);
 
-                        // start point for draw (
-                        int yN = lastPixelY > 0 ? lastPixelY : y;
-
                         // box from from last Y pixel to current pixel
-                        if (offX < sampleRaster) {
-                            g.fillRect(yN, x, offY + y - yN, offX);
+                        if (drawOutlines) {
+                            g.drawRect(lastPixelY, x, offY + y - lastPixelY, offX);
                         } else {
-                            g.drawRect(yN, x, offY + y - yN, offX);
+                            g.fillRect(lastPixelY, x, offY + y - lastPixelY, offX);
                         }
                     }
+
                     // restart detection
                     lastPixelY = y; lastPixelColor = thePixelColor;
@@ -1028,4 +1067,7 @@
             }
         }
+
+        // recover
+        g.setStroke(oldStroke);
     }
 
@@ -1042,6 +1084,6 @@
         final double zoomScale = mv.getScale();
 
-        // adjust global settings
-        final int globalLineWidth = Math.min(Math.max(lineWidth, 1), 20);
+        // adjust global settings ( zero = default line width )
+        final int globalLineWidth = (0 == lineWidth) ? 1 : Math.min(Math.max(lineWidth, 1), 20);
 
         // 1st setup virtual paint area ----------------------------------------
@@ -1070,5 +1112,5 @@
 
         // the line width (foreground: draw extra small footprint line of track)
-        final int lineWidthB = Math.max((int) (globalLineWidth / zoomScale) + 1, 2);
+        final int lineWidthB = (int) Math.max(1.5f * (globalLineWidth / zoomScale) + 1, 2);
         final int lineWidthF = lineWidthB > 2 ? (globalLineWidth - 1) : 0;
 
@@ -1087,5 +1129,5 @@
 
             // alpha combines both values, therefore the foreground shall be lighter
-            final float lineAlphaB = Math.min(Math.max((0.40f/(float) zoomScale)/(globalLineWidth + 1), 0.001f), 0.50f);
+            final float lineAlphaB = Math.min(Math.max((0.40f/(float) zoomScale)/(globalLineWidth + 1), 0.01f), 0.40f);
             final float lineAlphaF = lineAlphaB / 1.5f;
 
@@ -1104,5 +1146,7 @@
 
         // 4th. Draw data on target layer, map data via color lookup table --------------
-        drawHeatMapGrayMap(g, heatMapImgGray, lineWidthB);
+        drawHeatMapGrayMap(g, heatMapImgGray,
+                lineWidthB > 2 ? (lineWidthB / 2) : 1,
+                lineWidth > 2 ? (lineWidth - 2) : 1);
     }
 
