Changeset 1722 in josm


Ignore:
Timestamp:
2009-07-03T12:33:32+02:00 (10 years ago)
Author:
stoecker
Message:

Large rework in projection handling - now allows only switching and more specific projections
TODO:

  • allow subprojections (i.e. settings for projections)
  • setup preferences for subprojections
  • better support of the new projection depending world bounds (how to handle valid data outside of world)
  • do not allow to zoom out of the world - zoom should stop when whole world is displayed
  • fix Lambert and SwissGrid to handle new OutOfWorld style and subprojections
  • fix new UTM projection
  • handle layers with fixed projection on projection change
  • allow easier projection switching (e.g. in menu)

NOTE:
This checkin very likely will cause problems. Please report or fix them. Older plugins may have trouble. The SVN plugins
have been fixed but may have problems nevertheless. This is a BIG change, but will make JOSMs internal structure much cleaner
and reduce lots of projection related problems.

Location:
trunk/src/org/openstreetmap/josm
Files:
2 added
34 edited

Legend:

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

    r1681 r1722  
    250250        }
    251251    };
     252
     253    static public void setProjection(String name)
     254    {
     255        Bounds b = (map != null && map.mapView != null) ? map.mapView.getRealBounds() : null;
     256        Projection oldProj = Main.proj;
     257        try {
     258            Main.proj = (Projection)Class.forName(name).newInstance();
     259        } catch (final Exception e) {
     260            JOptionPane.showMessageDialog(null, tr("The projection {0} could not be activated. Using Mercator", name));
     261            Main.proj = new Mercator();
     262        }
     263        if(!Main.proj.equals(oldProj))
     264        {
     265            if(b != null)
     266                map.mapView.zoomTo(b);
     267            /* TODO - remove layers with fixed projection */
     268        }
     269    }
     270
    252271    /**
    253272     * Should be called before the main constructor to setup some parameter stuff
     
    255274     */
    256275    public static void preConstructorInit(Map<String, Collection<String>> args) {
    257         try {
    258             Main.proj = (Projection)Class.forName(Main.pref.get("projection")).newInstance();
    259         } catch (final Exception e) {
    260             e.printStackTrace();
    261             JOptionPane.showMessageDialog(null, tr("The projection could not be read from preferences. Using Mercator"));
    262             Main.proj = new Mercator();
    263         }
     276        setProjection(Main.pref.get("projection", Mercator.class.getName()));
    264277
    265278        try {
  • trunk/src/org/openstreetmap/josm/actions/MirrorAction.java

    r1639 r1722  
    5555        }
    5656
    57         double minEast = 200.0;
    58         double maxEast = -200.0;
     57        double minEast = 20000000000.0;
     58        double maxEast = -20000000000.0;
    5959        for (Node n : nodes) {
    60             minEast = Math.min(minEast, n.eastNorth.east());
    61             maxEast = Math.max(maxEast, n.eastNorth.east());
     60            double east = n.getEastNorth().east();
     61            minEast = Math.min(minEast, east);
     62            maxEast = Math.max(maxEast, east);
    6263        }
    6364        double middle = (minEast + maxEast) / 2;
     
    6667
    6768        for (Node n : nodes)
    68             cmds.add(new MoveCommand(n, 2 * (middle - n.eastNorth.east()), 0.0));
     69            cmds.add(new MoveCommand(n, 2 * (middle - n.getEastNorth().east()), 0.0));
    6970
    7071        Main.main.undoRedo.add(new SequenceCommand(tr("Mirror"), cmds));
  • trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java

    r1677 r1722  
    148148        if(e.getSource() instanceof JPanel) {
    149149            MapView mv = Main.map.mapView;
    150             n.setEastNorth(mv.getEastNorth(mv.lastMEvent.getX(), mv.lastMEvent.getY()));
     150            n.setCoor(mv.getLatLon(mv.lastMEvent.getX(), mv.lastMEvent.getY()));
    151151        }
    152152
  • trunk/src/org/openstreetmap/josm/actions/ZoomInAction.java

    r1218 r1722  
    2020    public void actionPerformed(ActionEvent e) {
    2121        if (Main.map == null) return;
    22         double zoom = Main.map.mapView.getScale();
    23         Main.map.mapView.zoomTo(Main.map.mapView.getCenter(), zoom * .9);
     22        Main.map.mapView.zoomToFactor(0.9);
    2423    }
    2524}
  • trunk/src/org/openstreetmap/josm/actions/ZoomOutAction.java

    r1218 r1722  
    2020    public void actionPerformed(ActionEvent e) {
    2121        if (Main.map == null) return;
    22         double zoom = Main.map.mapView.getScale();
    23         Main.map.mapView.zoomTo(Main.map.mapView.getCenter(), zoom /.9);
     22        Main.map.mapView.zoomToFactor(1/0.9);
    2423    }
    2524}
  • trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java

    r1677 r1722  
    812812            double c = A.distanceSq(B);
    813813            q = (a - b + c) / (2*c);
    814             n.setEastNorth(B.east() + q * (A.east() - B.east()), B.north() + q * (A.north() - B.north()));
     814            n.setEastNorth(new EastNorth(B.east() + q * (A.east() - B.east()), B.north() + q * (A.north() - B.north())));
    815815        }
    816816    }
  • trunk/src/org/openstreetmap/josm/actions/mapmode/ZoomAction.java

    r1195 r1722  
    5757     */
    5858    public void selectionEnded(Rectangle r, boolean alt, boolean shift, boolean ctrl) {
    59         if (r.width >= 3 && r.height >= 3) {
    60             double scale = mv.getScale() * r.getWidth()/mv.getWidth();
    61             EastNorth newCenter = mv.getEastNorth(r.x+r.width/2, r.y+r.height/2);
    62             mv.zoomTo(newCenter, scale);
    63         }
     59        if (r.width >= 3 && r.height >= 3)
     60            mv.zoomToFactor(mv.getEastNorth(r.x+r.width/2, r.y+r.height/2), r.getWidth()/mv.getWidth());
    6461    }
    6562
  • trunk/src/org/openstreetmap/josm/command/MoveCommand.java

    r1640 r1722  
    4848    public static class OldState {
    4949        LatLon latlon;
    50         EastNorth eastNorth;
    5150        boolean modified;
    5251    }
     
    7069        for (Node n : this.objects) {
    7170            OldState os = new OldState();
    72             os.eastNorth = n.getEastNorth();
    7371            os.latlon = n.getCoor();
    7472            os.modified = n.modified;
     
    105103        for (Node n : objects) {
    106104            OldState os = it.next();
    107             n.setEastNorth(os.eastNorth);
     105            n.setCoor(os.latlon);
    108106            n.modified = os.modified;
    109107        }
  • trunk/src/org/openstreetmap/josm/command/RotateCommand.java

    r1640 r1722  
    1414
    1515import org.openstreetmap.josm.data.coor.EastNorth;
     16import org.openstreetmap.josm.data.coor.LatLon;
    1617import org.openstreetmap.josm.data.osm.Node;
    1718import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    3738
    3839    /**
     40     * Small helper for holding the interesting part of the old data state of the
     41     * objects.
     42     */
     43    public static class OldState {
     44        LatLon latlon;
     45        EastNorth eastNorth;
     46        boolean modified;
     47    }
     48
     49    /**
    3950     * angle of rotation starting click to pivot
    4051     */
     
    4960     * List of all old states of the objects.
    5061     */
    51     private Map<Node, MoveCommand.OldState> oldState = new HashMap<Node, MoveCommand.OldState>();
     62    private Map<Node, OldState> oldState = new HashMap<Node, OldState>();
    5263
    5364    /**
     
    6374
    6475        for (Node n : this.objects) {
    65             MoveCommand.OldState os = new MoveCommand.OldState();
     76            OldState os = new OldState();
     77            os.latlon = n.getCoor();
    6678            os.eastNorth = n.getEastNorth();
    67             os.latlon = n.getCoor();
    6879            os.modified = n.modified;
    6980            oldState.put(n, os);
     
    102113            double nx =  sinPhi * x + cosPhi * y + pivot.east();
    103114            double ny = -cosPhi * x + sinPhi * y + pivot.north();
    104             n.setEastNorth(nx, ny);
     115            n.setEastNorth(new EastNorth(nx, ny));
    105116            if (setModified)
    106117                n.modified = true;
     
    115126    @Override public void undoCommand() {
    116127        for (Node n : objects) {
    117             MoveCommand.OldState os = oldState.get(n);
    118             n.setEastNorth(os.eastNorth);
     128            OldState os = oldState.get(n);
     129            n.setCoor(os.latlon);
    119130            n.modified = os.modified;
    120131        }
  • trunk/src/org/openstreetmap/josm/data/Bounds.java

    r1169 r1722  
    2525        this.min = min;
    2626        this.max = max;
    27     }
    28 
    29     /**
    30      * Construct bounds that span the whole world.
    31      */
    32     public Bounds() {
    33         min = new LatLon(-Projection.MAX_LAT, -Projection.MAX_LON);
    34         max = new LatLon(Projection.MAX_LAT, Projection.MAX_LON);
    3527    }
    3628
  • trunk/src/org/openstreetmap/josm/data/Preferences.java

    r1688 r1722  
    352352        put("selectionlist.visible", true);
    353353        put("commandstack.visible", true);
    354         put("projection", Mercator.class.getName());
    355354        if (System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") == -1) {
    356355            put("laf", "javax.swing.plaf.metal.MetalLookAndFeel");
  • trunk/src/org/openstreetmap/josm/data/coor/LatLon.java

    r1209 r1722  
    77import org.openstreetmap.josm.data.Bounds;
    88import org.openstreetmap.josm.data.projection.Projection;
     9import org.openstreetmap.josm.Main;
    910
    1011import java.text.DecimalFormat;
     
    8788     */
    8889    public boolean isOutSideWorld() {
    89         return lat() < -Projection.MAX_LAT || lat() > Projection.MAX_LAT ||
    90             lon() < -Projection.MAX_LON || lon() > Projection.MAX_LON;
     90        Bounds b = Main.proj.getWorldBoundsLatLon();
     91        return lat() < b.min.lat() || lat() > b.max.lat() ||
     92            lon() < b.min.lon() || lon() > b.max.lon();
    9193    }
    9294
  • trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java

    r1677 r1722  
    4040    public Collection<WayPoint> waypoints = new LinkedList<WayPoint>();
    4141
    42     public Bounds bounds;
    43 
    4442    public void mergeFrom(GpxData other) {
    4543        if (storageFile == null && other.storageFile != null) {
     
    8280
    8381    // FIXME might perhaps use visitor pattern?
    84     public void recalculateBounds() {
    85         bounds = null;
     82    public Bounds recalculateBounds() {
     83        Bounds bounds = null;
    8684        for (WayPoint wpt : waypoints) {
    8785            if (bounds == null) {
     
    111109            }
    112110        }
    113         if (bounds == null) {
    114             bounds = new Bounds();
    115         }
     111        return bounds;
    116112    }
    117113
  • trunk/src/org/openstreetmap/josm/data/osm/Node.java

    r1690 r1722  
    88import org.openstreetmap.josm.data.coor.LatLon;
    99import org.openstreetmap.josm.data.coor.LatLon.CoordinateFormat;
     10import org.openstreetmap.josm.data.projection.Projection;
    1011import org.openstreetmap.josm.data.osm.visitor.Visitor;
     12import org.openstreetmap.josm.data.osm.Node;
    1113
    1214
     
    1820public final class Node extends OsmPrimitive {
    1921
    20     public LatLon coor;
    21     public volatile EastNorth eastNorth;
     22    private LatLon coor;
     23
     24    private EastNorth eastNorth;
     25    private Projection proj;
     26
    2227
    2328    public final void setCoor(LatLon coor) {
    2429        this.coor = coor;
    25         this.eastNorth = Main.proj.latlon2eastNorth(coor);
     30        proj = null;
    2631    }
    2732
     
    3136
    3237    public final void setEastNorth(EastNorth eastNorth) {
    33         this.eastNorth = eastNorth;
    34         this.coor = Main.proj.eastNorth2latlon(eastNorth);
    35     }
    36 
    37     public final void setEastNorth(double east, double north) {
    38         this.setEastNorth(new EastNorth(east, north));
     38        proj = Main.proj;
     39        eastNorth = eastNorth;
     40        this.coor = proj.eastNorth2latlon(eastNorth);
    3941    }
    4042
    4143    public final EastNorth getEastNorth() {
     44        if(proj != Main.proj)
     45        {
     46            proj = Main.proj;
     47            eastNorth = proj.latlon2eastNorth(coor);
     48        }
    4249        return eastNorth;
    4350    }
     
    4552    private static CoordinateFormat mCord;
    4653
    47     static {
     54    static public CoordinateFormat getCoordinateFormat()
     55    {
     56        return mCord;
     57    }
     58
     59    static public void setCoordinateFormat()
     60    {
    4861        try {
    4962            mCord = LatLon.CoordinateFormat.valueOf(Main.pref.get("coordinates"));
    5063        } catch (IllegalArgumentException iae) {
    51             mCord =LatLon.CoordinateFormat.DECIMAL_DEGREES;
     64            mCord = LatLon.CoordinateFormat.DECIMAL_DEGREES;
    5265        }
     66    }
     67
     68    static {
     69        setCoordinateFormat();
    5370    }
    5471
     
    7289    }
    7390
     91    public Node(EastNorth eastNorth) {
     92        setEastNorth(eastNorth);
     93    }
     94
    7495    @Override public void visit(Visitor visitor) {
    7596        visitor.visit(this);
     
    7899    @Override public void cloneFrom(OsmPrimitive osm) {
    79100        super.cloneFrom(osm);
    80         coor = ((Node)osm).coor;
    81         eastNorth = ((Node)osm).eastNorth;
     101        setCoor(((Node)osm).coor);
    82102    }
    83103
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java

    r1640 r1722  
    44import org.openstreetmap.josm.Main;
    55import org.openstreetmap.josm.data.Bounds;
     6import org.openstreetmap.josm.data.ProjectionBounds;
    67import org.openstreetmap.josm.data.coor.EastNorth;
    78import org.openstreetmap.josm.data.coor.LatLon;
     
    1920public class BoundingXYVisitor extends AbstractVisitor {
    2021
    21     public EastNorth min, max;
     22    private ProjectionBounds bounds = null;
    2223
    2324    public void visit(Node n) {
     
    3839    }
    3940
     41    public void visit(Bounds b) {
     42        if(b != null)
     43        {
     44            visit(Main.proj.latlon2eastNorth(b.min));
     45            visit(Main.proj.latlon2eastNorth(b.max));
     46        }
     47    }
     48
     49    public void visit(ProjectionBounds b) {
     50        if(b != null)
     51            bounds = new ProjectionBounds(b.min, b.max);
     52    }
     53
    4054    public void visit(EastNorth eastNorth) {
    4155        if (eastNorth != null) {
    42             if (min == null)
    43                 min = eastNorth;
    44             else if (eastNorth.east() < min.east() || eastNorth.north() < min.north())
    45                 min = new EastNorth(Math.min(min.east(), eastNorth.east()), Math.min(min.north(), eastNorth.north()));
     56            if (bounds == null)
     57                bounds = new ProjectionBounds(eastNorth, eastNorth);
     58            else
     59                bounds.extend(eastNorth);
     60        }
     61    }
    4662
    47             if (max == null)
    48                 max = eastNorth;
    49             else if (eastNorth.east() > max.east() || eastNorth.north() > max.north())
    50                 max = new EastNorth(Math.max(max.east(), eastNorth.east()), Math.max(max.north(), eastNorth.north()));
    51         }
     63    public boolean hasExtend()
     64    {
     65        return bounds != null && !bounds.min.equals(bounds.max);
    5266    }
    5367
     
    5569     * @return The bounding box or <code>null</code> if no coordinates have passed
    5670     */
    57     public Bounds getBounds() {
    58         if (min == null || max == null)
    59             return null;
    60         return new Bounds(Main.proj.eastNorth2latlon(min), Main.proj.eastNorth2latlon(max));
     71    public ProjectionBounds getBounds() {
     72        return bounds;
    6173    }
    6274
     
    7890     */
    7991    public void enlargeBoundingBox(double enlargeDegree) {
    80         if (min == null || max == null)
     92        if (bounds == null)
    8193            return;
    82         LatLon minLatlon = Main.proj.eastNorth2latlon(min);
    83         min = Main.proj.latlon2eastNorth(new LatLon(minLatlon.lat() - enlargeDegree, minLatlon.lon() - enlargeDegree));
    84         LatLon maxLatlon = Main.proj.eastNorth2latlon(max);
    85         max = Main.proj.latlon2eastNorth(new LatLon(maxLatlon.lat() + enlargeDegree, maxLatlon.lon() + enlargeDegree));
     94        LatLon minLatlon = Main.proj.eastNorth2latlon(bounds.min);
     95        LatLon maxLatlon = Main.proj.eastNorth2latlon(bounds.max);
     96        bounds = new ProjectionBounds(
     97        Main.proj.latlon2eastNorth(new LatLon(minLatlon.lat() - enlargeDegree, minLatlon.lon() - enlargeDegree)),
     98        Main.proj.latlon2eastNorth(new LatLon(maxLatlon.lat() + enlargeDegree, maxLatlon.lon() + enlargeDegree)));
    8699    }
    87100}
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/MapPaintVisitor.java

    r1696 r1722  
    12741274        useRealWidth = Main.pref.getBoolean("mappaint.useRealWidth",false);
    12751275        zoomLevelDisplay = Main.pref.getBoolean("mappaint.zoomLevelDisplay",false);
    1276         circum = Main.map.mapView.getScale()*100*Main.proj.scaleFactor()*40041455; /* circumference of the earth in meter */
     1276        circum = Main.map.mapView.getMapScale();
    12771277        styles = MapPaintStyles.getStyles().getStyleSet();
    12781278        drawMultipolygon = Main.pref.getBoolean("mappaint.multipolygon",true);
  • trunk/src/org/openstreetmap/josm/data/projection/Epsg4326.java

    r1309 r1722  
    11// License: GPL. Copyright 2007 by Immanuel Scholz and others
    22package org.openstreetmap.josm.data.projection;
     3
    34import static org.openstreetmap.josm.tools.I18n.tr;
     5
    46import org.openstreetmap.josm.data.coor.LatLon;
    57import org.openstreetmap.josm.data.coor.EastNorth;
     8import org.openstreetmap.josm.data.Bounds;
     9import org.openstreetmap.josm.data.ProjectionBounds;
    610
    711/**
     
    3236    }
    3337
    34     public double scaleFactor() {
    35         return 1.0/360;
    36     }
    37 
    3838    @Override public boolean equals(Object o) {
    3939        return o instanceof Epsg4326;
    4040    }
    4141
    42     @Override public int hashCode() {
    43         return Epsg4326.class.hashCode();
     42    public ProjectionBounds getWorldBounds()
     43    {
     44        Bounds b = getWorldBoundsLatLon();
     45        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
     46    }
     47
     48    public Bounds getWorldBoundsLatLon()
     49    {
     50        return new Bounds(
     51        new LatLon(-90.0, -180.0),
     52        new LatLon(90.0, 180.0));
    4453    }
    4554}
  • trunk/src/org/openstreetmap/josm/data/projection/Lambert.java

    r1583 r1722  
    1212import org.openstreetmap.josm.data.coor.EastNorth;
    1313import org.openstreetmap.josm.data.coor.LatLon;
     14import org.openstreetmap.josm.data.Bounds;
     15import org.openstreetmap.josm.data.ProjectionBounds;
    1416
    1517public class Lambert implements Projection {
     
    104106        } else {
    105107            outOfLambertZones = true; // possible when MAX_LAT is used
    106             if (p.lat() != 0 && Math.abs(p.lat()) != Projection.MAX_LAT
    107                     && p.lon() != 0 && Math.abs(p.lon()) != Projection.MAX_LON
    108                     && dontDisplayErrors == false) {
    109                 JOptionPane.showMessageDialog(Main.parent,
    110                         tr("The projection \"{0}\" is designed for\n"
    111                         + "latitudes between 46.1\u00b0 and 57\u00b0 only.\n"
    112                         + "Use another projection system if you are not using\n"
    113                         + "a French WMS server.\n"
    114                         + "Do not upload any data after this message.", this.toString()));
    115                 dontDisplayErrors = true;
    116             }
    117108        }
    118109        if (!outOfLambertZones) {
     
    167158    }
    168159
    169     public double scaleFactor() {
    170         return 1.0 / 360;
    171     }
    172 
    173160    @Override
    174161    public boolean equals(Object o) {
    175162        return o instanceof Lambert;
    176     }
    177 
    178     @Override
    179     public int hashCode() {
    180         return Lambert.class.hashCode();
    181163    }
    182164
     
    300282    }
    301283
     284    public ProjectionBounds getWorldBounds()
     285    {
     286        Bounds b = getWorldBoundsLatLon();
     287        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
     288    }
     289
     290    public Bounds getWorldBoundsLatLon()
     291    {
     292        return new Bounds(
     293        new LatLon(-90.0, -180.0),
     294        new LatLon(90.0, 180.0));
     295    }
    302296}
  • trunk/src/org/openstreetmap/josm/data/projection/LambertEST.java

    r1309 r1722  
    99import org.openstreetmap.josm.data.coor.EastNorth;
    1010import org.openstreetmap.josm.data.coor.LatLon;
     11import org.openstreetmap.josm.data.Bounds;
     12import org.openstreetmap.josm.data.ProjectionBounds;
    1113
    1214public class LambertEST implements Projection {
     
    105107    }
    106108
    107     public double scaleFactor() {
    108         return 1.0 / 360;
    109     }
    110 
    111109    @Override
    112110    public boolean equals(Object o) {
     
    114112    }
    115113
    116     @Override
    117     public int hashCode() {
    118         return LambertEST.class.hashCode();
     114    public ProjectionBounds getWorldBounds()
     115    {
     116        Bounds b = getWorldBoundsLatLon();
     117        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
     118    }
     119
     120    public Bounds getWorldBoundsLatLon()
     121    {
     122        return new Bounds(
     123        new LatLon(-90.0, -180.0),
     124        new LatLon(90.0, 180.0));
    119125    }
    120126}
  • trunk/src/org/openstreetmap/josm/data/projection/Mercator.java

    r1644 r1722  
    66import org.openstreetmap.josm.data.coor.EastNorth;
    77import org.openstreetmap.josm.data.coor.LatLon;
     8import org.openstreetmap.josm.data.Bounds;
     9import org.openstreetmap.josm.data.ProjectionBounds;
    810
    911/**
     
    4547    }
    4648
    47     public double scaleFactor() {
    48         return 1/Math.PI/2;
    49     }
    50 
    5149    @Override public boolean equals(Object o) {
    5250        return o instanceof Mercator;
    5351    }
    5452
    55     @Override public int hashCode() {
    56         return Mercator.class.hashCode();
     53    public ProjectionBounds getWorldBounds()
     54    {
     55        Bounds b = getWorldBoundsLatLon();
     56        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
     57    }
     58
     59    public Bounds getWorldBoundsLatLon()
     60    {
     61        return new Bounds(
     62        new LatLon(-85.05112877980659, -180.0),
     63        new LatLon(85.05112877980659, 180.0));
    5764    }
    5865}
  • trunk/src/org/openstreetmap/josm/data/projection/Projection.java

    r1582 r1722  
    44import org.openstreetmap.josm.data.coor.EastNorth;
    55import org.openstreetmap.josm.data.coor.LatLon;
     6import org.openstreetmap.josm.data.Bounds;
     7import org.openstreetmap.josm.data.ProjectionBounds;
    68
    79/**
     
    1214 */
    1315public interface Projection {
    14 
    15     /**
    16      * Maximum latitude representable.
    17      */
    18     public static final double MAX_LAT = 85.05112877980659; // Mercator squares the world
    19 
    20     /**
    21      * Maximum longditude representable.
    22      */
    23     public static final double MAX_LON = 180;
    24 
    2516    /**
    2617     * Minimum difference in location to not be represented as the same position.
     
    3627        new Lambert(),
    3728        new LambertEST(),
    38         new SwissGrid()
     29        new SwissGrid(),
     30        new UTM()
    3931    };
    4032
     
    6961
    7062    /**
    71      * The factor to multiply with an easting coordinate to get from "easting
    72      * units per pixel" to "meters per pixel"
     63     * Get the bounds of the world
    7364     */
    74     double scaleFactor();
     65    ProjectionBounds getWorldBounds();
     66    Bounds getWorldBoundsLatLon();
    7567}
  • trunk/src/org/openstreetmap/josm/data/projection/SwissGrid.java

    r1583 r1722  
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66
    7 import javax.swing.JOptionPane;
    8 
    97import org.openstreetmap.josm.Main;
    108import org.openstreetmap.josm.data.coor.EastNorth;
    119import org.openstreetmap.josm.data.coor.LatLon;
     10import org.openstreetmap.josm.data.Bounds;
     11import org.openstreetmap.josm.data.ProjectionBounds;
    1212
    1313/**
     
    1919 */
    2020public class SwissGrid implements Projection {
    21     private boolean doAlertOnCoordinatesOufOfRange = true;
    22 
    23     /**
    24      * replies true if if wgs is in or reasonably close to Switzerland. False otherwise.
    25      *
    26      * @param wgs  lat/lon in WGS89
    27      * @return
    28      */
    29     protected boolean latlonInAcceptableRange(LatLon wgs) {
    30         // coordinate transformation is invoked for boundary values regardless
    31         // of current data set.
    32         //
    33         if (Math.abs(wgs.lon()) == Projection.MAX_LON && Math.abs(wgs.lat()) == Projection.MAX_LAT) {
    34             return true;
    35         }
    36         return   wgs.lon() >= 5.7 && wgs.lon() <= 10.6
    37                && wgs.lat() >= 45.7 && wgs.lat() <= 47.9;
    38     }
    39 
    40     /**
    41      * displays an alert if lat/lon are not reasonably close to Switzerland.
    42      */
    43     protected void alertCoordinatesOutOfRange() {
    44         JOptionPane.showMessageDialog(Main.parent,
    45                 tr("The projection \"{0}\" is designed for\n"
    46                 + "latitudes between 45.7\u00b0 and 47.9\u00b0\n"
    47                 + "and longitutes between 5.7\u00b0 and 10.6\u00b0 only.\n"
    48                 + "Use another projection system if you are not working\n"
    49                 + "on a data set of Switzerland or Liechtenstein.\n"
    50                 + "Do not upload any data after this message.", this.toString()),
    51                 "Current projection not suitable",
    52                 JOptionPane.WARNING_MESSAGE
    53         );
    54         doAlertOnCoordinatesOufOfRange = false;
    55     }
    56 
    5721    /**
    5822     * @param wgs  WGS84 lat/lon (ellipsoid GRS80) (in degree)
     
    6024     */
    6125    public EastNorth latlon2eastNorth(LatLon wgs) {
    62             if (!latlonInAcceptableRange(wgs)) {
    63                 if (doAlertOnCoordinatesOufOfRange) {
    64                     alertCoordinatesOutOfRange();
    65                 }
    66             }
    67 
    6826            double phi = 3600d * wgs.lat();
    6927            double lambda = 3600d * wgs.lon();
     
    13189    }
    13290
    133     public double scaleFactor() {
    134         return 1.0;
    135     }
    136 
    13791    @Override public String toString() {
    13892        return tr("Swiss Grid (Switzerland)");
     
    152106    }
    153107
    154     @Override
    155     public int hashCode() {
    156         return SwissGrid.class.hashCode();
     108    public ProjectionBounds getWorldBounds()
     109    {
     110        Bounds b = getWorldBoundsLatLon();
     111        return new ProjectionBounds(latlon2eastNorth(b.min), latlon2eastNorth(b.max));
     112    }
     113
     114    public Bounds getWorldBoundsLatLon()
     115    {
     116        return new Bounds(
     117        new LatLon(45.7, 5.7),
     118        new LatLon(47.9, 10.6));
    157119    }
    158120}
  • trunk/src/org/openstreetmap/josm/gui/MapMover.java

    r1677 r1722  
    4444                EastNorth newcenter = nc.getEastNorth(nc.getWidth()/2+nc.getWidth()/5, nc.getHeight()/2+nc.getHeight()/5);
    4545                if (action.equals("left"))
    46                     nc.zoomTo(new EastNorth(2*center.east()-newcenter.east(), center.north()), nc.getScale());
     46                    nc.zoomTo(new EastNorth(2*center.east()-newcenter.east(), center.north()));
    4747                else if (action.equals("right"))
    48                     nc.zoomTo(new EastNorth(newcenter.east(), center.north()), nc.getScale());
     48                    nc.zoomTo(new EastNorth(newcenter.east(), center.north()));
    4949                else if (action.equals("up"))
    50                     nc.zoomTo(new EastNorth(center.east(), 2*center.north()-newcenter.north()), nc.getScale());
     50                    nc.zoomTo(new EastNorth(center.east(), 2*center.north()-newcenter.north()));
    5151                else if (action.equals("down"))
    52                     nc.zoomTo(new EastNorth(center.east(), newcenter.north()), nc.getScale());
     52                    nc.zoomTo(new EastNorth(center.east(), newcenter.north()));
    5353            }
    5454        }
     
    123123            EastNorth center = nc.getCenter();
    124124            EastNorth mouseCenter = nc.getEastNorth(e.getX(), e.getY());
    125             EastNorth p = new EastNorth(
     125            nc.zoomTo(new EastNorth(
    126126                    mousePosMove.east() + center.east() - mouseCenter.east(),
    127                     mousePosMove.north() + center.north() - mouseCenter.north());
    128             nc.zoomTo(p, nc.getScale());
     127                    mousePosMove.north() + center.north() - mouseCenter.north()));
    129128        } else
    130129            endMovement();
     
    182181     */
    183182    public void mouseWheelMoved(MouseWheelEvent e) {
    184         double newScale = nc.getScale() * Math.pow(0.8, - e.getWheelRotation());
    185 
    186         // New center position so that point under the mouse pointer stays the same place as it was before zooming
    187         // You will get the formula by simplifying this expression: newCenter = oldCenter + mouseCoordinatesInNewZoom - mouseCoordinatesInOldZoom
    188         double newX = nc.center.east() - (e.getX() - nc.getWidth()/2.0) * (newScale - nc.scale);
    189         double newY = nc.center.north() + (e.getY() - nc.getHeight()/2.0) * (newScale - nc.scale);
    190 
    191         nc.zoomTo(new EastNorth(newX, newY), newScale);
     183        nc.zoomToFactor(e.getX(), e.getY(), Math.pow(0.8, - e.getWheelRotation()));
    192184    }
    193185
  • trunk/src/org/openstreetmap/josm/gui/MapScaler.java

    r1274 r1722  
    1414import org.openstreetmap.josm.actions.HelpAction.Helpful;
    1515import org.openstreetmap.josm.data.coor.LatLon;
    16 import org.openstreetmap.josm.data.projection.Projection;
    1716
    1817public class MapScaler extends JComponent implements Helpful {
    1918
    2019    private final NavigatableComponent mv;
    21     public MapScaler(NavigatableComponent mv, Projection proj) {
     20    public MapScaler(NavigatableComponent mv) {
    2221        this.mv = mv;
    2322        setSize(100,30);
     
    2625
    2726    @Override public void paint(Graphics g) {
    28         LatLon ll1 = mv.getLatLon(0,0);
    29         LatLon ll2 = mv.getLatLon(100,0);
    30         double dist = ll1.greatCircleDistance(ll2);
     27        double dist = mv.getDist100Pixel();
    3128        String text = dist >= 2000 ? Math.round(dist/100)/10 +" km" : (dist >= 1
    3229        ? Math.round(dist*10)/10 +" m" : "< 1 m");
  • trunk/src/org/openstreetmap/josm/gui/MapSlider.java

    r1677 r1722  
    1111import org.openstreetmap.josm.actions.HelpAction.Helpful;
    1212import org.openstreetmap.josm.data.coor.EastNorth;
     13import org.openstreetmap.josm.data.ProjectionBounds;
     14import org.openstreetmap.josm.Main;
    1315
    1416class MapSlider extends JSlider implements PropertyChangeListener, ChangeListener, Helpful {
     
    2830        if (getModel().getValueIsAdjusting()) return;
    2931
    30         double sizex = this.mv.scale * this.mv.getWidth();
    31         double sizey = this.mv.scale * this.mv.getHeight();
    32         for (int zoom = 0; zoom <= 150; zoom++, sizex *= 1.1, sizey *= 1.1) {
    33             if (sizex > MapView.world.east() || sizey > MapView.world.north()) {
    34                 preventChange=true;
    35                 setValue(zoom);
    36                 preventChange=false;
     32        ProjectionBounds world = Main.proj.getWorldBounds();
     33        ProjectionBounds current = this.mv.getProjectionBounds();
     34
     35        double cur_e = current.max.east()-current.min.east();
     36        double cur_n = current.max.north()-current.min.north();
     37        double e = world.max.east()-world.min.east();
     38        double n = world.max.north()-world.min.north();
     39        int zoom = 0;
     40
     41        while(zoom <= 150) {
     42            e /= 1.1;
     43            n /= 1.1;
     44            if(e < cur_e && n < cur_n)
    3745                break;
    38             }
     46            ++zoom;
    3947        }
     48        preventChange=true;
     49        setValue(zoom);
     50        preventChange=false;
    4051    }
    4152
    4253    public void stateChanged(ChangeEvent e) {
    4354        if (preventChange) return;
    44         EastNorth pos = MapView.world;
    45         for (int zoom = 0; zoom < getValue(); zoom++)
    46             pos = new EastNorth(pos.east()/1.1, pos.north()/1.1);
    47         if (this.mv.getWidth() < this.mv.getHeight())
    48             this.mv.zoomTo(this.mv.center, pos.east()/(this.mv.getWidth()-20));
    49         else
    50             this.mv.zoomTo(this.mv.center, pos.north()/(this.mv.getHeight()-20));
     55
     56        ProjectionBounds world = Main.proj.getWorldBounds();
     57        double fact = Math.pow(1.1, getValue());
     58        double es = world.max.east()-world.min.east();
     59        double n = world.max.north()-world.min.north();
     60
     61        this.mv.zoomTo(new ProjectionBounds(this.mv.getCenter(), es/fact, n/fact));
    5162    }
    5263
  • trunk/src/org/openstreetmap/josm/gui/MapStatus.java

    r1677 r1722  
    3838import org.openstreetmap.josm.actions.HelpAction.Helpful;
    3939import org.openstreetmap.josm.data.coor.LatLon;
     40import org.openstreetmap.josm.data.coor.LatLon.CoordinateFormat;
    4041import org.openstreetmap.josm.data.osm.OsmPrimitive;
    4142import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
     43import org.openstreetmap.josm.data.osm.Node;
    4244import org.openstreetmap.josm.tools.GBC;
    4345import org.openstreetmap.josm.tools.ImageProvider;
     
    8991        }
    9092    }
    91 
    92     LatLon.CoordinateFormat mCord;
    9393
    9494    ImageLabel lonText = new ImageLabel("lon", tr("The geographic longitude at the mouse pointer."), 11);
     
    263263        this.mv = mapFrame.mapView;
    264264
    265         try {
    266             mCord = LatLon.CoordinateFormat.valueOf(Main.pref.get("coordinates"));
    267         } catch (IllegalArgumentException iae) {
    268             mCord =LatLon.CoordinateFormat.DECIMAL_DEGREES;
    269         }
    270265        // Listen for mouse movements and set the position text field
    271266        mv.addMouseMotionListener(new MouseMotionListener(){
     
    278273                // Do not update the view if ctrl is pressed.
    279274                if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == 0) {
     275                    CoordinateFormat mCord = Node.getCoordinateFormat();
    280276                    LatLon p = mv.getLatLon(e.getX(),e.getY());
    281277                    latText.setText(p.latToString(mCord));
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r1685 r1722  
    3030import org.openstreetmap.josm.actions.MoveAction;
    3131import org.openstreetmap.josm.data.Bounds;
     32import org.openstreetmap.josm.data.ProjectionBounds;
    3233import org.openstreetmap.josm.data.SelectionChangedListener;
    3334import org.openstreetmap.josm.data.coor.EastNorth;
     
    9596                zoomSlider.setBounds(3, 0, 114, 30);
    9697
    97                 MapScaler scaler = new MapScaler(MapView.this, Main.proj);
     98                MapScaler scaler = new MapScaler(MapView.this);
    9899                add(scaler);
    99100                scaler.setLocation(10,30);
     
    197198    }
    198199
    199 
    200200    /**
    201201     * Remove the layer from the mapview. If the layer was in the list before,
     
    289289        // draw world borders
    290290        tempG.setColor(Color.WHITE);
    291         Bounds b = new Bounds();
    292         Point min = getPoint(getProjection().latlon2eastNorth(b.min));
    293         Point max = getPoint(getProjection().latlon2eastNorth(b.max));
     291        ProjectionBounds b = getProjection().getWorldBounds();
     292        Point min = getPoint(b.min);
     293        Point max = getPoint(b.max);
    294294        int x1 = Math.min(min.x, max.x);
    295295        int y1 = Math.min(min.y, max.y);
     
    307307
    308308    /**
    309      * Set the new dimension to the projection class. Also adjust the components
    310      * scale, if in autoScale mode.
     309     * Set the new dimension to the view.
    311310     */
    312311    public void recalculateCenterScale(BoundingXYVisitor box) {
    313         // -20 to leave some border
    314         int w = getWidth()-20;
    315         if (w < 20)
    316             w = 20;
    317         int h = getHeight()-20;
    318         if (h < 20)
    319             h = 20;
    320 
    321         EastNorth oldCenter = center;
    322         double oldScale = this.scale;
    323 
    324         if (box == null || box.min == null || box.max == null) {
    325             // no bounds means whole world
    326             center = getProjection().latlon2eastNorth(new LatLon(0,0));
    327             EastNorth world = getProjection().latlon2eastNorth(new LatLon(Projection.MAX_LAT,Projection.MAX_LON));
    328             double scaleX = world.east()*2/w;
    329             double scaleY = world.north()*2/h;
    330             scale = Math.max(scaleX, scaleY); // minimum scale to see all of the screen
    331         } else {
    332             if(box.min.equals(box.max))
    333                 box.enlargeBoundingBox();
    334             center = new EastNorth(box.min.east()/2+box.max.east()/2, box.min.north()/2+box.max.north()/2);
    335             double scaleX = (box.max.east()-box.min.east())/w;
    336             double scaleY = (box.max.north()-box.min.north())/h;
    337             scale = Math.max(scaleX, scaleY); // minimum scale to see all of the screen
    338         }
    339 
    340         if (!center.equals(oldCenter))
    341             firePropertyChange("center", oldCenter, center);
    342         if (oldScale != scale)
    343             firePropertyChange("scale", oldScale, scale);
    344         repaint();
     312        if(box == null)
     313            box = new BoundingXYVisitor();
     314        if(box.getBounds() == null)
     315            box.visit(getProjection().getWorldBounds());
     316        if(!box.hasExtend())
     317             box.enlargeBoundingBox();
     318
     319        zoomTo(box.getBounds());
    345320    }
    346321
     
    392367
    393368    /**
    394      * In addition to the base class funcitonality, this keep trak of the autoscale
    395      * feature.
    396      */
    397     @Override public void zoomTo(EastNorth newCenter, double scale) {
    398         EastNorth oldCenter = center;
    399         double oldScale = this.scale;
    400         super.zoomTo(newCenter, scale);
    401         if ((oldCenter == null && center != null) || !oldCenter.equals(center))
    402             firePropertyChange("center", oldCenter, center);
    403         if (oldScale != scale)
    404             firePropertyChange("scale", oldScale, scale);
    405     }
    406 
    407     /**
    408369     * Tries to zoom to the download boundingbox[es] of the current edit layer
    409370     * (aka {@link OsmDataLayer}). If the edit layer has multiple download bounding
     
    420381        BoundingXYVisitor bbox = new BoundingXYVisitor();
    421382        for (DataSource ds : dataSources) {
    422             if (ds.bounds != null) {
    423                 bbox.visit(Main.proj.latlon2eastNorth(ds.bounds.max));
    424                 bbox.visit(Main.proj.latlon2eastNorth(ds.bounds.min));
    425             }
    426             if (bbox.max != null && bbox.min != null && !bbox.max.equals(bbox.min)) {
     383            bbox.visit(ds.bounds);
     384            if (bbox.hasExtend()) {
    427385                // ... we zoom to it's bounding box
    428386                recalculateCenterScale(bbox);
  • trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java

    r1640 r1722  
    1616import org.openstreetmap.josm.Main;
    1717import org.openstreetmap.josm.actions.HelpAction.Helpful;
     18import org.openstreetmap.josm.data.Bounds;
     19import org.openstreetmap.josm.data.ProjectionBounds;
    1820import org.openstreetmap.josm.data.coor.EastNorth;
    1921import org.openstreetmap.josm.data.coor.LatLon;
     
    2426import org.openstreetmap.josm.data.osm.WaySegment;
    2527import org.openstreetmap.josm.data.projection.Projection;
     28import org.openstreetmap.josm.data.projection.Mercator;
    2629
    2730/**
     
    3336public class NavigatableComponent extends JComponent implements Helpful {
    3437
    35     public static final EastNorth world = Main.proj.latlon2eastNorth(new LatLon(Projection.MAX_LAT, Projection.MAX_LON));
    3638    public static final int snapDistance = sqr(Main.pref.getInteger("node.snap-distance", 10));
    3739
     
    4244     * northing/easting space of the projection.
    4345     */
    44     protected double scale;
     46    private double scale;
    4547    /**
    4648     * Center n/e coordinate of the desired screen center.
     
    5860
    5961    /**
    60      * Return the OSM-conform zoom factor (0 for whole world, 1 for half, 2 for quarter...)
    61      */
    62     public int zoom() {
    63         double sizex = scale * getWidth();
    64         double sizey = scale * getHeight();
    65         for (int zoom = 0; zoom <= 32; zoom++, sizex *= 2, sizey *= 2)
    66             if (sizex > world.east() || sizey > world.north())
    67                 return zoom;
    68         return 32;
    69     }
    70 
    71     /**
    7262     * Return a ID which is unique as long as viewport dimensions are the same
    7363     */
     
    7565    {
    7666        String x = center.east() + "_" + center.north() + "_" + scale + "_" +
    77         getWidth() + "_" + getHeight();
     67        getWidth() + "_" + getHeight() + "_" + getProjection().toString();
    7868        java.util.zip.CRC32 id = new java.util.zip.CRC32();
    7969        id.update(x.getBytes());
     
    8171    }
    8272
    83     /**
    84      * Return the current scale value.
    85      * @return The scale value currently used in display
    86      */
    87     public double getScale() {
    88         return scale;
     73    public double getMapScale() {
     74        /* TODO: we assume a pixel is 0.025mm */
     75        return getDist100Pixel()/(0.00025*100);
     76    }
     77
     78    public double getDist100Pixel()
     79    {
     80        LatLon ll1 = getLatLon(0,0);
     81        LatLon ll2 = getLatLon(100,0);
     82        return ll1.greatCircleDistance(ll2);
    8983    }
    9084
     
    110104    }
    111105
     106    public ProjectionBounds getProjectionBounds() {
     107        return new ProjectionBounds(
     108        new EastNorth(
     109                center.east() - getWidth()/2.0*scale,
     110                center.north() - getHeight()/2.0*scale),
     111        new EastNorth(
     112                center.east() + getWidth()/2.0*scale,
     113                center.north() + getHeight()/2.0*scale));
     114    };
     115
     116    public Bounds getRealBounds() {
     117        return new Bounds(
     118        getProjection().eastNorth2latlon(new EastNorth(
     119                center.east() - getWidth()/2.0*scale,
     120                center.north() - getHeight()/2.0*scale)),
     121        getProjection().eastNorth2latlon(new EastNorth(
     122                center.east() + getWidth()/2.0*scale,
     123                center.north() + getHeight()/2.0*scale)));
     124    };
     125
    112126    /**
    113127     * @param x X-Pixelposition to get coordinate from
     
    118132     */
    119133    public LatLon getLatLon(int x, int y) {
    120 
    121134        return getProjection().eastNorth2latlon(getEastNorth(x, y));
    122135    }
     
    141154     * @param scale The scale to use.
    142155     */
    143     public void zoomTo(EastNorth newCenter, double scale) {
    144         center = newCenter;
    145         getProjection().eastNorth2latlon(center);
    146         this.scale = scale;
    147         repaint();
     156    private void zoomTo(EastNorth newCenter, double newScale) {
     157/* TODO: check that newCenter is really inside visible world and that scale is correct, don't allow zooming out to much */
     158        boolean rep = false;
     159        if(!newCenter.equals(center))
     160        {
     161            EastNorth oldCenter = center;
     162            center = newCenter;
     163            rep = true;
     164            firePropertyChange("center", oldCenter, newCenter);
     165        }
     166        if(scale != newScale)
     167        {
     168            double oldScale = scale;
     169            scale = newScale;
     170            rep = true;
     171            firePropertyChange("scale", oldScale, newScale);
     172        }
     173        if(rep)
     174            repaint();
     175    }
     176
     177    public void zoomTo(EastNorth newCenter) {
     178        zoomTo(newCenter, scale);
     179    }
     180
     181    public void zoomToFactor(double x, double y, double factor) {
     182        double newScale = scale*factor;
     183        // New center position so that point under the mouse pointer stays the same place as it was before zooming
     184        // You will get the formula by simplifying this expression: newCenter = oldCenter + mouseCoordinatesInNewZoom - mouseCoordinatesInOldZoom
     185        zoomTo(new EastNorth(
     186        center.east() - (x - getWidth()/2.0) * (newScale - scale),
     187        center.north() + (y - getHeight()/2.0) * (newScale - scale)),
     188        newScale);
     189    }
     190
     191    public void zoomToFactor(EastNorth newCenter, double factor) {
     192        zoomTo(newCenter, scale*factor);
     193    }
     194
     195    public void zoomToFactor(double factor) {
     196        zoomTo(center, scale*factor);
     197    }
     198
     199    public void zoomTo(ProjectionBounds box) {
     200        // -20 to leave some border
     201        int w = getWidth()-20;
     202        if (w < 20)
     203            w = 20;
     204        int h = getHeight()-20;
     205        if (h < 20)
     206            h = 20;
     207
     208        double scaleX = (box.max.east()-box.min.east())/w;
     209        double scaleY = (box.max.north()-box.min.north())/h;
     210        double newScale = Math.max(scaleX, scaleY);
     211
     212        zoomTo(box.getCenter(), newScale);
     213    }
     214
     215    public void zoomTo(Bounds box) {
     216        zoomTo(new ProjectionBounds(getProjection().latlon2eastNorth(box.min),
     217        getProjection().latlon2eastNorth(box.max)));
    148218    }
    149219
  • trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java

    r1677 r1722  
    207207                ((OsmPrimitive) o).visit(box);
    208208        }
    209         if (box.max == null || box.min == null)
     209        if (box.getBounds() == null)
    210210            return;
    211211        box.enlargeBoundingBox();
  • trunk/src/org/openstreetmap/josm/gui/download/BoundingBoxSelection.java

    r1677 r1722  
    2121
    2222import org.openstreetmap.josm.data.Bounds;
     23import org.openstreetmap.josm.data.coor.LatLon;
    2324import org.openstreetmap.josm.tools.GBC;
    2425import org.openstreetmap.josm.tools.OsmUrlToBounds;
     
    162163
    163164    private void updateUrl(DownloadDialog gui) {
    164         double lat = (gui.minlat + gui.maxlat)/2;
    165         double lon = (gui.minlon + gui.maxlon)/2;
    166         // convert to mercator (for calculation of zoom only)
    167         double latMin = Math.log(Math.tan(Math.PI/4.0+gui.minlat/180.0*Math.PI/2.0))*180.0/Math.PI;
    168         double latMax = Math.log(Math.tan(Math.PI/4.0+gui.maxlat/180.0*Math.PI/2.0))*180.0/Math.PI;
    169         double size = Math.max(Math.abs(latMax-latMin), Math.abs(gui.maxlon-gui.minlon));
    170         int zoom = 0;
    171         while (zoom <= 20) {
    172             if (size >= 180)
    173                 break;
    174             size *= 2;
    175             zoom++;
    176         }
    177         // Truncate lat and lon to something more sensible
    178         int decimals = (int) Math.pow(10, (zoom / 3));
    179         lat = Math.round(lat * decimals);
    180         lat /= decimals;
    181         lon = Math.round(lon * decimals);
    182         lon /= decimals;
    183         showUrl.setText("http://www.openstreetmap.org/?lat="+lat+"&lon="+lon+"&zoom="+zoom);
     165        showUrl.setText(OsmUrlToBounds.getURL(new Bounds(
     166        new LatLon(gui.minlat, gui.minlon), new LatLon(gui.maxlat, gui.maxlon))));
    184167    }
    185168}
  • trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java

    r1704 r1722  
    536536
    537537            if (centerToggle.getModel().isSelected())
    538                 Main.map.mapView.zoomTo(currentImageEntry.pos, Main.map.mapView.getScale());
     538                Main.map.mapView.zoomTo(currentImageEntry.pos);
    539539
    540540            dlg.setTitle(currentImageEntry.image +
  • trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java

    r1180 r1722  
    1313
    1414import org.openstreetmap.josm.Main;
     15import org.openstreetmap.josm.data.projection.Mercator;
    1516import org.openstreetmap.josm.data.projection.Projection;
    1617import org.openstreetmap.josm.data.coor.LatLon.CoordinateFormat;
     18import org.openstreetmap.josm.data.osm.Node;
    1719import org.openstreetmap.josm.tools.GBC;
    1820
     
    2830
    2931        for (int i = 0; i < projectionCombo.getItemCount(); ++i) {
    30             if (projectionCombo.getItemAt(i).getClass().getName().equals(Main.pref.get("projection"))) {
     32            if (projectionCombo.getItemAt(i).getClass().getName().equals(Main.pref.get("projection", Mercator.class.getName()))) {
    3133                projectionCombo.setSelectedIndex(i);
    3234                break;
     
    5456
    5557    public boolean ok() {
    56         boolean restart = Main.pref.put("projection",
    57         projectionCombo.getSelectedItem().getClass().getName());
     58        String projname = projectionCombo.getSelectedItem().getClass().getName();
     59        if(Main.pref.put("projection", projname))
     60            Main.setProjection(projname);
    5861        if(Main.pref.put("coordinates",
    5962        ((CoordinateFormat)coordinatesCombo.getSelectedItem()).name()))
    60             restart = true;
    61         return restart;
     63            Node.setCoordinateFormat();
     64        return false;
    6265    }
    6366}
  • trunk/src/org/openstreetmap/josm/io/GpxWriter.java

    r1677 r1722  
    121121        if (attr.containsKey(GpxData.META_KEYWORDS)) simpleTag("keywords", (String)attr.get(GpxData.META_KEYWORDS));
    122122
    123         data.recalculateBounds();
    124         Bounds bounds = data.bounds;
    125         String b = "minlat=\"" + bounds.min.lat() + "\" minlon=\"" + bounds.min.lon() +
    126             "\" maxlat=\"" + bounds.max.lat() + "\" maxlon=\"" + bounds.max.lon() + "\"" ;
    127         inline("bounds", b);
     123        Bounds bounds = data.recalculateBounds();
     124        if(bounds != null)
     125        {
     126            String b = "minlat=\"" + bounds.min.lat() + "\" minlon=\"" + bounds.min.lon() +
     127                "\" maxlat=\"" + bounds.max.lat() + "\" maxlon=\"" + bounds.max.lon() + "\"" ;
     128            inline("bounds", b);
     129        }
    128130
    129131        closeln("metadata");
  • trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java

    r1689 r1722  
    5555        return Double.parseDouble(map.get("m"+key));
    5656    }
     57
     58    static public int getZoom(Bounds b)
     59    {
     60        // convert to mercator (for calculation of zoom only)
     61        double latMin = Math.log(Math.tan(Math.PI/4.0+b.min.lat()/180.0*Math.PI/2.0))*180.0/Math.PI;
     62        double latMax = Math.log(Math.tan(Math.PI/4.0+b.max.lat()/180.0*Math.PI/2.0))*180.0/Math.PI;
     63        double size = Math.max(Math.abs(latMax-latMin), Math.abs(b.max.lon()-b.min.lon()));
     64        int zoom = 0;
     65        while (zoom <= 20) {
     66            if (size >= 180)
     67                break;
     68            size *= 2;
     69            zoom++;
     70        }
     71        return zoom;
     72    }
     73
     74    static public String getURL(Bounds b)
     75    {
     76        return getURL(b.center(), getZoom(b));
     77    }
     78
     79    static public String getURL(LatLon pos, int zoom)
     80    {
     81        // Truncate lat and lon to something more sensible
     82        int decimals = (int) Math.pow(10, (zoom / 3));
     83        double lat = (Math.round(pos.lat() * decimals))/decimals;
     84        double lon = (Math.round(pos.lon() * decimals))/decimals;
     85        return new String("http://www.openstreetmap.org/?lat="+lat+"&lon="+lon+"&zoom="+zoom);
     86    }
    5787}
Note: See TracChangeset for help on using the changeset viewer.