Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 5670)
@@ -1,4 +1,5 @@
 // License: GPL. Copyright 2007 by Immanuel Scholz and others
 package org.openstreetmap.josm;
+
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -65,4 +66,5 @@
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.NavigatableComponent.ViewportData;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.io.SaveLayersDialog;
@@ -406,17 +408,26 @@
      */
     public final synchronized void addLayer(final Layer layer) {
-        if (map == null) {
-            final MapFrame mapFrame = new MapFrame(contentPanePrivate);
-            setMapFrame(mapFrame);
-            mapFrame.selectMapMode((MapMode)mapFrame.getDefaultButtonAction(), layer);
-            mapFrame.setVisible(true);
-            mapFrame.initializeDialogsPane();
-            // bootstrapping problem: make sure the layer list dialog is going to
-            // listen to change events of the very first layer
-            //
-            layer.addPropertyChangeListener(LayerListDialog.getInstance().getModel());
+        boolean noMap = map == null;
+        if (noMap) {
+            createMapFrame(layer, null);
         }
         layer.hookUpMapView();
         map.mapView.addLayer(layer);
+        if (noMap) {
+            Main.map.setVisible(true);
+        }
+    }
+
+    public synchronized void createMapFrame(Layer firstLayer, ViewportData viewportData) {
+        MapFrame mapFrame = new MapFrame(contentPanePrivate, viewportData);
+        setMapFrame(mapFrame);
+        if (firstLayer != null) {
+            mapFrame.selectMapMode((MapMode)mapFrame.getDefaultButtonAction(), firstLayer);
+        }
+        mapFrame.initializeDialogsPane();
+        // bootstrapping problem: make sure the layer list dialog is going to
+        // listen to change events of the very first layer
+        //
+        firstLayer.addPropertyChangeListener(LayerListDialog.getInstance().getModel());
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/JumpToAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JumpToAction.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/actions/JumpToAction.java	(revision 5670)
@@ -19,5 +19,4 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
Index: trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java	(revision 5670)
@@ -16,5 +16,8 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
+import org.openstreetmap.josm.gui.NavigatableComponent;
+import org.openstreetmap.josm.gui.NavigatableComponent.ViewportData;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -47,4 +50,5 @@
         private List<Layer> layers;
         private List<Runnable> postLoadTasks;
+        private ViewportData viewport;
 
         public Loader(File file, boolean zip) {
@@ -66,7 +70,17 @@
                 public void run() {
                     if (canceled) return;
-                    for (Layer l : layers) {
-                        if (canceled) return;
-                        Main.main.addLayer(l);
+                    if (!layers.isEmpty()) {
+                        Layer firstLayer = layers.iterator().next();
+                        boolean noMap = Main.map == null;
+                        if (noMap) {
+                            Main.main.createMapFrame(firstLayer, viewport);
+                        }
+                        for (Layer l : layers) {
+                            if (canceled) return;
+                            Main.main.addLayer(l);
+                        }
+                        if (noMap) {
+                            Main.map.setVisible(true);
+                        }
                     }
                     for (Runnable task : postLoadTasks) {
@@ -89,4 +103,5 @@
                 layers = reader.getLayers();
                 postLoadTasks = reader.getPostLoadTasks();
+                viewport = reader.getViewport();
             } catch (IllegalDataException e) {
                 e.printStackTrace();
Index: trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java	(revision 5670)
@@ -17,5 +17,5 @@
 
     /**
-     * Construct bounds out of two points
+     * Construct bounds out of two points.
      */
     public ProjectionBounds(EastNorth min, EastNorth max) {
Index: trunk/src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/gui/MapFrame.java	(revision 5670)
@@ -54,4 +54,5 @@
 import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.NavigatableComponent.ViewportData;
 import org.openstreetmap.josm.gui.dialogs.ChangesetDialog;
 import org.openstreetmap.josm.gui.dialogs.CommandStackDialog;
@@ -144,10 +145,17 @@
     private final Map<Layer, MapMode> lastMapMode = new HashMap<Layer, MapMode>();
 
-    public MapFrame(JPanel contentPane) {
+    /**
+     * Constructs a new {@code MapFrame}.
+     * @param contentPane The content pane used to register shortcuts in its
+     * {@link InputMap} and {@link ActionMap}
+     * @param viewportData the initial viewport of the map. Can be null, then
+     * the viewport is derived from the layer data.
+     */
+    public MapFrame(JPanel contentPane, ViewportData viewportData) {
         setSize(400,400);
         setLayout(new BorderLayout());
 
 
-        mapView = new MapView(contentPane);
+        mapView = new MapView(contentPane, viewportData);
 
         new FileDrop(mapView);
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 5670)
@@ -219,7 +219,10 @@
     /**
      * Constructs a new {@code MapView}.
-     * @param contentPane The content pane used to register shortcuts in its {@link InputMap} and {@link ActionMap}
-     */
-    public MapView(final JPanel contentPane) {
+     * @param contentPane The content pane used to register shortcuts in its
+     * {@link InputMap} and {@link ActionMap}
+     * @param viewportData the initial viewport of the map. Can be null, then
+     * the viewport is derived from the layer data.
+     */
+    public MapView(final JPanel contentPane, final ViewportData viewportData) {
         Main.pref.addPreferenceChangeListener(this);
 
@@ -237,12 +240,16 @@
 
                 mapMover = new MapMover(MapView.this, contentPane);
-                OsmDataLayer layer = getEditLayer();
-                if (layer != null) {
-                    if (!zoomToDataSetBoundingBox(layer.data)) {
-                        // no bounding box defined
-                        AutoScaleAction.autoScale("data");
+                if (viewportData != null) {
+                    zoomTo(viewportData.getCenter(), viewportData.getScale());
+                } else {
+                    OsmDataLayer layer = getEditLayer();
+                    if (layer != null) {
+                        if (!zoomToDataSetBoundingBox(layer.data)) {
+                            // no bounding box defined
+                            AutoScaleAction.autoScale("data");
+                        }
+                    } else {
+                        AutoScaleAction.autoScale("layer");
                     }
-                } else {
-                    AutoScaleAction.autoScale("layer");
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 5670)
@@ -65,4 +65,33 @@
     }
 
+    /**
+     * Simple data class that keeps map center and scale in one object.
+     */
+    public static class ViewportData {
+        private EastNorth center;
+        private Double scale;
+
+        public ViewportData(EastNorth center, Double scale) {
+            this.center = center;
+            this.scale = scale;
+        }
+
+        /**
+         * Return the projected coordinates of the map center
+         * @return the center
+         */
+        public EastNorth getCenter() {
+            return center;
+        }
+
+        /**
+         * Return the scale factor in east-/north-units per pixel.
+         * @return the scale
+         */
+        public Double getScale() {
+            return scale;
+        }
+    }
+
     public static final IntegerProperty PROP_SNAP_DISTANCE = new IntegerProperty("mappaint.node.snap-distance", 10);
 
@@ -172,4 +201,8 @@
     public EastNorth getCenter() {
         return center;
+    }
+
+    public double getScale() {
+        return scale;
     }
 
Index: trunk/src/org/openstreetmap/josm/io/session/SessionReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 5670)
@@ -33,5 +33,10 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.projection.Projection;
+import org.openstreetmap.josm.data.projection.Projections;
 import org.openstreetmap.josm.gui.ExtendedDialog;
+import org.openstreetmap.josm.gui.NavigatableComponent.ViewportData;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
@@ -84,4 +89,5 @@
     private List<Layer> layers = new ArrayList<Layer>();
     private List<Runnable> postLoadTasks = new ArrayList<Runnable>();
+    private ViewportData viewport;
 
     /**
@@ -97,4 +103,12 @@
     public List<Runnable> getPostLoadTasks() {
         return postLoadTasks;
+    }
+
+    /**
+     * Return the viewport (map position and scale).
+     * @return The viewport. Can be null when no viewport info is found in the file.
+     */
+    public ViewportData getViewport() {
+        return viewport;
     }
 
@@ -277,8 +291,37 @@
         }
 
-        NodeList layersNL = root.getElementsByTagName("layers");
-        if (layersNL.getLength() == 0) return;
-
-        Element layersEl = (Element) layersNL.item(0);
+        Element viewportEl = getElementByTagName(root, "viewport");
+        if (viewportEl != null) {
+            EastNorth center = null;
+            Element centerEl = getElementByTagName(viewportEl, "center");
+            if (centerEl != null && centerEl.hasAttribute("lat") && centerEl.hasAttribute("lon")) {
+                try {
+                    LatLon centerLL = new LatLon(Double.parseDouble(centerEl.getAttribute("lat")), Double.parseDouble(centerEl.getAttribute("lon")));
+                    center = Projections.project(centerLL);
+                } catch (NumberFormatException ex) {}
+            }
+            if (center != null) {
+                Element scaleEl = getElementByTagName(viewportEl, "scale");
+                if (scaleEl != null && scaleEl.hasAttribute("meter-per-pixel")) {
+                    try {
+                        Double meterPerPixel = Double.parseDouble(scaleEl.getAttribute("meter-per-pixel"));
+                        Projection proj = Main.getProjection();
+                        // Get a "typical" distance in east/north units that
+                        // corresponds to a couple of pixels. Shouldn't be too
+                        // large, to keep it within projection bounds and
+                        // not too small to avoid rounding errors.
+                        double dist = 0.01 * proj.getDefaultZoomInPPD();
+                        LatLon ll1 = proj.eastNorth2latlon(new EastNorth(center.east() - dist, center.north()));
+                        LatLon ll2 = proj.eastNorth2latlon(new EastNorth(center.east() + dist, center.north()));
+                        double meterPerEasting = ll1.greatCircleDistance(ll2) / dist / 2;
+                        double scale = meterPerPixel / meterPerEasting; // unit: easting per pixel
+                        viewport = new ViewportData(center, scale);
+                    } catch (NumberFormatException ex) {}
+                }
+            }
+        }
+
+        Element layersEl = getElementByTagName(root, "layers");
+        if (layersEl == null) return;
 
         MultiMap<Integer, Integer> deps = new MultiMap<Integer, Integer>();
@@ -532,3 +575,9 @@
     }
 
+    private static Element getElementByTagName(Element root, String name) {
+        NodeList els = root.getElementsByTagName(name);
+        if (els.getLength() == 0) return null;
+        return (Element) els.item(0);
+    }
+
 }
Index: trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 5668)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 5670)
@@ -28,4 +28,8 @@
 import javax.xml.transform.stream.StreamResult;
 
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.EastNorth;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.projection.Projections;
 import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -161,4 +165,17 @@
         root.setAttribute("version", "0.1");
         doc.appendChild(root);
+
+        Element viewportEl = doc.createElement("viewport");
+        root.appendChild(viewportEl);
+        Element centerEl = doc.createElement("center");
+        viewportEl.appendChild(centerEl);
+        EastNorth center = Main.map.mapView.getCenter();
+        LatLon centerLL = Projections.inverseProject(center);
+        centerEl.setAttribute("lat", Double.toString(centerLL.lat()));
+        centerEl.setAttribute("lon", Double.toString(centerLL.lon()));
+        Element scale = doc.createElement("scale");
+        viewportEl.appendChild(scale);
+        double dist100px = Main.map.mapView.getDist100Pixel();
+        scale.setAttribute("meter-per-pixel", Double.toString(dist100px / 100));
 
         Element layersEl = doc.createElement("layers");
