Index: /trunk/src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 11774)
@@ -7,7 +7,11 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.downloadtasks.AbstractDownloadTask;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesTask;
@@ -15,5 +19,9 @@
 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.ProjectionBounds;
+import org.openstreetmap.josm.data.ViewportData;
 import org.openstreetmap.josm.gui.download.DownloadDialog;
+import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -45,22 +53,57 @@
         if (!dialog.isCanceled()) {
             dialog.rememberSettings();
-            Bounds area = dialog.getSelectedDownloadArea();
+            final Bounds area = dialog.getSelectedDownloadArea();
+            final boolean zoom = dialog.isZoomToDownloadedDataRequired();
+            final List<Pair<AbstractDownloadTask<?>, Future<?>>> tasks = new ArrayList<>();
             if (dialog.isDownloadOsmData()) {
                 DownloadOsmTask task = new DownloadOsmTask();
-                task.setZoomAfterDownload(dialog.isZoomToDownloadedDataRequired());
+                task.setZoomAfterDownload(zoom && !dialog.isDownloadGpxData() && !dialog.isDownloadNotes());
                 Future<?> future = task.download(dialog.isNewLayerRequired(), area, null);
                 Main.worker.submit(new PostDownloadHandler(task, future));
+                if (zoom) {
+                    tasks.add(new Pair<>(task, future));
+                }
             }
             if (dialog.isDownloadGpxData()) {
                 DownloadGpsTask task = new DownloadGpsTask();
-                task.setZoomAfterDownload(dialog.isZoomToDownloadedDataRequired());
+                task.setZoomAfterDownload(zoom && !dialog.isDownloadOsmData() && !dialog.isDownloadNotes());
                 Future<?> future = task.download(dialog.isNewLayerRequired(), area, null);
                 Main.worker.submit(new PostDownloadHandler(task, future));
+                if (zoom) {
+                    tasks.add(new Pair<>(task, future));
+                }
             }
             if (dialog.isDownloadNotes()) {
                 DownloadNotesTask task = new DownloadNotesTask();
-                task.setZoomAfterDownload(dialog.isZoomToDownloadedDataRequired());
+                task.setZoomAfterDownload(zoom && !dialog.isDownloadOsmData() && !dialog.isDownloadGpxData());
                 Future<?> future = task.download(false, area, null);
                 Main.worker.submit(new PostDownloadHandler(task, future));
+                if (zoom) {
+                    tasks.add(new Pair<>(task, future));
+                }
+            }
+            if (zoom && tasks.size() > 1) {
+                Main.worker.submit(() -> {
+                    ProjectionBounds bounds = null;
+                    // Wait for completion of download jobs
+                    for (Pair<AbstractDownloadTask<?>, Future<?>> p : tasks) {
+                        try {
+                            p.b.get();
+                            ProjectionBounds b = p.a.getDownloadProjectionBounds();
+                            if (bounds == null) {
+                                bounds = b;
+                            } else if (b != null) {
+                                bounds.extend(b);
+                            }
+                        } catch (InterruptedException | ExecutionException ex) {
+                            Main.warn(ex);
+                        }
+                    }
+                    // Zoom to the larger download bounds
+                    if (Main.map != null && bounds != null) {
+                        final ProjectionBounds pb = bounds;
+                        GuiHelper.runInEDTAndWait(() -> Main.map.mapView.zoomTo(new ViewportData(pb)));
+                    }
+                });
             }
         }
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java	(revision 11774)
@@ -5,4 +5,5 @@
 import java.util.List;
 
+import org.openstreetmap.josm.data.ProjectionBounds;
 import org.openstreetmap.josm.io.XmlWriter;
 
@@ -170,3 +171,12 @@
         return new String[]{};
     }
+
+    /**
+     * Returns the projection bounds of downloaded data.
+     * @return the projection bounds of downloaded data or {@code null}
+     * @since 11774
+     */
+    public ProjectionBounds getDownloadProjectionBounds() {
+        return null;
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 11774)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.Bounds.ParseMethod;
+import org.openstreetmap.josm.data.ProjectionBounds;
 import org.openstreetmap.josm.data.ViewportData;
 import org.openstreetmap.josm.data.gpx.GpxData;
@@ -39,4 +40,5 @@
 
     private DownloadTask downloadTask;
+    private GpxLayer gpxLayer;
 
     private static final String PATTERN_TRACE_ID = "https?://.*(osm|openstreetmap).org/trace/\\p{Digit}+/data";
@@ -114,4 +116,9 @@
     }
 
