Index: src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 11427)
+++ src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(working copy)
@@ -4,17 +4,27 @@
 import static org.openstreetmap.josm.tools.I18n.marktr;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.awt.AlphaComposite;
 import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Composite;
 import java.awt.Graphics2D;
+import java.awt.LinearGradientPaint;
+import java.awt.MultipleGradientPaint;
+import java.awt.Paint;
 import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.RenderingHints;
 import java.awt.Stroke;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
+import java.util.LinkedList;
 import java.util.List;
 
 import org.openstreetmap.josm.Main;
@@ -28,6 +38,7 @@
 import org.openstreetmap.josm.data.preferences.ColorProperty;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.tools.ColorScale;
+import org.openstreetmap.josm.tools.Utils;
 
 /**
  * Class that helps to draw large set of GPS tracks with different colors and options
@@ -45,11 +56,15 @@
 
     // draw lines between points belonging to different segments
     private boolean forceLines;
+    // use alpha blending for line draw
+    private boolean alphaLines;
     // draw direction arrows on the lines
     private boolean direction;
-    /** don't draw lines if longer than x meters **/
+    /** width of line for paint **/
     private int lineWidth;
+    /** don't draw lines if longer than x meters **/
     private int maxLineLength;
+    // draw lines
     private boolean lines;
     /** paint large dots for points **/
     private boolean large;
@@ -73,6 +88,7 @@
     private boolean computeCacheColorDynamic;
     private ColorMode computeCacheColored;
     private int computeCacheColorTracksTune;
+    private int computeCacheHeatMapDrawColorTableIdx;
 
     //// Color-related fields
     /** Mode of the line coloring **/
@@ -104,6 +120,600 @@
         {+ll0, -sl4, +sl4, -ll0}, {+ll0, +sl9, +ll0, -sl9}
     };
 
