Changeset 5670 in josm


Ignore:
Timestamp:
2013-01-25T22:34:19+01:00 (12 years ago)
Author:
bastiK
Message:

session: save & restore map position and scale (see #4029)

Location:
trunk/src/org/openstreetmap/josm
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/Main.java

    r5538 r5670  
    11// License: GPL. Copyright 2007 by Immanuel Scholz and others
    22package org.openstreetmap.josm;
     3
    34import static org.openstreetmap.josm.tools.I18n.tr;
    45
     
    6566import org.openstreetmap.josm.gui.MapFrame;
    6667import org.openstreetmap.josm.gui.MapView;
     68import org.openstreetmap.josm.gui.NavigatableComponent.ViewportData;
    6769import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    6870import org.openstreetmap.josm.gui.io.SaveLayersDialog;
     
    406408     */
    407409    public final synchronized void addLayer(final Layer layer) {
    408         if (map == null) {
    409             final MapFrame mapFrame = new MapFrame(contentPanePrivate);
    410             setMapFrame(mapFrame);
    411             mapFrame.selectMapMode((MapMode)mapFrame.getDefaultButtonAction(), layer);
    412             mapFrame.setVisible(true);
    413             mapFrame.initializeDialogsPane();
    414             // bootstrapping problem: make sure the layer list dialog is going to
    415             // listen to change events of the very first layer
    416             //
    417             layer.addPropertyChangeListener(LayerListDialog.getInstance().getModel());
     410        boolean noMap = map == null;
     411        if (noMap) {
     412            createMapFrame(layer, null);
    418413        }
    419414        layer.hookUpMapView();
    420415        map.mapView.addLayer(layer);
     416        if (noMap) {
     417            Main.map.setVisible(true);
     418        }
     419    }
     420
     421    public synchronized void createMapFrame(Layer firstLayer, ViewportData viewportData) {
     422        MapFrame mapFrame = new MapFrame(contentPanePrivate, viewportData);
     423        setMapFrame(mapFrame);
     424        if (firstLayer != null) {
     425            mapFrame.selectMapMode((MapMode)mapFrame.getDefaultButtonAction(), firstLayer);
     426        }
     427        mapFrame.initializeDialogsPane();
     428        // bootstrapping problem: make sure the layer list dialog is going to
     429        // listen to change events of the very first layer
     430        //
     431        firstLayer.addPropertyChangeListener(LayerListDialog.getInstance().getModel());
    421432    }
    422433
  • trunk/src/org/openstreetmap/josm/actions/JumpToAction.java

    r4982 r5670  
    1919
    2020import org.openstreetmap.josm.Main;
    21 import org.openstreetmap.josm.actions.JosmAction;
    2221import org.openstreetmap.josm.data.Bounds;
    2322import org.openstreetmap.josm.data.coor.LatLon;
  • trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java

    r5573 r5670  
    1616
    1717import org.openstreetmap.josm.Main;
     18import org.openstreetmap.josm.data.coor.EastNorth;
    1819import org.openstreetmap.josm.gui.HelpAwareOptionPane;
     20import org.openstreetmap.josm.gui.NavigatableComponent;
     21import org.openstreetmap.josm.gui.NavigatableComponent.ViewportData;
    1922import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    2023import org.openstreetmap.josm.gui.layer.Layer;
     
    4750        private List<Layer> layers;
    4851        private List<Runnable> postLoadTasks;
     52        private ViewportData viewport;
    4953
    5054        public Loader(File file, boolean zip) {
     
    6670                public void run() {
    6771                    if (canceled) return;
    68                     for (Layer l : layers) {
    69                         if (canceled) return;
    70                         Main.main.addLayer(l);
     72                    if (!layers.isEmpty()) {
     73                        Layer firstLayer = layers.iterator().next();
     74                        boolean noMap = Main.map == null;
     75                        if (noMap) {
     76                            Main.main.createMapFrame(firstLayer, viewport);
     77                        }
     78                        for (Layer l : layers) {
     79                            if (canceled) return;
     80                            Main.main.addLayer(l);
     81                        }
     82                        if (noMap) {
     83                            Main.map.setVisible(true);
     84                        }
    7185                    }
    7286                    for (Runnable task : postLoadTasks) {
     
    89103                layers = reader.getLayers();
    90104                postLoadTasks = reader.getPostLoadTasks();
     105                viewport = reader.getViewport();
    91106            } catch (IllegalDataException e) {
    92107                e.printStackTrace();
  • trunk/src/org/openstreetmap/josm/data/ProjectionBounds.java

    r4065 r5670  
    1717
    1818    /**
    19      * Construct bounds out of two points
     19     * Construct bounds out of two points.
    2020     */
    2121    public ProjectionBounds(EastNorth min, EastNorth max) {
  • trunk/src/org/openstreetmap/josm/gui/MapFrame.java

    r5463 r5670  
    5454import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
    5555import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
     56import org.openstreetmap.josm.gui.NavigatableComponent.ViewportData;
    5657import org.openstreetmap.josm.gui.dialogs.ChangesetDialog;
    5758import org.openstreetmap.josm.gui.dialogs.CommandStackDialog;
     
    144145    private final Map<Layer, MapMode> lastMapMode = new HashMap<Layer, MapMode>();
    145146
    146     public MapFrame(JPanel contentPane) {
     147    /**
     148     * Constructs a new {@code MapFrame}.
     149     * @param contentPane The content pane used to register shortcuts in its
     150     * {@link InputMap} and {@link ActionMap}
     151     * @param viewportData the initial viewport of the map. Can be null, then
     152     * the viewport is derived from the layer data.
     153     */
     154    public MapFrame(JPanel contentPane, ViewportData viewportData) {
    147155        setSize(400,400);
    148156        setLayout(new BorderLayout());
    149157
    150158
    151         mapView = new MapView(contentPane);
     159        mapView = new MapView(contentPane, viewportData);
    152160
    153161        new FileDrop(mapView);
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r5519 r5670  
    219219    /**
    220220     * Constructs a new {@code MapView}.
    221      * @param contentPane The content pane used to register shortcuts in its {@link InputMap} and {@link ActionMap}
    222      */
    223     public MapView(final JPanel contentPane) {
     221     * @param contentPane The content pane used to register shortcuts in its
     222     * {@link InputMap} and {@link ActionMap}
     223     * @param viewportData the initial viewport of the map. Can be null, then
     224     * the viewport is derived from the layer data.
     225     */
     226    public MapView(final JPanel contentPane, final ViewportData viewportData) {
    224227        Main.pref.addPreferenceChangeListener(this);
    225228
     
    237240
    238241                mapMover = new MapMover(MapView.this, contentPane);
    239                 OsmDataLayer layer = getEditLayer();
    240                 if (layer != null) {
    241                     if (!zoomToDataSetBoundingBox(layer.data)) {
    242                         // no bounding box defined
    243                         AutoScaleAction.autoScale("data");
     242                if (viewportData != null) {
     243                    zoomTo(viewportData.getCenter(), viewportData.getScale());
     244                } else {
     245                    OsmDataLayer layer = getEditLayer();
     246                    if (layer != null) {
     247                        if (!zoomToDataSetBoundingBox(layer.data)) {
     248                            // no bounding box defined
     249                            AutoScaleAction.autoScale("data");
     250                        }
     251                    } else {
     252                        AutoScaleAction.autoScale("layer");
    244253                    }
    245                 } else {
    246                     AutoScaleAction.autoScale("layer");
    247254                }
    248255            }
  • trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java

    r5565 r5670  
    6565    }
    6666
     67    /**
     68     * Simple data class that keeps map center and scale in one object.
     69     */
     70    public static class ViewportData {
     71        private EastNorth center;
     72        private Double scale;
     73
     74        public ViewportData(EastNorth center, Double scale) {
     75            this.center = center;
     76            this.scale = scale;
     77        }
     78
     79        /**
     80         * Return the projected coordinates of the map center
     81         * @return the center
     82         */
     83        public EastNorth getCenter() {
     84            return center;
     85        }
     86
     87        /**
     88         * Return the scale factor in east-/north-units per pixel.
     89         * @return the scale
     90         */
     91        public Double getScale() {
     92            return scale;
     93        }
     94    }
     95
    6796    public static final IntegerProperty PROP_SNAP_DISTANCE = new IntegerProperty("mappaint.node.snap-distance", 10);
    6897
     
    172201    public EastNorth getCenter() {
    173202        return center;
     203    }
     204
     205    public double getScale() {
     206        return scale;
    174207    }
    175208
  • trunk/src/org/openstreetmap/josm/io/session/SessionReader.java

    r5572 r5670  
    3333
    3434import org.openstreetmap.josm.Main;
     35import org.openstreetmap.josm.data.coor.EastNorth;
     36import org.openstreetmap.josm.data.coor.LatLon;
     37import org.openstreetmap.josm.data.projection.Projection;
     38import org.openstreetmap.josm.data.projection.Projections;
    3539import org.openstreetmap.josm.gui.ExtendedDialog;
     40import org.openstreetmap.josm.gui.NavigatableComponent.ViewportData;
    3641import org.openstreetmap.josm.gui.layer.Layer;
    3742import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     
    8489    private List<Layer> layers = new ArrayList<Layer>();
    8590    private List<Runnable> postLoadTasks = new ArrayList<Runnable>();
     91    private ViewportData viewport;
    8692
    8793    /**
     
    97103    public List<Runnable> getPostLoadTasks() {
    98104        return postLoadTasks;
     105    }
     106
     107    /**
     108     * Return the viewport (map position and scale).
     109     * @return The viewport. Can be null when no viewport info is found in the file.
     110     */
     111    public ViewportData getViewport() {
     112        return viewport;
    99113    }
    100114
     
    277291        }
    278292
    279         NodeList layersNL = root.getElementsByTagName("layers");
    280         if (layersNL.getLength() == 0) return;
    281 
    282         Element layersEl = (Element) layersNL.item(0);
     293        Element viewportEl = getElementByTagName(root, "viewport");
     294        if (viewportEl != null) {
     295            EastNorth center = null;
     296            Element centerEl = getElementByTagName(viewportEl, "center");
     297            if (centerEl != null && centerEl.hasAttribute("lat") && centerEl.hasAttribute("lon")) {
     298                try {
     299                    LatLon centerLL = new LatLon(Double.parseDouble(centerEl.getAttribute("lat")), Double.parseDouble(centerEl.getAttribute("lon")));
     300                    center = Projections.project(centerLL);
     301                } catch (NumberFormatException ex) {}
     302            }
     303            if (center != null) {
     304                Element scaleEl = getElementByTagName(viewportEl, "scale");
     305                if (scaleEl != null && scaleEl.hasAttribute("meter-per-pixel")) {
     306                    try {
     307                        Double meterPerPixel = Double.parseDouble(scaleEl.getAttribute("meter-per-pixel"));
     308                        Projection proj = Main.getProjection();
     309                        // Get a "typical" distance in east/north units that
     310                        // corresponds to a couple of pixels. Shouldn't be too
     311                        // large, to keep it within projection bounds and
     312                        // not too small to avoid rounding errors.
     313                        double dist = 0.01 * proj.getDefaultZoomInPPD();
     314                        LatLon ll1 = proj.eastNorth2latlon(new EastNorth(center.east() - dist, center.north()));
     315                        LatLon ll2 = proj.eastNorth2latlon(new EastNorth(center.east() + dist, center.north()));
     316                        double meterPerEasting = ll1.greatCircleDistance(ll2) / dist / 2;
     317                        double scale = meterPerPixel / meterPerEasting; // unit: easting per pixel
     318                        viewport = new ViewportData(center, scale);
     319                    } catch (NumberFormatException ex) {}
     320                }
     321            }
     322        }
     323
     324        Element layersEl = getElementByTagName(root, "layers");
     325        if (layersEl == null) return;
    283326
    284327        MultiMap<Integer, Integer> deps = new MultiMap<Integer, Integer>();
     
    532575    }
    533576
     577    private static Element getElementByTagName(Element root, String name) {
     578        NodeList els = root.getElementsByTagName(name);
     579        if (els.getLength() == 0) return null;
     580        return (Element) els.item(0);
     581    }
     582
    534583}
  • trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java

    r5551 r5670  
    2828import javax.xml.transform.stream.StreamResult;
    2929
     30import org.openstreetmap.josm.Main;
     31import org.openstreetmap.josm.data.coor.EastNorth;
     32import org.openstreetmap.josm.data.coor.LatLon;
     33import org.openstreetmap.josm.data.projection.Projections;
    3034import org.openstreetmap.josm.gui.layer.GpxLayer;
    3135import org.openstreetmap.josm.gui.layer.Layer;
     
    161165        root.setAttribute("version", "0.1");
    162166        doc.appendChild(root);
     167
     168        Element viewportEl = doc.createElement("viewport");
     169        root.appendChild(viewportEl);
     170        Element centerEl = doc.createElement("center");
     171        viewportEl.appendChild(centerEl);
     172        EastNorth center = Main.map.mapView.getCenter();
     173        LatLon centerLL = Projections.inverseProject(center);
     174        centerEl.setAttribute("lat", Double.toString(centerLL.lat()));
     175        centerEl.setAttribute("lon", Double.toString(centerLL.lon()));
     176        Element scale = doc.createElement("scale");
     177        viewportEl.appendChild(scale);
     178        double dist100px = Main.map.mapView.getDist100Pixel();
     179        scale.setAttribute("meter-per-pixel", Double.toString(dist100px / 100));
    163180
    164181        Element layersEl = doc.createElement("layers");
Note: See TracChangeset for help on using the changeset viewer.