+    @Override
+    public ProjectionBounds getDownloadProjectionBounds() {
+        return gpxLayer != null ? gpxLayer.getViewProjectionBounds() : null;
+    }
+
     class DownloadTask extends PleaseWaitRunnable {
         private final OsmServerReader reader;
@@ -130,6 +137,5 @@
                 if (isCanceled())
                     return;
-                ProgressMonitor subMonitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
-                rawData = reader.parseRawGps(subMonitor);
+                rawData = reader.parseRawGps(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
             } catch (OsmTransferException e) {
                 if (isCanceled())
@@ -149,5 +155,5 @@
                     tr("Markers from {0}", name));
 
-            GpxLayer gpxLayer = addOrMergeLayer(layers.getGpxLayer(), findGpxMergeLayer());
+            gpxLayer = addOrMergeLayer(layers.getGpxLayer(), findGpxMergeLayer());
             addOrMergeLayer(layers.getMarkerLayer(), findMarkerMergeLayer(gpxLayer));
 
@@ -158,10 +164,10 @@
             if (layer == null) return null;
             if (newLayer || mergeLayer == null) {
-                Main.getLayerManager().addLayer(layer);
+                Main.getLayerManager().addLayer(layer, zoomAfterDownload);
                 return layer;
             } else {
                 mergeLayer.mergeFrom(layer);
                 mergeLayer.invalidate();
-                if (Main.map != null && zoomAfterDownload) {
+                if (Main.map != null && zoomAfterDownload && layer instanceof GpxLayer) {
                     Main.map.mapView.scheduleZoomTo(new ViewportData(layer.getViewProjectionBounds()));
                 }
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java	(revision 11774)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.ProjectionBounds;
 import org.openstreetmap.josm.data.ViewportData;
 import org.openstreetmap.josm.data.notes.Note;
@@ -40,4 +41,5 @@
 
     private DownloadTask downloadTask;
+    private NoteLayer noteLayer;
 
     /**
@@ -96,4 +98,9 @@
     }
 
+    @Override
+    public ProjectionBounds getDownloadProjectionBounds() {
+        return noteLayer != null ? noteLayer.getViewProjectionBounds() : null;
+    }
+
     abstract class DownloadTask extends PleaseWaitRunnable {
         protected OsmServerReader reader;
@@ -117,10 +124,11 @@
             List<NoteLayer> noteLayers = Main.getLayerManager().getLayersOfType(NoteLayer.class);
             if (!noteLayers.isEmpty()) {
-                noteLayers.get(0).getNoteData().addNotes(notesData);
+                noteLayer = noteLayers.get(0);
+                noteLayer.getNoteData().addNotes(notesData);
                 if (Main.map != null && zoomAfterDownload) {
-                    Main.map.mapView.scheduleZoomTo(new ViewportData(noteLayers.get(0).getViewProjectionBounds()));
+                    Main.map.mapView.scheduleZoomTo(new ViewportData(noteLayer.getViewProjectionBounds()));
                 }
             } else {
-                Main.getLayerManager().addLayer(new NoteLayer(notesData, tr("Notes")));
+                Main.getLayerManager().addLayer(new NoteLayer(notesData, tr("Notes")), zoomAfterDownload);
             }
         }
Index: /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 11774)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.data.DataSource;
 import org.openstreetmap.josm.data.ProjectionBounds;
+import org.openstreetmap.josm.data.ViewportData;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -175,4 +176,9 @@
     }
 
+    @Override
+    public ProjectionBounds getDownloadProjectionBounds() {
+        return downloadTask != null ? downloadTask.computeBbox(currentBounds) : null;
+    }
+
     /**
      * Superclass of internal download task.
@@ -253,11 +259,4 @@
         }
 
-        protected void computeBboxAndCenterScale(Bounds bounds) {
-            ProjectionBounds pb = computeBbox(bounds);
-            BoundingXYVisitor v = new BoundingXYVisitor();
-            v.visit(pb);
-            Main.map.mapView.zoomTo(v);
-        }
-
         protected OsmDataLayer addNewLayerIfRequired(String newLayerName) {
             int numDataLayers = getNumDataLayers();
@@ -268,5 +267,5 @@
                 final OsmDataLayer layer = createNewLayer(newLayerName);
                 if (Main.main != null)
-                    Main.getLayerManager().addLayer(layer);
+                    Main.getLayerManager().addLayer(layer, zoomAfterDownload);
                 return layer;
             }
@@ -280,6 +279,6 @@
                 Collection<OsmPrimitive> primitivesToUpdate = searchPrimitivesToUpdate(bounds, layer.data);
                 layer.mergeFrom(dataSet);
-                if (zoomAfterDownload) {
-                    computeBboxAndCenterScale(bounds);
+                if (Main.map != null && zoomAfterDownload) {
+                    Main.map.mapView.zoomTo(new ViewportData(computeBbox(bounds)));
                 }
                 if (!primitivesToUpdate.isEmpty()) {
Index: /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java	(revision 11774)
@@ -97,4 +97,24 @@
 
     /**
+     * Extends bounds to include bounds {@code b}.
+     * @param b bounds to include
+     * @since 11774
+     */
+    public void extend(ProjectionBounds b) {
+        if (b.minEast < minEast) {
+            minEast = b.minEast;
+        }
+        if (b.maxEast > maxEast) {
+            maxEast = b.maxEast;
+        }
+        if (b.minNorth < minNorth) {
+            minNorth = b.minNorth;
+        }
+        if (b.maxNorth > maxNorth) {
+            maxNorth = b.maxNorth;
+        }
+    }
+
+    /**
      * Returns the center east/north.
      * @return the center east/north
Index: /trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 11774)
@@ -343,7 +343,9 @@
                 registeredLayers.put(layer, painter);
 
-                ProjectionBounds viewProjectionBounds = layer.getViewProjectionBounds();
-                if (viewProjectionBounds != null) {
-                    scheduleZoomTo(new ViewportData(viewProjectionBounds));
+                if (e.isZoomRequired()) {
+                    ProjectionBounds viewProjectionBounds = layer.getViewProjectionBounds();
+                    if (viewProjectionBounds != null) {
+                        scheduleZoomTo(new ViewportData(viewProjectionBounds));
+                    }
                 }
 
Index: /trunk/src/org/openstreetmap/josm/gui/layer/LayerManager.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/LayerManager.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/LayerManager.java	(revision 11774)
@@ -71,4 +71,8 @@
         }
 
+        /**
+         * Returns the {@code LayerManager} at the origin of this event.
+         * @return the {@code LayerManager} at the origin of this event
+         */
         public LayerManager getSource() {
             return source;
@@ -82,8 +86,10 @@
     public static class LayerAddEvent extends LayerManagerEvent {
         private final Layer addedLayer;
-
-        LayerAddEvent(LayerManager source, Layer addedLayer) {
+        private final boolean requiresZoom;
+
+        LayerAddEvent(LayerManager source, Layer addedLayer, boolean requiresZoom) {
             super(source);
             this.addedLayer = addedLayer;
+            this.requiresZoom = requiresZoom;
         }
 
@@ -94,4 +100,13 @@
         public Layer getAddedLayer() {
             return addedLayer;
+        }
+
+        /**
+         * Determines if an initial zoom is required.
+         * @return {@code true} if a zoom is required when this layer is added
+         * @since 11774
+         */
+        public final boolean isZoomRequired() {
+            return requiresZoom;
         }
 
@@ -182,14 +197,23 @@
 
     /**
+     * Add a layer. The layer will be added at a given position and the mapview zoomed at its projection bounds.
+     * @param layer The layer to add
+     */
+    public void addLayer(final Layer layer) {
+        addLayer(layer, true);
+    }
+
+    /**
      * Add a layer. The layer will be added at a given position.
      * @param layer The layer to add
-     */
-    public void addLayer(final Layer layer) {
+     * @param initialZoom whether if the mapview must be zoomed at layer projection bounds
+     */
+    public void addLayer(final Layer layer, final boolean initialZoom) {
         // we force this on to the EDT Thread to make events fire from there.
         // The synchronization lock needs to be held by the EDT.
-        GuiHelper.runInEDTAndWaitWithException(() -> realAddLayer(layer));
-    }
-
-    protected synchronized void realAddLayer(Layer layer) {
+        GuiHelper.runInEDTAndWaitWithException(() -> realAddLayer(layer, initialZoom));
+    }
+
+    protected synchronized void realAddLayer(Layer layer, boolean initialZoom) {
         if (containsLayer(layer)) {
             throw new IllegalArgumentException("Cannot add a layer twice: " + layer);
@@ -199,5 +223,5 @@
         checkPosition(position);
         insertLayerAt(layer, position);
-        fireLayerAdded(layer);
+        fireLayerAdded(layer, initialZoom);
         if (Main.map != null) {
             layer.hookUpMapView(); // needs to be after fireLayerAdded
@@ -366,5 +390,5 @@
         if (fireAdd) {
             for (Layer l : getLayers()) {
-                listener.layerAdded(new LayerAddEvent(this, l));
+                listener.layerAdded(new LayerAddEvent(this, l, true));
             }
         }
@@ -399,7 +423,7 @@
     }
 
-    private void fireLayerAdded(Layer layer) {
+    private void fireLayerAdded(Layer layer, boolean initialZoom) {
         GuiHelper.assertCallFromEdt();
-        LayerAddEvent e = new LayerAddEvent(this, layer);
+        LayerAddEvent e = new LayerAddEvent(this, layer, initialZoom);
         for (LayerChangeListener l : layerChangeListeners) {
             try {
Index: /trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java	(revision 11773)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java	(revision 11774)
@@ -242,5 +242,5 @@
 
     @Override
-    protected synchronized void realAddLayer(Layer layer) {
+    protected synchronized void realAddLayer(Layer layer, boolean initialZoom) {
         if (getLayers().isEmpty()) {
             LayerAvailabilityEvent e = new LayerAvailabilityEvent(this, true);
@@ -249,5 +249,5 @@
             }
         }
-        super.realAddLayer(layer);
+        super.realAddLayer(layer, initialZoom);
 
         // update the active layer automatically.
