Changeset 9565 in josm


Ignore:
Timestamp:
2016-01-22T16:50:40+01:00 (8 years ago)
Author:
bastiK
Message:

add 2 standard parallel & non-spherical variants for Mercator projection (see #12186)
(imports pieces of code from the Geotools project)

Location:
trunk
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/data_nodist/projection/josm-epsg

    r9532 r9565  
    5353# Belgian Lambert 2008
    5454<3812> +proj=lcc +lat_0=50d47'52.134" +lat_1=49d50'0" +lat_2=51d10'0" +lon_0=4d21'33.177" +x_0=649328 +y_0=665262 +ellps=GRS80 +nadgrids=null +units=m +bounds=2.54,49.51,6.4,51.5  <>
    55 # Pseudo-Mercator
    56 <3857> +proj=josm:smerc +datum=WGS84 +units=m +bounds=-180,-85.05112877980659,180,85.05112877980659 <>
     55# WGS 84 / Pseudo-Mercator
     56<3857> +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +bounds=-180,-85.05112877980659,180,85.05112877980659 <>
    5757# Lambert CC9 (France) Zone 42
    5858<3942> +proj=lcc +lat_0=42 +lat_1=41.25 +lat_2=42.75 +lon_0=3 +x_0=1700000 +y_0=1200000 +ellps=GRS80 +nadgrids=null +units=m +bounds=-5.5,41,10.2,44.5  <>
  • trunk/data_nodist/projection/projection-regression-test-data

    r9560 r9565  
    59455945  en  -193969.4282884883 8469842.549172236
    59465946  ll2 -13.760992483199203 38.60194124510362
     5947EPSG:3000
     5948  ll  31.910053601835273 18.106211343257215
     5949  en  -6298607.693804365 4617158.822506971
     5950  ll2 31.910053822996915 18.10621242764793
     5951EPSG:3001
     5952  ll  35.517579866263844 152.3184248561901
     5953  en  8596711.674334003 5097011.9228557665
     5954  ll2 35.51757975669143 152.31842469563856
     5955EPSG:3002
     5956  ll  11.457376033055027 163.93490862689723
     5957  en  9885642.748954434 2171556.0805702494
     5958  ll2 11.457376033600664 163.9349086202522
    59475959EPSG:3003
    59485960  ll  38.09725651416973 7.4345625019044315
     
    95419553  en  6480276.344184 1151844.8226038879
    95429554  ll2 10.291404319051509 41.91402761717174
     9555EPSG:3388
     9556  ll  -73.24907273227738 126.72589597701531
     9557  en  6273844.747247949 -9063422.188490324
     9558  ll2 -73.24907270081529 126.72589592872397
    95439559EPSG:3389
    95449560  ll  -14.438886660384838 173.46408675562256
     
    95659581  en  4744317.466116981 -1532445.4287352874
    95669582  ll2 5.39523547581824 71.65431390978326
     9583EPSG:3395
     9584  ll  -55.07366715935213 -39.25832129180364
     9585  en  -4370216.3356023105 -7341116.553800662
     9586  ll2 -55.073667159347856 -39.25832129180364
    95679587EPSG:3396
    95689588  ll  85.94787390828097 5.998729693776394
     
    1117311193  en  578839.8963415996 9495341.810721355
    1117411194  ll2 85.4401286193869 132.0129193956132
     11195EPSG:3832
     11196  ll  73.69237557115602 34.57071836335369
     11197  en  -1.284952885442483E7 1.23513911708691E7
     11198  ll2 73.69237557115602 34.57071836335369
    1117511199EPSG:3833
    1117611200  ll  -40.122015589116714 8.310180221924293
     
    1146111485  en  4313912.928101179 3313513.266237703
    1146211486  ll2 41.9479651127952 -20.193469561386244
     11487EPSG:3994
     11488  ll  -50.71638723313427 160.46719257754955
     11489  en  5087418.440840361 -4941555.3324789135
     11490  ll2 -50.716387233124316 160.46719257754955
    1146311491EPSG:3995
    1146411492  ll  -58.51924034223759 170.25401704511552
     
    1440514433  en  3110069.5559353866 -4317519.519979515
    1440614434  ll2 25.078168139707362 -7.402209063825693
     14435EPSG:5329
     14436  ll  -23.170901896645304 -57.605842799307936
     14437  en  -1.4699694275369853E7 -1727381.2603731817
     14438  ll2 -23.170902573741188 -57.605842740240085
     14439EPSG:5330
     14440  ll  12.9779121381478 142.08163488900027
     14441  en  7460496.874071628 2343321.8977075103
     14442  ll2 12.977912125247077 142.08163486687238
     14443EPSG:5331
     14444  ll  -4.523931631753413 -57.62016766238983
     14445  en  -1.4701037559979454E7 400716.72736424254
     14446  ll2 -4.523931469991159 -57.620168125269096
    1440714447EPSG:5337
    1440814448  ll  -0.4402497156128504 -35.57669067759142
     
    1476914809  en  4181126.435413616 2483990.525243229
    1477014810  ll2 49.02916195063009 12.564236704801566
     14811EPSG:5641
     14812  ll  -49.93383931217301 40.41312972718575
     14813  en  1.4279888478912478E7 3601767.464654859
     14814  ll2 -49.933839312161766 40.413129727185755
    1477114815EPSG:5643
    1477214816  ll  41.66055483285982 31.866237633592732
  • trunk/src/org/openstreetmap/josm/data/projection/CustomProjection.java

    r9562 r9565  
    2727import org.openstreetmap.josm.data.projection.datum.WGS84Datum;
    2828import org.openstreetmap.josm.data.projection.proj.ICentralMeridianProvider;
     29import org.openstreetmap.josm.data.projection.proj.IScaleFactorProvider;
    2930import org.openstreetmap.josm.data.projection.proj.Mercator;
    3031import org.openstreetmap.josm.data.projection.proj.Proj;
     
    274275                this.k0 = parseDouble(s, Param.k_0.key);
    275276            }
     277            if (proj instanceof IScaleFactorProvider) {
     278                this.k0 *= ((IScaleFactorProvider) proj).getScaleFactor();
     279            }
    276280            s = parameters.get(Param.bounds.key);
    277281            if (s != null) {
  • trunk/src/org/openstreetmap/josm/data/projection/Ellipsoid.java

    r9419 r9565  
    132132
    133133    /**
     134     * if ellipsoid is spherical, i.e.&nbsp;the major and minor semiaxis are
     135     * the same
     136     */
     137    public final boolean spherical;
     138
     139    /**
    134140     * private constructur - use one of the create_* methods
    135141     *
     
    139145     * @param e2 first eccentricity squared
    140146     * @param eb2 square of the second eccentricity
    141      */
    142     private Ellipsoid(double a, double b, double e, double e2, double eb2) {
     147     * @param sperical if the ellipsoid is sphere
     148     */
     149    private Ellipsoid(double a, double b, double e, double e2, double eb2, boolean sperical) {
    143150        this.a = a;
    144151        this.b = b;
     
    146153        this.e2 = e2;
    147154        this.eb2 = eb2;
     155        this.spherical = sperical;
    148156    }
    149157
     
    159167        double e = Math.sqrt(e2);
    160168        double eb2 = e2 / (1.0 - e2);
    161         return new Ellipsoid(a, b, e, e2, eb2);
     169        return new Ellipsoid(a, b, e, e2, eb2, a == b);
    162170    }
    163171
     
    173181        double e = Math.sqrt(es);
    174182        double eb2 = es / (1.0 - es);
    175         return new Ellipsoid(a, b, e, es, eb2);
     183        return new Ellipsoid(a, b, e, es, eb2, es == 0);
    176184    }
    177185
     
    188196        double e = Math.sqrt(e2);
    189197        double eb2 = e2 / (1.0 - e2);
    190         return new Ellipsoid(a, b, e, e2, eb2);
     198        return new Ellipsoid(a, b, e, e2, eb2, f == 0);
    191199    }
    192200
     
    334342        return new LatLon(Math.toDegrees(lt), Math.toDegrees(lg));
    335343    }
    336    
     344
    337345    /**
    338346     * convert ellipsoidal coordinates to cartesian coordinates
  • trunk/src/org/openstreetmap/josm/data/projection/Projections.java

    r9560 r9565  
    8989        registerBaseProjection("aea", AlbersEqualArea.class, "core");
    9090        registerBaseProjection("cass", CassiniSoldner.class, "core");
    91         registerBaseProjection("josm:smerc", Mercator.class, "core");
    9291        registerBaseProjection("laea", LambertAzimuthalEqualArea.class, "core");
    9392        registerBaseProjection("lcc", LambertConformalConic.class, "core");
    9493        registerBaseProjection("lonlat", LonLat.class, "core");
     94        registerBaseProjection("merc", Mercator.class, "core");
    9595        registerBaseProjection("omerc", ObliqueMercator.class, "core");
    9696        registerBaseProjection("somerc", SwissObliqueMercator.class, "core");
  • trunk/src/org/openstreetmap/josm/data/projection/proj/AbstractProj.java

    r9558 r9565  
    7474     */
    7575    protected double e2;
     76   
     77    /**
     78     * is ellipsoid spherical?
     79     * @see Ellisoid.spherical
     80     */
     81    protected boolean spherical;
    7682
    7783    @Override
     
    7985        e2 = params.ellps.e2;
    8086        e = params.ellps.e;
     87        spherical = params.ellps.spherical;
    8188        //  Compute constants for the mlfn
    8289        double t;
  • trunk/src/org/openstreetmap/josm/data/projection/proj/Mercator.java

    r9124 r9565  
    22package org.openstreetmap.josm.data.projection.proj;
    33
    4 import static java.lang.Math.PI;
    5 import static java.lang.Math.atan;
    6 import static java.lang.Math.log;
    7 import static java.lang.Math.sinh;
    8 import static java.lang.Math.tan;
    94import static org.openstreetmap.josm.tools.I18n.tr;
    105
     
    138
    149/**
    15  * Mercator Projection.
     10 * Mercator Cylindrical Projection. The parallels and the meridians are straight lines and
     11 * cross at right angles; this projection thus produces rectangular charts. The scale is true
     12 * along the equator (by default) or along two parallels equidistant of the equator (if a scale
     13 * factor other than 1 is used). This projection is used to represent areas close to the equator.
     14 * It is also often used for maritime navigation because all the straight lines on the chart are
     15 * <em>loxodrome</em> lines, i.e. a ship following this line would keep a constant azimuth on its
     16 * compass.
     17 * <p>
     18 * This implementation handles both the 1 and 2 stardard parallel cases.
     19 * For 1 SP (EPSG code 9804), the line of contact is the equator.
     20 * For 2 SP (EPSG code 9805) lines of contact are symmetrical
     21 * about the equator.
     22 * <p>
     23 * This class has been derived from the implementation of the Geotools project;
     24 * git 8cbf52d, org.geotools.referencing.operation.projection.CassiniSoldner
     25 * at the time of migration.
     26 * <p>
     27 * <b>References:</b>
     28 * <ul>
     29 *   <li>John P. Snyder (Map Projections - A Working Manual,<br>
     30 *       U.S. Geological Survey Professional Paper 1395, 1987)</li>
     31 *   <li>"Coordinate Conversions and Transformations including Formulas",<br>
     32 *       EPSG Guidence Note Number 7, Version 19.</li>
     33 * </ul>
     34 *
     35 * @see <A HREF="http://mathworld.wolfram.com/MercatorProjection.html">Mercator projection on MathWorld</A>
     36 * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/mercator_1sp.html">"mercator_1sp" on RemoteSensing.org</A>
     37 * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/mercator_2sp.html">"mercator_2sp" on RemoteSensing.org</A>
     38 *
     39 * @author André Gosselin
     40 * @author Martin Desruisseaux (PMO, IRD)
     41 * @author Rueben Schulz
     42 * @author Simone Giannecchini
    1643 */
    17 public class Mercator implements Proj {
     44public class Mercator extends AbstractProj implements IScaleFactorProvider {
     45    /**
     46     * Maximum difference allowed when comparing real numbers.
     47     */
     48    private static final double EPSILON = 1E-6;
     49
     50    protected double scaleFactor;
    1851
    1952    @Override
     
    2457    @Override
    2558    public String getProj4Id() {
    26         return "josm:smerc"; // "merc" is ellipsoidal Mercator projection in PROJ.4
     59        return "merc";
    2760    }
    2861
    2962    @Override
    3063    public void initialize(ProjParameters params) throws ProjectionConfigurationException {
     64        super.initialize(params);
     65        scaleFactor = 1;
     66        if (params.lat_ts != null) {
     67            /*
     68             * scaleFactor is not a parameter in the 2 SP case and is computed from
     69             * the standard parallel.
     70             */
     71            double standardParallel = Math.toRadians(params.lat_ts);
     72            if (spherical) {
     73                scaleFactor *= Math.cos(standardParallel);
     74            }  else {
     75                scaleFactor *= msfn(Math.sin(standardParallel), Math.cos(standardParallel));
     76            }
     77        }
     78        /*
     79         * A correction that allows us to employs a latitude of origin that is not
     80         * correspondent to the equator. See Snyder and al. for reference, page 47.
     81         */
     82        if (params.lat0 != null) {
     83            final double lat0 = Math.toRadians(params.lat0);
     84            final double sinPhi = Math.sin(lat0);
     85            scaleFactor *= (Math.cos(lat0) / (Math.sqrt(1 - e2 * sinPhi * sinPhi)));
     86        }
    3187    }
    3288
    3389    @Override
    34     public double[] project(double lat_rad, double lon_rad) {
    35         return new double[] {lon_rad, log(tan(PI/4 + lat_rad/2))};
     90    public double[] project(double y, double x) {
     91        if (Math.abs(y) > (Math.PI/2 - EPSILON)) {
     92            return new double[] {0, 0}; // this is an error and should be handled somehow
     93        }
     94        if (spherical) {
     95            y = Math.log(Math.tan(Math.PI/4 + 0.5*y));
     96        } else {
     97            y = -Math.log(tsfn(y, Math.sin(y)));
     98        }
     99        return new double[] {x, y};
    36100    }
    37101
    38102    @Override
    39     public double[] invproject(double east, double north) {
    40         return new double[] {atan(sinh(north)), east};
     103    public double[] invproject(double x, double y) {
     104        if (spherical) {
     105            y = Math.PI/2 - 2.0*Math.atan(Math.exp(-y));
     106        } else {
     107            y = Math.exp(-y);
     108            y = cphi2(y);
     109        }
     110        return new double[] {y, x};
    41111    }
    42112
     
    45115        return new Bounds(-89, -180, 89, 180, false);
    46116    }
     117
     118    @Override
     119    public double getScaleFactor() {
     120        return scaleFactor;
     121    }
    47122}
  • trunk/src/org/openstreetmap/josm/data/projection/proj/ProjParameters.java

    r9532 r9565  
    1515    public Double lat2;
    1616
    17     // Polar Stereographic
     17    // Polar Stereographic and Mercator
    1818    public Double lat_ts;
    1919
  • trunk/test/unit/org/openstreetmap/josm/data/projection/ProjectionTest.java

    r9560 r9565  
    112112        final double EPS = 1e-6;
    113113        testProj("lonlat", EPS, "");
    114         testProj("josm:smerc", EPS, "");
    115114        testProj("lcc", EPS, "+lat_0=34");
    116115        testProj("lcc", EPS, "+lat_1=87 +lat_2=83.6 +lat_0=85.43");
     
    125124        testProj("cass", 1e-3, "+lat_0=11 +bounds=-1.0,-89,1.0,89");
    126125        testProj("laea", 3e-3, "+lat_0=34");
     126        testProj("merc", 1e-5, "");
    127127
    128128        if (error2) {
Note: See TracChangeset for help on using the changeset viewer.