Index: src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java
===================================================================
--- src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java	(revision 14953)
+++ src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java	(working copy)
@@ -7,6 +7,8 @@
 import java.awt.geom.Area;
 import java.awt.geom.Path2D;
 import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collection;
 
 import org.openstreetmap.josm.actions.DownloadAlongAction;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -18,6 +20,7 @@
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.gui.help.HelpUtil;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -50,6 +53,36 @@
         this.data = data;
     }
 
+    /**
+     * Calculate list of points between two given points so that the distance between two consecutive points is below a limit.
+     * @param p1 first point or null
+     * @param p2 second point (must not be null)
+     * @param bufferDist the maximum distance
+     * @return a list of points with at least one point (p2) and maybe more.
+     */
+    private static Collection<? extends LatLon> calcBetween(LatLon p1, LatLon p2, double bufferDist) {
+        ArrayList<LatLon> intermediateNodes = new ArrayList<>();
+        intermediateNodes.add(p2);
+        if (p1 != null && p2.greatCircleDistance(p1) > bufferDist) {
+            Double d = p2.greatCircleDistance(p1) / bufferDist;
+            int nbNodes = d.intValue();
+            if (Logging.isDebugEnabled()) {
+                Logging.debug(tr("{0} intermediate nodes to download.", nbNodes));
+                Logging.debug(tr("between {0} {1} and {2} {3}", p2.lat(), p2.lon(), p1.lat(), p1.lon()));
+            }
+            double latStep = (p2.lat() - p1.lat()) / (nbNodes + 1);
+            double lonStep = (p2.lon() - p1.lon()) / (nbNodes + 1);
+            for (int i = 1; i <= nbNodes; i++) {
+                LatLon intermediate = new LatLon(p1.lat() + i * latStep, p1.lon() + i * lonStep);
+                intermediateNodes.add(intermediate);
+                if (Logging.isTraceEnabled()) {
+                    Logging.trace(tr("  adding {0} {1}", intermediate.lat(), intermediate.lon()));
+                }
+            }
+        }
+        return intermediateNodes;
+    }
+
     PleaseWaitRunnable createTask() {
         final DownloadAlongPanel panel = new DownloadAlongPanel(
                 PREF_DOWNLOAD_ALONG_TRACK_OSM, PREF_DOWNLOAD_ALONG_TRACK_GPS,
@@ -100,7 +133,7 @@
         final double bufferX = bufferY / scale;
         final int totalTicks = latcnt;
         // guess if a progress bar might be useful.
-        final boolean displayProgress = totalTicks > 200_000 && bufferY < 0.01;
+        final boolean displayProgress = totalTicks > 20_000 && bufferY < 0.01;
 
         class CalculateDownloadArea extends PleaseWaitRunnable {
 
@@ -129,7 +162,7 @@
                     return;
                 }
                 confirmAndDownloadAreas(new Area(path), maxArea, panel.isDownloadOsmData(), panel.isDownloadGpxData(),
-                        tr("Download from OSM along this track"), progressMonitor);
+                        tr("Download from OSM along this track"), NullProgressMonitor.INSTANCE);
             }
 
             /**
@@ -142,22 +175,6 @@
                 }
             }
 
-            /**
-             * calculate area for single, given way point and return new LatLon if the
-             * way point has been used to modify the area.
-             */
-            private LatLon calcAreaForWayPoint(WayPoint p, LatLon previous) {
-                tick();
-                LatLon c = p.getCoor();
-                if (previous == null || c.greatCircleDistance(previous) > bufferDist) {
-                    // we add a buffer around the point.
-                    r.setRect(c.lon() - bufferX, c.lat() - bufferY, 2 * bufferX, 2 * bufferY);
-                    path.append(r, false);
-                    return c;
-                }
-                return previous;
-            }
-
             @Override
             protected void realRun() {
                 progressMonitor.setTicksCount(totalTicks);
@@ -166,15 +183,19 @@
                  * points that lie closer to the previous point than the given buffer size because
                  * otherwise this operation takes ages.
                  */
-                LatLon previous = null;
                 if (near == NEAR_TRACK || near == NEAR_BOTH) {
                     for (GpxTrack trk : data.tracks) {
                         for (GpxTrackSegment segment : trk.getSegments()) {
+                            LatLon previous = null;
                             for (WayPoint p : segment.getWayPoints()) {
-                                if (cancel) {
-                                    return;
+                                tick();
+                                LatLon c = p.getCoor();
+                                for (LatLon d : calcBetween(previous, c, bufferDist)) {
+                                    // we add a buffer around the point.
+                                    r.setRect(d.lon() - bufferX, d.lat() - bufferY, 2 * bufferX, 2 * bufferY);
+                                    path.append(r, false);
                                 }
-                                previous = calcAreaForWayPoint(p, previous);
+                                previous = c;
                             }
                         }
                     }
@@ -181,10 +202,10 @@
                 }
                 if (near == NEAR_WAYPOINTS || near == NEAR_BOTH) {
                     for (WayPoint p : data.waypoints) {
-                        if (cancel) {
-                            return;
-                        }
-                        previous = calcAreaForWayPoint(p, previous);
+                        tick();
+                        LatLon c = p.getCoor();
+                        r.setRect(c.lon() - bufferX, c.lat() - bufferY, 2 * bufferX, 2 * bufferY);
+                        path.append(r, false);
                     }
                 }
             }
