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/data/projection
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • 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}
Note: See TracChangeset for help on using the changeset viewer.