+    /** heat map parameters **/
+
+    // enabled or not (override by settings)
+    private boolean heatMapEnabled = false;
+    // draw small extra line
+    private boolean heatMapDrawExtraLine = false;
+    // used index for color table (parameter)
+    private int heatMapDrawColorTableIdx = 0;
+
+    // normal buffered image and draw object (cached)
+    private BufferedImage heatMapImgGray = null;
+    private Graphics2D heatMapGraph2d = null;
+
+    // some cached values
+    Rectangle heatMapCacheScreenBounds = new Rectangle();
+    int heatMapCacheVisibleSegments = 0;
+    double heatMapCacheZoomScale = 0;
+    int heatMapCacheLineWith = 0;
+
+    // copied value for line drawing
+    private List<Integer> heatMapPolyX = new ArrayList<Integer>();
+    private List<Integer> heatMapPolyY = new ArrayList<Integer>();
+
+    // based on color map aka inferno with adjustment to more brighter values
+    // Used to reconstruct the colormap in viscm (http://bids.github.io/colormap/)
+    // parameters = {'xp': [-2.059155383623448, 55.527989656842408, 34.409268195655187, 4.76708575112832, -9.505963894261754},
+    //               'yp': [-25.66489361702122, -20.376712328767127, 26.997716894977174, 20.56737588652487, 32.047872340425585},
+    //               'min_Jp': 33.3692722372,
+    //               'max_Jp': 95}
+    private static final double[][] colorMapJosmInfernoBright = {
+            {0.21520753, 0.27038249, 0.57012105},
+            {0.22312459, 0.27103303, 0.57166455},
+            {0.23080347, 0.27168503, 0.57324007},
+            {0.23833063, 0.27231877, 0.57483869},
+            {0.24568074, 0.27294692, 0.57646522},
+            {0.25289476, 0.2735611, 0.57811579},
+            {0.25997831, 0.27416334, 0.57979067},
+            {0.2669379, 0.27475519, 0.58148978},
+            {0.27380298, 0.27532947, 0.58321},
+            {0.28055428, 0.27589622, 0.58495399},
+            {0.287239, 0.2764405, 0.58671621},
+            {0.29381911, 0.27697939, 0.58850116},
+            {0.30035424, 0.27749166, 0.59030167},
+            {0.3067935, 0.27799996, 0.59212335},
+            {0.31320428, 0.2784783, 0.59395808},
+            {0.31952836, 0.27895311, 0.59581191},
+            {0.32583529, 0.27939586, 0.59767646},
+            {0.3320659, 0.27983431, 0.59955752},
+            {0.33828602, 0.28023999, 0.60144712},
+            {0.34443919, 0.2806404, 0.60335045},
+            {0.35058925, 0.28100652, 0.60525968},
+            {0.35668082, 0.28136625, 0.60717967},
+            {0.36277287, 0.28169157, 0.60910303},
+            {0.3688165, 0.28200806, 0.61103375},
+            {0.37486069, 0.28229156, 0.61296536},
+            {0.38086771, 0.28256263, 0.61490057},
+            {0.38687304, 0.28280326, 0.61683417},
+            {0.39285321, 0.28302691, 0.61876728},
+            {0.39882725, 0.28322388, 0.6206963},
+            {0.40478897, 0.28339829, 0.62262037},
+            {0.41073803, 0.28355108, 0.62453795},
+            {0.41668846, 0.28367469, 0.62644568},
+            {0.42261777, 0.28378305, 0.62834468},
+            {0.42856299, 0.28385455, 0.63022847},
+            {0.43448626, 0.28391267, 0.63210021},
+            {0.44042184, 0.28393692, 0.63395343},
+            {0.44634815, 0.28394123, 0.63578925},
+            {0.45227252, 0.28392157, 0.63760476},
+            {0.45820558, 0.28387152, 0.63939628},
+            {0.46412436, 0.28380662, 0.6411656},
+            {0.47006356, 0.28370439, 0.64290476},
+            {0.47599406, 0.28358471, 0.64461676},
+            {0.48192565, 0.28344156, 0.64629781},
+            {0.48786962, 0.28326756, 0.64794343},
+            {0.49380435, 0.28307827, 0.64955593},
+            {0.49975251, 0.28285825, 0.65112821},
+            {0.50570289, 0.28261587, 0.65266041},
+            {0.51164619, 0.2823585, 0.65415271},
+            {0.51760901, 0.28206718, 0.65559589},
+            {0.52356861, 0.28175913, 0.65699349},
+            {0.52952249, 0.28143693, 0.65834417},
+            {0.5354961, 0.28108192, 0.65963775},
+            {0.54146547, 0.28071283, 0.66087903},
+            {0.54742976, 0.28033111, 0.66206616},
+            {0.55340844, 0.27992224, 0.66318972},
+            {0.55938599, 0.27949898, 0.66425255},
+            {0.56535835, 0.27906539, 0.66525388},
+            {0.57133473, 0.2786149, 0.66618743},
+            {0.57731677, 0.27814689, 0.66704956},
+            {0.58329279, 0.27767173, 0.66784277},
+            {0.58926275, 0.27719044, 0.66856469},
+            {0.59523878, 0.27669389, 0.66920646},
+            {0.601212, 0.27619042, 0.66976956},
+            {0.60717734, 0.27568537, 0.67025404},
+            {0.61313444, 0.27518023, 0.67065755},
+            {0.6190896, 0.27467077, 0.67097344},
+            {0.62504118, 0.27415958, 0.67119949},
+            {0.63098171, 0.27365438, 0.67133763},
+            {0.63691049, 0.27315721, 0.67138563},
+            {0.64282668, 0.27267021, 0.67134132},
+            {0.64873334, 0.2721922, 0.67119941},
+            {0.65463011, 0.27172501, 0.67095685},
+            {0.66051031, 0.27127617, 0.67061602},
+            {0.66637279, 0.27084839, 0.67017505},
+            {0.67221629, 0.27044454, 0.66963216},
+            {0.67803951, 0.27006762, 0.66898569},
+            {0.68384101, 0.26972075, 0.66823411},
+            {0.68962043, 0.2694062, 0.66737478},
+            {0.69537788, 0.26912584, 0.66640432},
+            {0.70110815, 0.26888634, 0.66532544},
+            {0.70680955, 0.26869125, 0.66413723},
+            {0.71248034, 0.26854423, 0.66283897},
+            {0.71811869, 0.26844898, 0.66143017},
+            {0.72372274, 0.26840929, 0.6599105},
+            {0.72929057, 0.26842895, 0.65827991},
+            {0.7348202, 0.26851179, 0.65653854},
+            {0.74030966, 0.26866163, 0.65468679},
+            {0.74575692, 0.26888225, 0.65272532},
+            {0.75115994, 0.26917738, 0.65065505},
+            {0.75651668, 0.26955067, 0.64847715},
+            {0.76182512, 0.27000568, 0.64619309},
+            {0.76708321, 0.27054582, 0.64380458},
+            {0.77228898, 0.27117434, 0.64131363},
+            {0.77744045, 0.27189431, 0.63872252},
+            {0.78253571, 0.27270861, 0.63603377},
+            {0.7875729, 0.27361986, 0.63325018},
+            {0.79255022, 0.27463045, 0.6303748},
+            {0.79746596, 0.27574247, 0.62741092},
+            {0.80231908, 0.27695738, 0.62436032},
+            {0.80710794, 0.27827681, 0.62122676},
+            {0.81183046, 0.27970239, 0.6180159},
+            {0.8164853, 0.28123501, 0.61473188},
+            {0.82107123, 0.28287522, 0.611379},
+            {0.82558714, 0.28462328, 0.60796168},
+            {0.83003205, 0.28647909, 0.60448445},
+            {0.8344051, 0.28844227, 0.60095193},
+            {0.83870608, 0.29051198, 0.59736649},
+            {0.84293394, 0.29268742, 0.59373445},
+            {0.84708799, 0.29496738, 0.59006162},
+            {0.8511679, 0.29735032, 0.58635274},
+            {0.85517346, 0.29983446, 0.58261253},
+            {0.85910459, 0.30241779, 0.57884566},
+            {0.86296154, 0.30509821, 0.57505503},
+            {0.8667442, 0.30787334, 0.57124668},
+            {0.87045278, 0.31074062, 0.56742555},
+            {0.87408763, 0.3136974, 0.5635959},
+            {0.87764922, 0.31674094, 0.55976186},
+            {0.88113814, 0.31986844, 0.55592693},
+            {0.88455499, 0.32307701, 0.55209513},
+            {0.88790044, 0.32636363, 0.54827073},
+            {0.89117526, 0.32972536, 0.54445721},
+            {0.89438031, 0.33315921, 0.54065783},
+            {0.89751647, 0.33666226, 0.53687571},
+            {0.90058468, 0.34023153, 0.53311396},
+            {0.90358593, 0.34386414, 0.52937539},
+            {0.90652122, 0.34755725, 0.52566255},
+            {0.90939159, 0.35130809, 0.5219778},
+            {0.91219812, 0.35511391, 0.51832354},
+            {0.91494189, 0.35897199, 0.51470218},
+            {0.91762398, 0.36287988, 0.51111515},
+            {0.92024546, 0.36683514, 0.50756411},
+            {0.92280743, 0.3708354, 0.50405059},
+            {0.92531095, 0.37487835, 0.5005761},
+            {0.92775723, 0.37896156, 0.49714278},
+            {0.93014721, 0.38308319, 0.4937508},
+            {0.93248195, 0.38724127, 0.49040111},
+            {0.93476246, 0.3914339, 0.48709457},
+            {0.93698975, 0.39565929, 0.48383192},
+            {0.93916494, 0.39991543, 0.48061464},
+            {0.94128894, 0.40420083, 0.47744286},
+            {0.94336261, 0.40851411, 0.47431661},
+            {0.94538686, 0.4128538, 0.47123623},
+            {0.94736256, 0.41721856, 0.468202},
+            {0.94929056, 0.42160708, 0.46521414},
+            {0.95117192, 0.42601776, 0.46227381},
+            {0.95300724, 0.4304498, 0.45938022},
+            {0.95479724, 0.43490219, 0.4565332},
+            {0.95654264, 0.43937392, 0.45373274},
+            {0.95824414, 0.44386407, 0.45097877},
+            {0.95990241, 0.44837175, 0.44827118},
+            {0.96151825, 0.45289592, 0.44561039},
+            {0.96309223, 0.45743586, 0.44299605},
+            {0.9646248, 0.46199106, 0.44042751},
+            {0.96611649, 0.46656086, 0.43790454},
+            {0.96756782, 0.47114466, 0.43542688},
+            {0.96897927, 0.47574187, 0.43299428},
+            {0.9703513, 0.48035197, 0.43060645},
+            {0.97168455, 0.48497424, 0.42826362},
+            {0.9729793, 0.48960837, 0.42596514},
+            {0.97423583, 0.49425407, 0.42371048},
+            {0.97545448, 0.49891094, 0.42149932},
+            {0.97663559, 0.50357865, 0.41933134},
+            {0.97777945, 0.50825686, 0.41720624},
+            {0.97888633, 0.51294528, 0.41512369},
+            {0.97995654, 0.5176436, 0.41308347},
+            {0.98099046, 0.52235141, 0.41108558},
+            {0.98198808, 0.5270687, 0.40912927},
+            {0.98294961, 0.53179527, 0.40721424},
+            {0.98387521, 0.53653092, 0.40534022},
+            {0.98476504, 0.54127549, 0.40350692},
+            {0.98561924, 0.54602881, 0.40171405},
+            {0.98643793, 0.55079072, 0.39996136},
+            {0.98722122, 0.55556111, 0.3982486},
+            {0.98796936, 0.5603397, 0.39657571},
+            {0.98868226, 0.56512655, 0.39494219},
+            {0.98936, 0.56992153, 0.3933478},
+            {0.99000264, 0.57472455, 0.39179229},
+            {0.99061026, 0.57953551, 0.39027544},
+            {0.99118291, 0.5843543, 0.38879701},
+            {0.99172063, 0.58918085, 0.38735678},
+            {0.99222348, 0.59401505, 0.38595451},
+            {0.99269152, 0.59885681, 0.38458997},
+            {0.99312476, 0.60370607, 0.38326287},
+            {0.99352325, 0.60856274, 0.38197295},
+            {0.99388704, 0.61342672, 0.38071994},
+            {0.9942162, 0.61829793, 0.37950355},
+            {0.9945108, 0.62317625, 0.37832349},
+            {0.99477091, 0.62806159, 0.37717942},
+            {0.99499662, 0.63295383, 0.376071},
+            {0.99518804, 0.63785286, 0.37499782},
+            {0.99534511, 0.64275869, 0.37395927},
+            {0.99546806, 0.64767111, 0.372955},
+            {0.99555705, 0.65258996, 0.37198453},
+            {0.99561226, 0.65751512, 0.37104728},
+            {0.99563387, 0.66244643, 0.37014263},
+            {0.99562207, 0.66738375, 0.36926988},
+            {0.99557709, 0.6723269, 0.36842829},
+            {0.99549919, 0.67727574, 0.367617},
+            {0.99538832, 0.68223028, 0.3668348},
+            {0.99524486, 0.6871903, 0.36608079},
+            {0.99506928, 0.69215551, 0.36535402},
+            {0.99486193, 0.69712571, 0.36465327},
+            {0.99462316, 0.70210071, 0.36397724},
+            {0.99435337, 0.70708033, 0.36332451},
+            {0.99405297, 0.71206436, 0.36269354},
+            {0.99372226, 0.7170527, 0.36208252},
+            {0.99336115, 0.72204548, 0.36148919},
+            {0.99297075, 0.72704212, 0.36091215},
+            {0.99255157, 0.73204239, 0.36034933},
+            {0.99210417, 0.7370461, 0.35979848},
+            {0.9916291, 0.74205305, 0.35925722},
+            {0.99112697, 0.74706302, 0.35872299},
+            {0.99059766, 0.75207625, 0.35819249},
+            {0.99004191, 0.75709248, 0.3576629},
+            {0.98946091, 0.76211118, 0.35713157},
+            {0.98885534, 0.76713218, 0.35659523},
+            {0.98822592, 0.77215526, 0.3560504},
+            {0.98757341, 0.77718026, 0.35549344},
+            {0.98689724, 0.78220771, 0.35491939},
+            {0.98619894, 0.78723702, 0.35432474},
+            {0.98547981, 0.79226775, 0.35370552},
+            {0.98474069, 0.79729971, 0.35305716},
+            {0.98398247, 0.80233272, 0.35237485},
+            {0.98320475, 0.80736733, 0.3516524},
+            {0.98240874, 0.81240322, 0.35088461},
+            {0.9815964, 0.81743967, 0.35006665},
+            {0.9807688, 0.8224765, 0.34919255},
+            {0.97992705, 0.82751352, 0.34825605},
+            {0.97906945, 0.83255201, 0.34724796},
+            {0.97819995, 0.83759034, 0.34616365},
+            {0.97731989, 0.84262826, 0.34499577},
+            {0.97643067, 0.84766553, 0.34373656},
+            {0.97553084, 0.85270337, 0.34237486},
+            {0.9746244, 0.85774026, 0.34090421},
+            {0.97371347, 0.86277567, 0.3393158},
+            {0.97279937, 0.8678095, 0.33759927},
+            {0.97188135, 0.87284272, 0.33574113},
+            {0.97096472, 0.87787333, 0.33373367},
+            {0.97005177, 0.88290083, 0.33156512},
+            {0.96914211, 0.88792612, 0.3292193},
+            {0.9682402, 0.89294775, 0.32668465},
+            {0.96735004, 0.89796453, 0.32394813},
+            {0.96647255, 0.90297683, 0.32099108},
+            {0.96561166, 0.9079836, 0.31779718},
+            {0.96477281, 0.91298312, 0.31435094},
+            {0.96395774, 0.91797553, 0.31062911},
+            {0.96317157, 0.92295935, 0.30661145},
+            {0.96242046, 0.92793272, 0.30227735},
+            {0.96170672, 0.93289563, 0.29759626},
+            {0.96103783, 0.93784572, 0.29254395},
+            {0.96041973, 0.94278138, 0.2870899},
+            {0.95985661, 0.94770189, 0.28119495},
+            {0.95935719, 0.95260448, 0.27482525},
+            {0.95892721, 0.9574878, 0.26793369},
+            {0.95857402, 0.9623498, 0.2604697},
+            {0.9583055, 0.96718821, 0.25237504}
+
+    }; // end of colorMapJosmInfernoBright
+
+    // Used to reconstruct the colormap in viscm (http://bids.github.io/colormap/)
+    // {'xp': [-8.9697272381347659, -14.962877923066287, -32.371553722153038, -30.373836827175865, -6.9720103431575922, -8.684339110280888},
+    // 'yp': [-25.513698630136986, 15.296803652968038, -30.650684931506845, 20.719178082191775, 25.570776255707756, 32.990867579908667},
+    // 'min_Jp': 33.3692722372,
+    // 'max_Jp': 95}
+    private static final double[][] colorMapJosmViridisBright = {
+            {0.0331179, 0.29975688, 0.57579112},
+            {0.04256739, 0.3028265, 0.57286799},
+            {0.0512467, 0.30584793, 0.57009011},
+            {0.05914659, 0.30882508, 0.5674503},
+            {0.06654831, 0.3117815, 0.5647918},
+            {0.07345228, 0.31469781, 0.56227052},
+            {0.07995739, 0.31757925, 0.55986398},
+            {0.08619278, 0.32044241, 0.55745447},
+            {0.09212195, 0.32327213, 0.55517502},
+            {0.09780928, 0.32607626, 0.55297584},
+            {0.10331033, 0.32886259, 0.55080222},
+            {0.10859491, 0.33162106, 0.54875221},
+            {0.11372563, 0.33436292, 0.54673886},
+            {0.11870231, 0.33708616, 0.54479015},
+            {0.12351267, 0.33978626, 0.54295921},
+            {0.12822783, 0.3424784, 0.541114},
+            {0.13279867, 0.34515022, 0.53938101},
+            {0.13725748, 0.34780851, 0.53770555},
+            {0.14161799, 0.35045603, 0.53606914},
+            {0.14585622, 0.3530865, 0.53454415},
+            {0.15002582, 0.35571293, 0.5330082},
+            {0.15408488, 0.35832466, 0.5315781},
+            {0.15806357, 0.36092928, 0.53018482},
+            {0.16195691, 0.36352554, 0.52884943},
+            {0.16576237, 0.36611275, 0.52758751},
+            {0.16949979, 0.36869662, 0.52634711},
+            {0.1731454, 0.37127046, 0.52520656},
+            {0.17673382, 0.37384485, 0.52406183},
+            {0.18023309, 0.37641026, 0.52302135},
+            {0.18367353, 0.37897678, 0.5219859},
+            {0.18703181, 0.38153698, 0.52104134},
+            {0.19032855, 0.38409867, 0.52011314},
+            {0.19354787, 0.38665632, 0.5192658},
+            {0.19670438, 0.38921652, 0.51843878},
+            {0.19978526, 0.39177424, 0.51769017},
+            {0.20280277, 0.39433623, 0.51695934},
+            {0.20574448, 0.39689659, 0.51631112},
+            {0.20862219, 0.39946359, 0.51567252},
+            {0.21142395, 0.40203013, 0.51511745},
+            {0.21415805, 0.40460435, 0.51457709},
+            {0.21681705, 0.40718098, 0.51410601},
+            {0.21940294, 0.40976427, 0.5136727},
+            {0.22191346, 0.4123542, 0.51328427},
+            {0.22434688, 0.41494912, 0.51295975},
+            {0.22670152, 0.4175556, 0.51265342},
+            {0.22897578, 0.42016834, 0.51241261},
+            {0.23116721, 0.42279102, 0.51221511},
+            {0.23327224, 0.42542553, 0.5120539},
+            {0.23529113, 0.42806929, 0.51195199},
+            {0.23721876, 0.4307259, 0.51189091},
+            {0.23905088, 0.43339672, 0.51186833},
+            {0.24078829, 0.43607984, 0.51190068},
+            {0.24242777, 0.43877648, 0.5119848},
+            {0.24395722, 0.44149191, 0.51209793},
+            {0.24538089, 0.44422266, 0.51226326},
+            {0.24669486, 0.44696981, 0.512479},
+            {0.24789484, 0.44973443, 0.51274365},
+            {0.24897073, 0.45251957, 0.51304809},
+            {0.24992008, 0.45532509, 0.51339708},
+            {0.25074106, 0.45815079, 0.51379462},
+            {0.25142853, 0.46099761, 0.51423996},
+            {0.2519772, 0.46386643, 0.51473252},
+            {0.25238166, 0.46675805, 0.51527187},
+            {0.25263645, 0.46967322, 0.51585774},
+            {0.25273608, 0.47261257, 0.51648993},
+            {0.25267511, 0.47557666, 0.51716828},
+            {0.25244821, 0.47856593, 0.51789267},
+            {0.25205017, 0.4815807, 0.51866293},
+            {0.25147595, 0.48462119, 0.51947882},
+            {0.25072074, 0.48768749, 0.52034},
+            {0.24977992, 0.49077954, 0.52124597},
+            {0.24864914, 0.49389721, 0.52219605},
+            {0.24732429, 0.4970402, 0.52318934},
+            {0.2458015, 0.50020813, 0.5242247},
+            {0.24407712, 0.50340048, 0.52530069},
+            {0.24213937, 0.50661827, 0.52641341},
+            {0.23998809, 0.50986008, 0.52756205},
+            {0.2376243, 0.51312431, 0.5287454},
+            {0.23504515, 0.51641008, 0.52996075},
+            {0.23223599, 0.51971846, 0.53120267},
+            {0.22919943, 0.52304738, 0.53246911},
+            {0.22593842, 0.52639479, 0.53375736},
+            {0.22243635, 0.52976175, 0.53506084},
+            {0.21869708, 0.53314592, 0.53637622},
+            {0.21472177, 0.53654544, 0.53769908},
+            {0.21049097, 0.53996144, 0.53902151},
+            {0.20602332, 0.5433894, 0.54034076},
+            {0.20129189, 0.54683133, 0.54164703},
+            {0.19632014, 0.5502822, 0.54293704},
+            {0.1910817, 0.5537437, 0.54420016},
+            {0.1856016, 0.55721085, 0.54543206},
+            {0.17986279, 0.56068409, 0.5466222},
+            {0.17388472, 0.56415953, 0.54776421},
+            {0.16767592, 0.56763485, 0.54884959},
+            {0.16124118, 0.57110836, 0.54986858},
+            {0.15461572, 0.57457555, 0.55081476},
+            {0.14782653, 0.57803342, 0.55167986},
+            {0.14090518, 0.58147916, 0.55245531},
+            {0.13391472, 0.5849079, 0.5531362},
+            {0.12692017, 0.58831582, 0.55371706},
+            {0.12000191, 0.59169907, 0.55419371},
+            {0.11326013, 0.59505365, 0.55456398},
+            {0.10681409, 0.59837568, 0.55482785},
+            {0.10079543, 0.60166197, 0.55498638},
+            {0.09534887, 0.60490977, 0.55504241},
+            {0.09063347, 0.60811639, 0.55500215},
+            {0.08679049, 0.61128079, 0.55487004},
+            {0.08394854, 0.6144023, 0.55465197},
+            {0.08221537, 0.61748019, 0.55435753},
+            {0.08164325, 0.6205151, 0.55399342},
+            {0.08223013, 0.62350855, 0.55356369},
+            {0.08394439, 0.62646065, 0.55308231},
+            {0.08668611, 0.6293742, 0.55254872},
+            {0.09034668, 0.63225032, 0.55197376},
+            {0.09479378, 0.63509139, 0.55135952},
+            {0.09989897, 0.63789906, 0.55071423},
+            {0.10553908, 0.64067585, 0.55003665},
+            {0.11160448, 0.64342303, 0.54933941},
+            {0.11800283, 0.64614329, 0.54861541},
+            {0.12465323, 0.64883798, 0.54787462},
+            {0.13149053, 0.65150897, 0.54711829},
+            {0.13846531, 0.65415809, 0.5463437},
+            {0.1455335, 0.65678673, 0.54555555},
+            {0.15265709, 0.65939627, 0.54476003},
+            {0.15981518, 0.66198821, 0.54395146},
+            {0.16698676, 0.66456378, 0.54313117},
+            {0.17415531, 0.66712409, 0.54230031},
+            {0.18130458, 0.66967023, 0.54146307},
+            {0.18842545, 0.67220323, 0.54061925},
+            {0.19551341, 0.67472397, 0.53976647},
+            {0.2025629, 0.67723331, 0.53890516},
+            {0.20956984, 0.67973202, 0.53803564},
+            {0.2165314, 0.68222082, 0.53715809},
+            {0.22344573, 0.68470038, 0.53627262},
+            {0.23031175, 0.6871713, 0.53537923},
+            {0.23712903, 0.68963415, 0.53447784},
+            {0.24389765, 0.69208946, 0.53356833},
+            {0.25061808, 0.6945377, 0.53265048},
+            {0.25729111, 0.69697932, 0.53172407},
+            {0.26391778, 0.6994147, 0.53078879},
+            {0.27049933, 0.70184423, 0.52984433},
+            {0.27703712, 0.70426823, 0.52889033},
+            {0.28353264, 0.70668701, 0.52792642},
+            {0.28998746, 0.70910086, 0.52695218},
+            {0.29640321, 0.71151001, 0.52596722},
+            {0.30278152, 0.71391471, 0.5249711},
+            {0.30912407, 0.71631516, 0.52396339},
+            {0.31543254, 0.71871153, 0.52294366},
+            {0.3217086, 0.72110401, 0.52191145},
+            {0.3279539, 0.72349274, 0.52086633},
+            {0.33417008, 0.72587784, 0.51980786},
+            {0.34035875, 0.72825944, 0.5187356},
+            {0.34652147, 0.73063763, 0.51764911},
+            {0.35265864, 0.73301261, 0.51654918},
+            {0.35877137, 0.73538448, 0.51543583},
+            {0.3648628, 0.73775319, 0.51430692},
+            {0.37093438, 0.74011877, 0.51316203},
+            {0.37698751, 0.74248126, 0.51200075},
+            {0.38302357, 0.7448407, 0.51082267},
+            {0.38904388, 0.7471971, 0.5096274},
+            {0.39504973, 0.74955049, 0.50841457},
+            {0.40104082, 0.75190103, 0.5071855},
+            {0.40701899, 0.75424866, 0.50593917},
+            {0.41298655, 0.75659325, 0.50467398},
+            {0.41894464, 0.75893479, 0.50338958},
+            {0.42489434, 0.76127325, 0.50208564},
+            {0.43083671, 0.76360862, 0.50076184},
+            {0.43677259, 0.76594088, 0.4994181},
+            {0.44270136, 0.7682702, 0.49805594},
+            {0.44862605, 0.77059628, 0.49667271},
+            {0.45454756, 0.77291909, 0.49526814},
+            {0.46046679, 0.77523857, 0.49384196},
+            {0.46638456, 0.77755469, 0.4923939},
+            {0.47230148, 0.7798674, 0.49092398},
+            {0.47821759, 0.78217677, 0.48943283},
+            {0.48413494, 0.78448256, 0.48791871},
+            {0.49005423, 0.78678471, 0.48638138},
+            {0.49597616, 0.78908317, 0.48482063},
+            {0.50190137, 0.79137786, 0.48323626},
+            {0.5078303, 0.79366877, 0.48162833},
+            {0.5137638, 0.79595578, 0.47999631},
+            {0.51970278, 0.79823879, 0.47833963},
+            {0.52564777, 0.80051774, 0.47665809},
+            {0.53159931, 0.80279254, 0.47495153},
+            {0.53755788, 0.80506315, 0.47321975},
+            {0.54352447, 0.80732942, 0.47146196},
+            {0.54949945, 0.80959129, 0.46967805},
+            {0.55548322, 0.81184871, 0.4678679},
+            {0.56147617, 0.8141016, 0.46603131},
+            {0.5674787, 0.81634992, 0.46416812},
+            {0.57349149, 0.81859354, 0.46227771},
+            {0.57951582, 0.82083223, 0.46035867},
+            {0.58555114, 0.82306609, 0.45841193},
+            {0.59159777, 0.82529507, 0.45643726},
+            {0.59765599, 0.82751909, 0.45443444},
+            {0.60372607, 0.82973812, 0.45240324},
+            {0.60980907, 0.83195194, 0.45034236},
+            {0.61590608, 0.83416034, 0.44825035},
+            {0.62201604, 0.83636352, 0.44612867},
+            {0.62813915, 0.83856142, 0.443977},
+            {0.6342756, 0.84075401, 0.44179501},
+            {0.64042559, 0.84294124, 0.43958235},
+            {0.64658927, 0.84512308, 0.43733862},
+            {0.65276961, 0.84729891, 0.43505957},
+            {0.65896438, 0.84946917, 0.43274795},
+            {0.66517356, 0.85163387, 0.43040351},
+            {0.67139725, 0.85379299, 0.4280257},
+            {0.67763555, 0.85594651, 0.42561396},
+            {0.68388856, 0.8580944, 0.42316766},
+            {0.69015635, 0.86023667, 0.42068611},
+            {0.69643989, 0.86237309, 0.41816731},
+            {0.70274062, 0.86450334, 0.41560843},
+            {0.70905639, 0.86662792, 0.41301167},
+            {0.71538721, 0.86874683, 0.41037609},
+            {0.72173308, 0.87086011, 0.40770069},
+            {0.72809396, 0.87296778, 0.40498434},
+            {0.7344698, 0.87506988, 0.40222583},
+            {0.74086053, 0.87716647, 0.39942384},
+            {0.74726606, 0.8792576, 0.39657691},
+            {0.75368625, 0.88134336, 0.39368347},
+            {0.76012096, 0.88342383, 0.39074178},
+            {0.76656999, 0.88549913, 0.38774996},
+            {0.77303308, 0.8875694, 0.38470595},
+            {0.77950995, 0.88963477, 0.38160749},
+            {0.78600023, 0.89169545, 0.37845211},
+            {0.79250349, 0.89375165, 0.37523713},
+            {0.79901921, 0.89580363, 0.37195957},
+            {0.80554676, 0.8978517, 0.36861621},
+            {0.8120854, 0.89989622, 0.3652035},
+            {0.81863422, 0.90193761, 0.36171754},
+            {0.82519216, 0.90397637, 0.35815405},
+            {0.83175795, 0.9060131, 0.35450833},
+            {0.83833008, 0.90804849, 0.3507752},
+            {0.84490673, 0.91008337, 0.34694895},
+            {0.85148576, 0.91211872, 0.34302325},
+            {0.85806684, 0.91415505, 0.33898699},
+            {0.86465276, 0.91619201, 0.3348209},
+            {0.87123317, 0.91823316, 0.33052851},
+            {0.87780375, 0.9202804, 0.32609988},
+            {0.88435971, 0.92233593, 0.32152327},
+            {0.89091043, 0.92439784, 0.31675269},
+            {0.89743393, 0.9264737, 0.31180336},
+            {0.9039243, 0.92856651, 0.3066523},
+            {0.91038551, 0.93067656, 0.30124469},
+            {0.91678774, 0.93281453, 0.29559791},
+            {0.92313653, 0.9349809, 0.28963085},
+            {0.92939556, 0.93718902, 0.28335908},
+            {0.93555967, 0.93944353, 0.2766966},
+            {0.94159054, 0.94175935, 0.26963707},
+            {0.94745672, 0.94414992, 0.26213946},
+            {0.95312442, 0.94662987, 0.25415069},
+            {0.9585465, 0.94921781, 0.24566287},
+            {0.96367764, 0.95193147, 0.23667632},
+            {0.96847776, 0.95478608, 0.22720755},
+            {0.97291733, 0.95779215, 0.21729217},
+            {0.97698301, 0.96095356, 0.20697158}
+
+    }; // end of colorMapJosmViridisBright
+
+    // diverging red to blue, designed by http://colorbrewer2.org/
+    private static Color[] colorMapJosmRed2Blue = {
+            new Color(0, 0, 0),
+            new Color(49, 54, 149),
+            new Color(69, 117, 180),
+            new Color(116, 173, 209),
+            new Color(171, 217, 233),
+            new Color(224, 243, 248),
+            new Color(254, 224, 144),
+            new Color(253, 174, 97),
+            new Color(244, 109, 67),
+            new Color(215, 48, 39),
+            new Color(165, 0, 38),
+    };
+
+    // diverging brown to green, designed by http://colorbrewer2.org/
+    private static Color[] colorMapJosmBrown2SeaGreen = {
+            new Color(0, 0, 0),
+            new Color(1, 102, 9),
+            new Color(53, 151, 143),
+            new Color(128, 205, 193),
+            new Color(199, 234, 229),
+            new Color(246, 232, 195),
+            new Color(223, 194, 125),
+            new Color(191, 129, 45),
+            new Color(140, 81, 10)
+    };
+
+    // setup color maps used by heat map
+    private static Color[] heatMapLutColorJosmInferno = createColorFromRawArray(colorMapJosmInfernoBright);
+    private static Color[] heatMapLutColorJosmViridis = createColorFromRawArray(colorMapJosmViridisBright);
+    private static Color[] heatMapLutColorJosmBrown2Sea = createColorLut(colorMapJosmBrown2SeaGreen);
+    private static Color[] heatMapLutColorJosmRed2Blue = createColorLut(colorMapJosmRed2Blue);
+
+    // user defined heatmap color
+    private Color[] heatMapLutUserColor = createColorLut(Color.BLACK, Color.WHITE);
+
+    // heat map color in use
+    private Color[] heatMapLutColor = null;
+
     private void setupColors() {
         hdopAlpha = Main.pref.getInteger("hdop.color.alpha", -1);
         velocityScale = ColorScale.createHSBScale(256);
@@ -111,6 +721,8 @@
         hdopScale = ColorScale.createHSBScale(256).makeReversed().addTitle(tr("HDOP"));
         dateScale = ColorScale.createHSBScale(256).addTitle(tr("Time"));
         directionScale = ColorScale.createCyclicScale(256).setIntervalCount(4).addTitle(tr("Direction"));
+        heatMapLutColor = heatMapLutUserColor;
+
         systemOfMeasurementChanged(null, null);
     }
 
@@ -127,7 +739,7 @@
      * Different color modes
      */
     public enum ColorMode {
-        NONE, VELOCITY, HDOP, DIRECTION, TIME;
+        NONE, VELOCITY, HDOP, DIRECTION, TIME, HEATMAP;
 
         static ColorMode fromIndex(final int index) {
             return values()[index];
@@ -198,6 +810,7 @@
         forceLines = Main.pref.getBoolean("draw.rawgps.lines.force", spec, false);
         direction = Main.pref.getBoolean("draw.rawgps.direction", spec, false);
         lineWidth = Main.pref.getInteger("draw.rawgps.linewidth", spec, 0);
+        alphaLines = Main.pref.getBoolean("draw.rawgps.lines.alpha-blend", spec, false);
 
         if (!data.fromServer) {
             maxLineLength = Main.pref.getInteger("draw.rawgps.max-line-length.local", spec, -1);
@@ -219,6 +832,11 @@
         minTrackDurationForTimeColoring = Main.pref.getInteger("draw.rawgps.date-coloring-min-dt", 60);
         largePointAlpha = Main.pref.getInteger("draw.rawgps.large.alpha", -1) & 0xFF;
 
+        // get heatmap parameters
+        heatMapEnabled = Main.pref.getBoolean("draw.rawgps.heatmap.enabled", spec, false);
+        heatMapDrawExtraLine = Main.pref.getBoolean("draw.rawgps.heatmap.line-extra", spec, false);
+        heatMapDrawColorTableIdx = Main.pref.getInteger("draw.rawgps.heatmap.colormap", specName(layerName), 0);
+
         neutralColor = getColor(layerName, true);
         velocityScale.setNoDataColor(neutralColor);
         dateScale.setNoDataColor(neutralColor);
@@ -230,6 +848,8 @@
 
     public void drawAll(Graphics2D g, MapView mv, List<WayPoint> visibleSegments) {
 
+        final long timeStart = System.currentTimeMillis();
+
         checkCache();
 
         // STEP 2b - RE-COMPUTE CACHE DATA *********************
@@ -237,8 +857,14 @@
             calculateColors();
         }
 
-        Stroke storedStroke = g.getStroke();
+        fixColors(visibleSegments);
+
+        // backup the environment
+        Composite oldComposite = g.getComposite();
+        Stroke oldStroke = g.getStroke();
+        Paint oldPaint = g.getPaint();
 
+        // set hints for the render
         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
             Main.pref.getBoolean("mappaint.gpx.use-antialiasing", false) ?
                     RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
@@ -246,12 +872,55 @@
         if (lineWidth != 0) {
             g.setStroke(new BasicStroke(lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
         }
-        fixColors(visibleSegments);
-        drawLines(g, mv, visibleSegments);
+
+        // global enabled or select via color
+        boolean useHeatMap = heatMapEnabled || ColorMode.HEATMAP == colored;
+
+        // default global alpha level
+        float layerAlpha = 1.00f;
+
+        // extract current alpha blending value
+        if (oldComposite instanceof AlphaComposite) {
+            layerAlpha = ((AlphaComposite) oldComposite).getAlpha();
+        }
+
+        // use heatmap background layer
+        if (useHeatMap) {
+            drawHeatMap(g, mv, visibleSegments);
+        } else {
+            // use normal line style or alpha-blending lines
+            if (!alphaLines) {
+                drawLines(g, mv, visibleSegments);
+            } else {
+                drawLinesAlpha(g, mv, visibleSegments, layerAlpha);
+            }
+        }
+
+        // override global alpha settings (smooth overlay)
+        if (alphaLines || useHeatMap) {
+            g.setComposite(AlphaComposite.SrcOver.derive(0.25f * layerAlpha));
+        }
+
+        // normal overlays
         drawArrows(g, mv, visibleSegments);
         drawPoints(g, mv, visibleSegments);
-        if (lineWidth != 0) {
-            g.setStroke(storedStroke);
+
+        // restore environment
+        g.setPaint(oldPaint);
+        g.setStroke(oldStroke);
+        g.setComposite(oldComposite);
+
+        // show some debug info
+        if (Main.isDebugEnabled() && !visibleSegments.isEmpty()) {
+            final long timeDiff = System.currentTimeMillis() - timeStart;
+
+            Main.debug("gpxdraw::draw takes " +
+                         Utils.getDurationString(timeDiff) +
+                         "(" +
+                         "segments= " + visibleSegments.size() +
+                         ", per 10000 = " + Utils.getDurationString(10000 * timeDiff / visibleSegments.size()) +
+                         ")"
+              );
         }
     }
 
@@ -391,6 +1060,35 @@
             }
         }
 
+        // heat mode
+        if (ColorMode.HEATMAP == colored) {
+
+            // generate new user color map
+            heatMapLutUserColor = createColorLut(Color.BLACK, neutralColor.darker(),
+                                                 neutralColor, neutralColor.brighter(), Color.WHITE);
+
+            // decide what, keep order is sync with setting on GUI
+            Color[][] lut = {
+                    heatMapLutUserColor,
+                    heatMapLutColorJosmInferno,
+                    heatMapLutColorJosmViridis,
+                    heatMapLutColorJosmBrown2Sea,
+                    heatMapLutColorJosmRed2Blue,
+            };
+
+            // select by index
+            if (heatMapDrawColorTableIdx < lut.length) {
+                heatMapLutColor = lut[ heatMapDrawColorTableIdx ];
+            } else {
+                // fallback
+                heatMapLutColor = heatMapLutUserColor;
+            }
+
+            // force redraw of image
+            heatMapCacheVisibleSegments = 0;
+
+        } // end of if (ColorMode.HEATMAP == colored)
+
         computeCacheInSync = true;
     }
 
@@ -550,6 +1248,374 @@
         } // end if large
     }
 
+    // draw GPS a lines by using alpha blending
+    private void drawLinesAlpha(Graphics2D g, MapView mv, List<WayPoint> visibleSegments, float layerAlpha) {
+
+        // early abort
+        if (lineWidth < 1) return;
+
+        // 1st. backup the paint environment ----------------------------------
+        Composite oldComposite = g.getComposite();
+        Stroke oldStroke = g.getStroke();
+        Paint oldPaint = g.getPaint();
+
+        // 2nd. determine current scale factors -------------------------------
+
+        // cache scale of view
+        final double zoomScale = mv.getScale();
+
+        // 3rd. determine current paint parameters -----------------------------
+
+        // alpha value is based on zoom and line with combined with global layer alpha
+        float theLineAlpha = Math.min(Math.max((0.50f/(float) zoomScale)/(lineWidth + 1), 0.001f), 0.50f) * layerAlpha;
+        final int theLineWith = (int) (lineWidth / zoomScale) + 1;
+
+        // 4th setup virtual paint area ----------------------------------------
+
+        // set line format and alpha channel for all overlays (more lines -> few overlap -> more transparency)
+        g.setStroke(new BasicStroke(theLineWith, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+        g.setComposite(AlphaComposite.SrcOver.derive(theLineAlpha));
+
+        // last used / calculated entries
+        Point lastPaintPnt = null;
+
+        // 5th draw the layer ---------------------------------------------------
+
+        // for all points
+        for (WayPoint trkPnt : visibleSegments) {
+
+            // transform coordinates
+            final Point paintPnt = mv.getPoint(trkPnt.getEastNorth());
+
+            // skip single points
+            if (lastPaintPnt != null && trkPnt.drawLine && !lastPaintPnt.equals(paintPnt)) {
+
+                // set different color
+                g.setColor(trkPnt.customColoring);
+
+                // draw it
+                g.drawLine(lastPaintPnt.x, lastPaintPnt.y, paintPnt.x, paintPnt.y);
+
+            } // end of if()
+
+            lastPaintPnt = paintPnt;
+
+        } // end of for()
+
+        // @last restore modified paint environment -----------------------------
+        g.setPaint(oldPaint);
+        g.setStroke(oldStroke);
+        g.setComposite(oldComposite);
+    }
+
+    // creates a linear distributed colormap by linear blending between colors
+    protected static Color[] createColorLut(Color... colors) {
+
+        // number of lookup entries
+        int tableSize = 256;
+
+        // create image an paint object
+        BufferedImage img = new BufferedImage(tableSize, 1, BufferedImage.TYPE_INT_RGB);
+        Graphics2D g = img.createGraphics();
+
+        float[] fract = new float[ colors.length ];
+
+        // distribute fractions (define position of color in map)
+        for (int i = 0; i < colors.length; ++i) {
+            fract[i] = i * (1.0f / colors.length);
+        }
+
+        // draw the gradient map
+        LinearGradientPaint gradient = new LinearGradientPaint(0, 0, tableSize, 1, fract, colors,
+                                                               MultipleGradientPaint.CycleMethod.NO_CYCLE);
+        g.setPaint(gradient);
+        g.fillRect(0, 0, tableSize, 1);
+        g.dispose();
+
+        // access it via raw interface
+        final Raster imgRaster = img.getData();
+
+        // the pixel storage
+        int[] pixel = new int[1];
+
+        Color[] colorTable = new Color[tableSize];
+
+        // map the range 0..255 to 0..pi/2
+        final double mapTo90Deg = Math.PI / 2.0 / 255.0;
+
+        // create the lookup table
+        for (int i = 0; i < tableSize; i++) {
+
+            // get next single pixel
+            imgRaster.getDataElements((int) (i * (double) img.getWidth() / tableSize), 0, pixel);
+
+            // get color and map
+            Color c = new Color(pixel[0]);
+
+            // smooth alpha like sin curve
+            int alpha = (int) (Math.sin(i * mapTo90Deg) * 255);
+
+            // alpha with pre-offset, first color -> full transparent
+            alpha = i > 0 ? (75 + alpha) : 0;
+
+            // shrink to maximum bound
+            if (alpha > 255) {
+                alpha = 255;
+            }
+
+            // increase transparency for higher values ( avoid big saturation )
+            if (i > 240 && 255 == alpha) {
+                alpha -= (i - 240);
+            }
+
+            // fill entry in table, assign a alpha value
+            colorTable[i] = new Color(c.getRed(), c.getGreen(), c.getBlue(), alpha);
+        }
+
+        // transform into lookup table
+        return colorTable;
+
+    } // end of createColorLut()
+
+    // creates a colormap by using a static color map with 1..n colors (RGB 0.0 ..1.0)
+    protected static Color[] createColorFromRawArray(double[][] data) {
+
+        // create the array
+        Color[] color = new Color[ data.length ];
+
+        for (int k = 0; k < data.length; k++) {
+           // cast an map to linear array
+           color[k] = new Color((float) data[k][0], (float) data[k][1], (float) data[k][2]);
+        }
+
+        // forward
+        return createColorLut(color);
+
+    } // end of createColorFromRawArray()
+
+    // collect and draw GPS segments and displays a heat-map
+    private void drawHeatMap(Graphics2D g, MapView mv, List<WayPoint> visibleSegments) {
+
+        // early abort
+        if (lineWidth < 1) return;
+
+        long timeStart;
+
+        // 1st setup virtual paint area ----------------------------------------
+
+        // get bounds of screen image and projection
+        final Rectangle screenBounds = g.getDeviceConfiguration().getBounds();
+
+        // cache scale of view
+        final double zoomScale = mv.getScale();
+
+        if (Main.isDebugEnabled()) {
+            Main.debug("gpxdraw::heat : bound = " + screenBounds.width + "x" + screenBounds.height);
+        }
+
+        // HACK: sometime screen bounds does not return valid values when picture is shifted
+        // therefore we use a bigger area to avoid missing parts of image
+        screenBounds.width = screenBounds.width * 3 / 2;
+        screenBounds.height = screenBounds.height * 3 / 2;
+
+        // new image buffer needed
+        boolean imageSetup = !heatMapCacheScreenBounds.equals(screenBounds) || null == heatMapImgGray;
+
+        // screen bounds changed, need new image buffer ?
+        if (imageSetup) {
+            timeStart = System.currentTimeMillis();
+
+            // we would use a "pure" grayscale image, but there is not efficient way to map gray scale values to RGB)
+            heatMapImgGray = new BufferedImage(screenBounds.width, screenBounds.height, BufferedImage.TYPE_INT_ARGB);
+
+            heatMapGraph2d = heatMapImgGray.createGraphics();
+            heatMapGraph2d.setBackground(new Color(0, 0, 0, 255));
+            heatMapGraph2d.setColor(Color.WHITE);
+
+            // cache it
+            heatMapCacheScreenBounds = screenBounds;
+
+            // show some debug info
+            if (Main.isDebugEnabled()) {
+                Main.debug("gpxdraw::heat : new buffer takes " + Utils.getDurationString(System.currentTimeMillis() - timeStart));
+            }
+        }
+
+        // shortcuts
+        final BufferedImage imgG = heatMapImgGray;
+        final Graphics2D gB = heatMapGraph2d;
+
+        // 2nd. determine current scale factors -------------------------------
+
+        // alpha combines both values, therefore the foreground shall be lighter
+        final float lineAlphaB = Math.min(Math.max((0.40f/(float) zoomScale)/(lineWidth + 1), 0.001f), 0.50f);
+        final float lineAlphaF = lineAlphaB / 1.5f;
+
+        // derive draw parameters
+        final Composite fC = AlphaComposite.SrcOver.derive(lineAlphaF);
+        final Composite bC = AlphaComposite.SrcOver.derive(lineAlphaB);
+
+        // the line width (foreground: draw extra small footprint line of track)
+        final int lineWidthB = Math.max((int) (lineWidth / zoomScale) + 1, 2);
+        final int lineWidthF = lineWidthB > 2 ? lineWidth - 1 : 0;
+
+        final Stroke bS = new BasicStroke(lineWidthB, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+        final Stroke fS = new BasicStroke(lineWidthF, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
+
+        // set initial values
+        gB.setStroke(bS); gB.setComposite(bC);
+
+        if (Main.isDebugEnabled()) {
+            Main.debug("gpxdraw::heat : GPX segments = " + visibleSegments.size());
+            Main.debug("gpxdraw::heat : zoomscale = " + zoomScale);
+            Main.debug("gpxdraw::heat : f-line-alpha = " + lineAlphaF);
+            Main.debug("gpxdraw::heat : b-line-alpha = " + lineAlphaB);
+            Main.debug("gpxdraw::heat : f-line-width = " + lineWidthF);
+            Main.debug("gpxdraw::heat : b-line-with = " + lineWidthB);
+        }
+
+        // 3rd Calculate the heat map data by draw GPX traces with alpha value ----------
+
+        timeStart = System.currentTimeMillis();
+
+        // clear data storage
+        heatMapPolyX.clear(); heatMapPolyY.clear();
+
+        // dummy list
+        List<WayPoint> listSegm = new LinkedList<>();
+
+        // recalculation of image needed
+        final boolean imageRecalc = heatMapCacheVisibleSegments != visibleSegments.size() ||
+                                    heatMapCacheZoomScale != zoomScale ||
+                                    heatMapCacheLineWith != lineWidth;
+
+        // need re-generation of gray image ?
+        if (imageSetup || imageRecalc) {
+
+            // clear background
+            gB.clearRect(0, 0, heatMapImgGray.getWidth(), heatMapImgGray.getHeight());
+
+            // use real data
+            listSegm = visibleSegments;
+
+            // remember
+            heatMapCacheVisibleSegments = visibleSegments.size();
+            heatMapCacheZoomScale = zoomScale;
+            heatMapCacheLineWith = lineWidth;
+        }
+
+        // for all points, draw single lines by using optimize drawing
+        for (WayPoint trkPnt : listSegm) {
+
+            // something to paint or color changed (new segment needed, decrease performance ;-()
+            if (!trkPnt.drawLine && !heatMapPolyX.isEmpty()) {
+
+                // convert to primitive type
+                final int[] polyXArr = heatMapPolyX.stream().mapToInt(Integer::intValue).toArray();
+                final int[] polyYArr = heatMapPolyY.stream().mapToInt(Integer::intValue).toArray();
+
+                // a.) draw background
+                gB.drawPolyline(polyXArr, polyYArr, polyXArr.length);
+
+                // b.) draw extra foreground
+                if (heatMapDrawExtraLine && lineWidthF > 0) {
+
+                    gB.setStroke(fS); gB.setComposite(fC);
+                    gB.drawPolyline(polyXArr, polyYArr, polyXArr.length);
+                    gB.setStroke(bS); gB.setComposite(bC);
+                }
+
+                // drop used pints
+                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());
+            }
+
+        } // end of for()
+
+        // show some debug info
+        if (Main.isDebugEnabled()) {
+            Main.debug("gpxdraw::heat : gray-image takes " + Utils.getDurationString(System.currentTimeMillis() - timeStart));
+        }
+
+        // 4th. Draw data on target layer, map data via color lookup table --------------
+
+        timeStart = System.currentTimeMillis();
+
+        final int[] imgPixels = ((DataBufferInt) imgG.getRaster().getDataBuffer()).getData();
+
+        // samples offset and bounds are scaled with line width derived from zoom level
+        final int offX = Math.max(1, lineWidthB / 2);
+        final int offY = Math.max(1, lineWidthB / 2);
+
+        final int maxPixelX = imgG.getWidth();
+        final int maxPixelY = imgG.getHeight();
+
+        int lastPixelY = 0; int lastPixelColor = 0;
+
+        // resample gray scale image with line linear weight of next sample in line
+        // process each line and draw pixels / rectangles with same color with one operations
+        for (int x = 0; x < maxPixelX; x += offX) {
+            for (int y = 0; y < maxPixelY; y += offY) {
+
+                int thePixelColor = 0;
+
+                // sample the image (it is gray scale)
+                int offset = (x * maxPixelX) + y;
+
+                // merge next pixels of window of line
+                for (int k = 0; k < offX && offset + k < imgPixels.length; k++) {
+                    thePixelColor += imgPixels[offset+k] & 0xFF;
+                }
+
+                // mean value
+                thePixelColor /= offX;
+
+                // 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) {
+
+                        // gray to RGB mapping
+                        g.setColor(heatMapLutColor[ lastPixelColor ]);
+
+                        // start point for draw (
+                        int yN = lastPixelY > 0 ? lastPixelY - 1 : y;
+
+                        // box from from last Y pixel to current pixel
+                        if (offX < lineWidth + 2) {
+                            g.fillRect(yN, x, offY + y - yN, offX);
+                        } else {
+                            g.drawRect(yN, x, offY + y - yN, offX);
+                        }
+                    }
+                    // restart detection
+                    lastPixelY = y; lastPixelColor = thePixelColor;
+                }
+            }
+
+        } // end of for()
+
+        // show some debug info
+        if (Main.isDebugEnabled()) {
+            Main.debug("gpxdraw::heat : color-image takes " + Utils.getDurationString(System.currentTimeMillis() - timeStart));
+        }
+
+    } // end of drawHeatMap()
+
     private void fixColors(List<WayPoint> visibleSegments) {
         for (WayPoint trkPnt : visibleSegments) {
             if (trkPnt.customColoring == null) {
@@ -564,13 +1630,16 @@
     private void checkCache() {
         if ((computeCacheMaxLineLengthUsed != maxLineLength) || (!neutralColor.equals(computeCacheColorUsed))
                 || (computeCacheColored != colored) || (computeCacheColorTracksTune != colorTracksTune)
-                || (computeCacheColorDynamic != colorModeDynamic)) {
+                || (computeCacheColorDynamic != colorModeDynamic)
+                || (computeCacheHeatMapDrawColorTableIdx != heatMapDrawColorTableIdx)
+      ) {
             computeCacheMaxLineLengthUsed = maxLineLength;
             computeCacheInSync = false;
             computeCacheColorUsed = neutralColor;
             computeCacheColored = colored;
             computeCacheColorTracksTune = colorTracksTune;
             computeCacheColorDynamic = colorModeDynamic;
+            computeCacheHeatMapDrawColorTableIdx = heatMapDrawColorTableIdx;
         }
     }
 
@@ -580,6 +1649,10 @@
 
     public void drawColorBar(Graphics2D g, MapView mv) {
         int w = mv.getWidth();
+
+        // set do default
+        g.setComposite(AlphaComposite.SrcOver.derive(1.00f));
+
         if (colored == ColorMode.HDOP) {
             hdopScale.drawColorBar(g, w-30, 50, 20, 100, 1.0);
         } else if (colored == ColorMode.VELOCITY) {
Index: src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java
===================================================================
--- src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java	(revision 11427)
+++ src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java	(working copy)
@@ -55,9 +55,12 @@
     private final JRadioButton colorTypeDirection = new JRadioButton(tr("Direction (red = west, yellow = north, green = east, blue = south)"));
     private final JRadioButton colorTypeDilution = new JRadioButton(tr("Dilution of Position (red = high, green = low, if available)"));
     private final JRadioButton colorTypeTime = new JRadioButton(tr("Track date"));
+    private final JRadioButton colorTypeHeatMap = new JRadioButton(tr("Heat Map (dark = few tracks, bright = many tracks)"));
     private final JRadioButton colorTypeNone = new JRadioButton(tr("Single Color (can be customized for named layers)"));
     private final JRadioButton colorTypeGlobal = new JRadioButton(tr("Use global settings"));
     private final JosmComboBox<String> colorTypeVelocityTune = new JosmComboBox<>(new String[] {tr("Car"), tr("Bicycle"), tr("Foot")});
+    private final JosmComboBox<String> colorTypeHeatMapTune = new JosmComboBox<>(new String[] {tr("User"), tr("Inferno"), tr("Viridis"),
+                                                                                 tr("Wood"), tr("Heat")});
     private final JCheckBox makeAutoMarkers = new JCheckBox(tr("Create markers when reading GPX"));
     private final JCheckBox drawGpsArrows = new JCheckBox(tr("Draw Direction Arrows"));
     private final JCheckBox drawGpsArrowsFast = new JCheckBox(tr("Fast drawing (looks uglier)"));
@@ -68,6 +71,7 @@
     private final JosmComboBox<String> audioWaypointLabel = new JosmComboBox<>(LABEL_PATTERN_DESC);
     private final JosmTextField audioWaypointLabelPattern = new JosmTextField();
     private final JCheckBox useGpsAntialiasing = new JCheckBox(tr("Smooth GPX graphics (antialiasing)"));
+    private final JCheckBox drawLineWithAlpha = new JCheckBox(tr("Draw with Opacity (alpha blending) "));
 
     private String layerName;
     private final boolean local; // flag to display LocalOnly checkbox
@@ -179,16 +183,16 @@
             drawGpsArrowsMinDist.setEnabled(drawGpsArrows.isSelected() && drawGpsArrows.isEnabled());
         });
         drawGpsArrows.setToolTipText(tr("Draw direction arrows for lines, connecting GPS points."));
-        add(drawGpsArrows, GBC.eop().insets(40, 0, 0, 0));
+        add(drawGpsArrows, GBC.eop().insets(20, 0, 0, 0));
 
         // drawGpsArrowsFast
         drawGpsArrowsFast.setToolTipText(tr("Draw the direction arrows using table lookups instead of complex math."));
-        add(drawGpsArrowsFast, GBC.eop().insets(60, 0, 0, 0));
+        add(drawGpsArrowsFast, GBC.eop().insets(40, 0, 0, 0));
         ExpertToggleAction.addVisibilitySwitcher(drawGpsArrowsFast);
 
         // drawGpsArrowsMinDist
         drawGpsArrowsMinDist.setToolTipText(tr("Do not draw arrows if they are not at least this distance away from the last one."));
-        add(new JLabel(tr("Minimum distance (pixels)")), GBC.std().insets(60, 0, 0, 0));
+        add(new JLabel(tr("Minimum distance (pixels)")), GBC.std().insets(40, 0, 0, 0));
         add(drawGpsArrowsMinDist, GBC.eol().fill(GBC.HORIZONTAL).insets(5, 0, 0, 5));
 
         // hdopCircleGpsPoints
@@ -210,6 +214,11 @@
         add(useGpsAntialiasing, GBC.eop().insets(20, 0, 0, 0));
         ExpertToggleAction.addVisibilitySwitcher(useGpsAntialiasing);
 
+        // alpha blending
+        drawLineWithAlpha.setToolTipText(tr("Apply dynamic alpha-blending and adjust width based on zoom level for all GPX lines."));
+        add(drawLineWithAlpha, GBC.eop().insets(20, 0, 0, 0));
+        ExpertToggleAction.addVisibilitySwitcher(drawLineWithAlpha);
+
         // colorTracks
         ButtonGroup colorGroup = new ButtonGroup();
         if (layerName != null) {
@@ -220,11 +229,18 @@
         colorGroup.add(colorTypeDirection);
         colorGroup.add(colorTypeDilution);
         colorGroup.add(colorTypeTime);
+        colorGroup.add(colorTypeHeatMap);
 
         colorTypeVelocity.addChangeListener(e -> {
             colorTypeVelocityTune.setEnabled(colorTypeVelocity.isSelected());
             colorDynamic.setEnabled(colorTypeVelocity.isSelected() || colorTypeDilution.isSelected());
         });
+
+        colorTypeHeatMap.addChangeListener(e -> {
+            colorTypeHeatMapTune.setEnabled(colorTypeHeatMap.isSelected());
+            colorDynamic.setEnabled(false);
+        });
+
         colorTypeDilution.addChangeListener(e -> colorDynamic.setEnabled(colorTypeVelocity.isSelected() || colorTypeDilution.isSelected()));
 
         colorTypeNone.setToolTipText(tr("All points and track segments will have the same color. Can be customized in Layer Manager."));
@@ -233,10 +249,13 @@
         colorTypeDilution.setToolTipText(
                 tr("Colors points and track segments by dilution of position (HDOP). Your capture device needs to log that information."));
         colorTypeTime.setToolTipText(tr("Colors points and track segments by its timestamp."));
+        colorTypeHeatMap.setToolTipText(tr("Collected points and track segments for a position and displayed as heat map."));
 
         // color Tracks by Velocity Tune
         colorTypeVelocityTune.setToolTipText(tr("Allows to tune the track coloring for different average speeds."));
 
+        colorTypeHeatMapTune.setToolTipText(tr("Selects the color schema for heat map."));
+
         add(Box.createVerticalGlue(), GBC.eol().insets(0, 20, 0, 0));
 
         add(new JLabel(tr("Track and Point Coloring")), GBC.eol().insets(20, 0, 0, 0));
@@ -249,6 +268,9 @@
         add(colorTypeDirection, GBC.eol().insets(40, 0, 0, 0));
         add(colorTypeDilution, GBC.eol().insets(40, 0, 0, 0));
         add(colorTypeTime, GBC.eol().insets(40, 0, 0, 0));
+        add(colorTypeHeatMap, GBC.std().insets(40, 0, 0, 0));
+        add(colorTypeHeatMapTune, GBC.eop().insets(5, 0, 0, 5));
+
         ExpertToggleAction.addVisibilitySwitcher(colorTypeDirection);
         ExpertToggleAction.addVisibilitySwitcher(colorTypeDilution);
 
@@ -315,6 +337,7 @@
         drawRawGpsMaxLineLengthLocal.setText(Integer.toString(Main.pref.getInteger("draw.rawgps.max-line-length.local", layerName, -1)));
         drawRawGpsMaxLineLength.setText(Integer.toString(Main.pref.getInteger("draw.rawgps.max-line-length", layerName, 200)));
         drawLineWidth.setText(Integer.toString(Main.pref.getInteger("draw.rawgps.linewidth", layerName, 0)));
+        drawLineWithAlpha.setSelected(Main.pref.getBoolean("draw.rawgps.lines.alpha-blend", layerName, false));
         forceRawGpsLines.setSelected(Main.pref.getBoolean("draw.rawgps.lines.force", layerName, false));
         drawGpsArrows.setSelected(Main.pref.getBoolean("draw.rawgps.direction", layerName, false));
         drawGpsArrowsFast.setSelected(Main.pref.getBoolean("draw.rawgps.alternatedirection", layerName, false));
@@ -322,6 +345,7 @@
         hdopCircleGpsPoints.setSelected(Main.pref.getBoolean("draw.rawgps.hdopcircle", layerName, false));
         largeGpsPoints.setSelected(Main.pref.getBoolean("draw.rawgps.large", layerName, false));
         useGpsAntialiasing.setSelected(Main.pref.getBoolean("mappaint.gpx.use-antialiasing", false));
+
         drawRawGpsLinesActionListener.actionPerformed(null);
 
         if (layerName != null && Main.pref.get("draw.rawgps.colors."+layerName).isEmpty()) {
@@ -336,11 +360,16 @@
             case 2: colorTypeDilution.setSelected(true); break;
             case 3: colorTypeDirection.setSelected(true); break;
             case 4: colorTypeTime.setSelected(true); break;
+            case 5: colorTypeHeatMap.setSelected(true); break;
             default: Main.warn("Unknown color type: " + colorType);
             }
             int ccts = Main.pref.getInteger("draw.rawgps.colorTracksTune", layerName, 45);
             colorTypeVelocityTune.setSelectedIndex(ccts == 10 ? 2 : (ccts == 20 ? 1 : 0));
             colorTypeVelocityTune.setEnabled(colorTypeVelocity.isSelected() && colorTypeVelocity.isEnabled());
+
+            colorTypeHeatMapTune.setSelectedIndex(Main.pref.getInteger("draw.rawgps.heatmap.colormap", layerName, 0));
+            colorTypeHeatMapTune.setEnabled(colorTypeHeatMap.isSelected() && colorTypeHeatMap.isEnabled());
+
             colorDynamic.setSelected(Main.pref.getBoolean("draw.rawgps.colors.dynamic", layerName, false));
             colorDynamic.setEnabled(colorTypeVelocity.isSelected() || colorTypeDilution.isSelected());
         }
@@ -385,6 +414,8 @@
         Main.pref.put("draw.rawgps.hdopcircle"+layerNameDot, hdopCircleGpsPoints.isSelected());
         Main.pref.put("draw.rawgps.large"+layerNameDot, largeGpsPoints.isSelected());
         Main.pref.put("draw.rawgps.linewidth"+layerNameDot, drawLineWidth.getText());
+        Main.pref.put("draw.rawgps.lines.alpha-blend"+layerNameDot, drawLineWithAlpha.isSelected());
+
         Main.pref.put("mappaint.gpx.use-antialiasing", useGpsAntialiasing.isSelected());
 
         TemplateEntryProperty.forMarker(layerName).put(waypointLabelPattern.getText());
@@ -403,12 +434,17 @@
             Main.pref.putInteger("draw.rawgps.colors"+layerNameDot, 3);
         } else if (colorTypeTime.isSelected()) {
             Main.pref.putInteger("draw.rawgps.colors"+layerNameDot, 4);
+        } else if (colorTypeHeatMap.isSelected()) {
+            Main.pref.putInteger("draw.rawgps.colors"+layerNameDot, 5);
         } else {
             Main.pref.putInteger("draw.rawgps.colors"+layerNameDot, 0);
         }
         Main.pref.put("draw.rawgps.colors.dynamic"+layerNameDot, colorDynamic.isSelected());
         int ccti = colorTypeVelocityTune.getSelectedIndex();
         Main.pref.putInteger("draw.rawgps.colorTracksTune"+layerNameDot, ccti == 2 ? 10 : (ccti == 1 ? 20 : 45));
+
+        Main.pref.putInteger("draw.rawgps.heatmap.colormap"+layerNameDot, colorTypeHeatMapTune.getSelectedIndex());
+
         return false;
     }
 
