On Tue, Jul 19, 2011 at 10:04 AM, Andrea Aime
<[email protected]> wrote:
> I don't have instructions but I can show you the diff of the commit that added
> the Robinson projection to GeoTools (and thus GeoServer), attached.

This time with the attachment

Cheers
Andrea


-- 
-------------------------------------------------------
Ing. Andrea Aime
GeoSolutions S.A.S.
Tech lead

Via Poggio alle Viti 1187
55054  Massarosa (LU)
Italy

phone: +39 0584 962313
fax:      +39 0584 962313

http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://www.youtube.com/user/GeoSolutionsIT
http://www.linkedin.com/in/andreaaime
http://twitter.com/geowolf

-------------------------------------------------------
diff --git 
a/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/Robinson.java
 
b/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/Robinson.java
new file mode 100644
index 0000000..e7be2e7
--- /dev/null
+++ 
b/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/Robinson.java
@@ -0,0 +1,374 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 1999-2008, Open Source Geospatial Foundation (OSGeo)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *    Lesser General Public License for more details.
+ *
+ *    This package contains formulas from the PROJ package of USGS.
+ *    USGS's work is fully acknowledged here. This derived work has
+ *    been relicensed under LGPL with Frank Warmerdam's permission.
+ */
+package org.geotools.referencing.operation.projection;
+
+import static java.lang.Math.*;
+
+import java.awt.geom.Point2D;
+
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.NamedIdentifier;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform;
+
+
+/**
+ * Robinson projection 
+ *
+ * @see <A HREF="http://en.wikipedia.org/wiki/Robinson_projection";>Robinson 
projection on Wikipedia</A>
+ * @see <A 
HREF="http://www.remotesensing.org/geotiff/proj_list/robinson.html";>"Robinson" 
on RemoteSensing.org</A>
+ *
+ * @since 2.6.3
+ * @source $URL: 
http://svn.osgeo.org/geotools/branches/2.6.x/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/Mercator.java
 $
+ * @author Andrea Aime
+ */
+public class Robinson extends MapProjection {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = 8428056162968814860L;
+    
+    static final class Coeff {
+        double c0, c1, c2, c3;
+
+        public Coeff(double c0, double c1, double c2, double c3) {
+            super();
+            this.c0 = c0;
+            this.c1 = c1;
+            this.c2 = c2;
+            this.c3 = c3;
+        }
+        
+        public Coeff(Coeff other) {
+            super();
+            this.c0 = other.c0;
+            this.c1 = other.c1;
+            this.c2 = other.c2;
+            this.c3 = other.c3;
+        }
+        
+        public final double forward(double z) {
+            return c0 + z * (c1 + z * (c2 + z * c3));
+        }
+        
+        public final double inverse(double z) {
+            return c1 + z * (c2 + c2 + z * 3d * c3);
+        }
+    }
+    
+    /**
+     * X translation table
+     */
+    private final static Coeff X[] = {
+        new Coeff(1,  -5.67239e-12,   -7.15511e-05,   3.11028e-06),
+        new Coeff(0.9986, -0.000482241,   -2.4897e-05,    -1.33094e-06),
+        new Coeff(0.9954, -0.000831031,   -4.4861e-05,    -9.86588e-07),
+        new Coeff(0.99,   -0.00135363,    -5.96598e-05,   3.67749e-06),
+        new Coeff(0.9822, -0.00167442,    -4.4975e-06,    -5.72394e-06),
+        new Coeff(0.973,  -0.00214869,    -9.03565e-05,   1.88767e-08),
+        new Coeff(0.96,   -0.00305084,    -9.00732e-05,   1.64869e-06),
+        new Coeff(0.9427, -0.00382792,    -6.53428e-05,   -2.61493e-06),
+        new Coeff(0.9216, -0.00467747,    -0.000104566,   4.8122e-06),
+        new Coeff(0.8962, -0.00536222,    -3.23834e-05,   -5.43445e-06),
+        new Coeff(0.8679, -0.00609364,    -0.0001139, 3.32521e-06),
+        new Coeff(0.835,  -0.00698325,    -6.40219e-05,   9.34582e-07),
+        new Coeff(0.7986, -0.00755337,    -5.00038e-05,   9.35532e-07),
+        new Coeff(0.7597, -0.00798325,    -3.59716e-05,   -2.27604e-06),
+        new Coeff(0.7186, -0.00851366,    -7.0112e-05,    -8.63072e-06),
+        new Coeff(0.6732, -0.00986209,    -0.000199572,   1.91978e-05),
+        new Coeff(0.6213, -0.010418,  8.83948e-05,    6.24031e-06),
+        new Coeff(0.5722, -0.00906601,    0.000181999,    6.24033e-06),
+        new Coeff(0.5322, 0., 0., 0.)
+    };
+
+    /**
+     * Y translation table
+     */
+    private final static Coeff Y[] = {
+        new Coeff(0,  0.0124, 3.72529e-10,    1.15484e-09),
+        new Coeff(0.062,  0.0124001,  1.76951e-08,    -5.92321e-09),
+        new Coeff(0.124,  0.0123998,  -7.09668e-08,   2.25753e-08),
+        new Coeff(0.186,  0.0124008,  2.66917e-07,    -8.44523e-08),
+        new Coeff(0.248,  0.0123971,  -9.99682e-07,   3.15569e-07),
+        new Coeff(0.31,   0.0124108,  3.73349e-06,    -1.1779e-06),
+        new Coeff(0.372,  0.0123598,  -1.3935e-05,    4.39588e-06),
+        new Coeff(0.434,  0.0125501,  5.20034e-05,    -1.00051e-05),
+        new Coeff(0.4968, 0.0123198,  -9.80735e-05,   9.22397e-06),
+        new Coeff(0.5571, 0.0120308,  4.02857e-05,    -5.2901e-06),
+        new Coeff(0.6176, 0.0120369,  -3.90662e-05,   7.36117e-07),
+        new Coeff(0.6769, 0.0117015,  -2.80246e-05,   -8.54283e-07),
+        new Coeff(0.7346, 0.0113572,  -4.08389e-05,   -5.18524e-07),
+        new Coeff(0.7903, 0.0109099,  -4.86169e-05,   -1.0718e-06),
+        new Coeff(0.8435, 0.0103433,  -6.46934e-05,   5.36384e-09),
+        new Coeff(0.8936, 0.00969679, -6.46129e-05,   -8.54894e-06),
+        new Coeff(0.9394, 0.00840949, -0.000192847,   -4.21023e-06),
+        new Coeff(0.9761, 0.00616525, -0.000256001,   -4.21021e-06),
+        new Coeff(1., 0., 0., 0)
+    };
+
+    private final static double FXC = 0.8487;
+    private final static double FYC = 1.3523;
+    private final static double C1 = 11.45915590261646417544;
+    private final static double RC1 = 0.08726646259971647884;
+    private final int NODES = 18;
+    private final static double ONEEPS = 1.000001;
+    private final static double EPS = 1e-12;
+    
+
+    /**
+     * Constructs a new map projection from the supplied parameters.
+     *
+     * @param  parameters The parameter values in standard units.
+     * @throws ParameterNotFoundException if a mandatory parameter is missing.
+     */
+    protected Robinson(final ParameterValueGroup parameters) throws 
ParameterNotFoundException {
+        super(parameters);
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Provider.PARAMETERS;
+    }
+
+    /**
+     * Transforms the specified (<var>&lambda;</var>,<var>&phi;</var>) 
coordinates
+     * (units in radians) and stores the result in {@code ptDst} (linear 
distance
+     * on a unit sphere).
+     */
+    protected Point2D transformNormalized(double lam, double phi, final 
Point2D ptDst)
+            throws ProjectionException {
+
+        double dphi = abs(phi);
+        int i = (int) floor(dphi * C1);
+        if (i >= NODES) {
+            i = NODES - 1;
+        }
+        dphi = toDegrees(dphi - RC1 * i);
+        double x = X[i].forward(dphi) * FXC * lam;
+        double y = Y[i].forward(dphi) * FYC;
+        if (phi < 0d) {
+            y = -y;
+        }
+        
+        if(ptDst != null) {
+            ptDst.setLocation(x, y);
+            return ptDst;
+        } else {
+            return new Point2D.Double(x, y);
+        }
+    }
+
+    /**
+     * Transforms the specified (<var>x</var>,<var>y</var>) coordinates
+     * and stores the result in {@code ptDst}.
+     */
+    protected Point2D inverseTransformNormalized(double x, double y, final 
Point2D ptDst)
+            throws ProjectionException {
+        double lam = x / FXC;
+        double phi = abs(y / FYC);
+        if (phi >= 1d) { /* simple pathologic cases */
+            if (phi > ONEEPS) {
+                phi = y < 0. ? -PI / 2 : PI / 2;
+                lam /= X[NODES].c0;
+            }
+        } else { /* general problem */
+            /* in Y space, reduce to table interval */
+            int i;
+            for (i = (int) floor(phi * NODES);;) {
+                if (Y[i].c0 > phi) {
+                    --i;
+                } else if (Y[i+1].c0 <= phi) {
+                    ++i;
+                } else {
+                    break;
+                }
+            }
+            Coeff T = new Coeff(Y[i]);
+            /* first guess, linear interp */
+            double t = 5d * (phi - T.c0) / (Y[i+1].c0 - T.c0);
+            /* make into root */
+            T.c0 -= phi;
+            for (;;) { /* Newton-Raphson reduction */
+                double t1 = T.forward(t) / T.inverse(t);
+                t -= t1;
+                if (abs(t1) < EPS) {
+                    break;
+                }
+            }
+            phi = toRadians(5 * i + t);
+            if (y < 0d) {
+                phi = -phi;
+            }
+            lam /= X[i].forward(t);
+        }
+        
+        if(ptDst != null) {
+            ptDst.setLocation(lam, phi);
+            return ptDst;
+        } else {
+            return new Point2D.Double(lam, phi);
+        }
+    }
+    
+    /**
+     * Compares the specified object with this map projection for equality.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            // Slight optimization
+            return true;
+        }
+        return super.equals(object);
+    }
+    
+    @Override
+    protected double getToleranceForAssertions(double longitude, double 
latitude) {
+        // the Robinson projection is meant for world-wide displays, don't be 
picky
+        return 2;
+    }
+    
+    
+    
//////////////////////////////////////////////////////////////////////////////////////////
+    
//////////////////////////////////////////////////////////////////////////////////////////
+    ////////                                                                   
       ////////
+    ////////                                 PROVIDERS                         
       ////////
+    ////////                                                                   
       ////////
+    
//////////////////////////////////////////////////////////////////////////////////////////
+    
//////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * The {@linkplain 
org.geotools.referencing.operation.MathTransformProvider math transform
+     * provider} for the Robinson projection (not part of the EPSG database).
+     *
+     * @since 2.6.3
+     * @author Andrea Aime
+     *
+     * @see org.geotools.referencing.operation.DefaultMathTransformFactory
+     */
+    public static class Provider extends AbstractProvider {
+        /**
+         * For cross-version compatibility.
+         */
+        private static final long serialVersionUID = 3586488124601927036L;
+        
+        /**
+         * The parameters group.
+         */
+        static final ParameterDescriptorGroup PARAMETERS = 
createDescriptorGroup(new NamedIdentifier[] {
+                new NamedIdentifier(Citations.GEOTOOLS, "Robinson"),
+                new NamedIdentifier(Citations.ESRI, "Robinson")
+            }, new ParameterDescriptor[] {
+                SEMI_MAJOR, SEMI_MINOR, CENTRAL_MERIDIAN
+            });
+
+        /**
+         * Constructs a new provider.
+         */
+        public Provider() {
+            super(PARAMETERS);
+        }
+
+        /**
+         * Creates a transform from the specified group of parameter values.
+         *
+         * @param  parameters The group of parameter values.
+         * @return The created math transform.
+         * @throws ParameterNotFoundException if a required parameter was not 
found.
+         */
+        protected MathTransform createMathTransform(final ParameterValueGroup 
parameters)
+                throws ParameterNotFoundException
+        {
+            return new Robinson(parameters);
+        }
+    }
+    
+//    public static void main(String[] args) {
+//        double px[] = {
+//                1,  -5.67239e-12,   -7.15511e-05,   3.11028e-06,
+//                0.9986, -0.000482241,   -2.4897e-05,    -1.33094e-06,
+//                0.9954, -0.000831031,   -4.4861e-05,    -9.86588e-07,
+//                0.99,   -0.00135363,    -5.96598e-05,   3.67749e-06,
+//                0.9822, -0.00167442,    -4.4975e-06,    -5.72394e-06,
+//                0.973,  -0.00214869,    -9.03565e-05,   1.88767e-08,
+//                0.96,   -0.00305084,    -9.00732e-05,   1.64869e-06,
+//                0.9427, -0.00382792,    -6.53428e-05,   -2.61493e-06,
+//                0.9216, -0.00467747,    -0.000104566,   4.8122e-06,
+//                0.8962, -0.00536222,    -3.23834e-05,   -5.43445e-06,
+//                0.8679, -0.00609364,    -0.0001139, 3.32521e-06,
+//                0.835,  -0.00698325,    -6.40219e-05,   9.34582e-07,
+//                0.7986, -0.00755337,    -5.00038e-05,   9.35532e-07,
+//                0.7597, -0.00798325,    -3.59716e-05,   -2.27604e-06,
+//                0.7186, -0.00851366,    -7.0112e-05,    -8.63072e-06,
+//                0.6732, -0.00986209,    -0.000199572,   1.91978e-05,
+//                0.6213, -0.010418,  8.83948e-05,    6.24031e-06,
+//                0.5722, -0.00906601,    0.000181999,    6.24033e-06,
+//                0.5322, 0.,0.,0.  };
+//
+//
+//
+//
+//
+//                double py[] = {
+//                0,  0.0124, 3.72529e-10,    1.15484e-09,
+//                0.062,  0.0124001,  1.76951e-08,    -5.92321e-09,
+//                0.124,  0.0123998,  -7.09668e-08,   2.25753e-08,
+//                0.186,  0.0124008,  2.66917e-07,    -8.44523e-08,
+//                0.248,  0.0123971,  -9.99682e-07,   3.15569e-07,
+//                0.31,   0.0124108,  3.73349e-06,    -1.1779e-06,
+//                0.372,  0.0123598,  -1.3935e-05,    4.39588e-06,
+//                0.434,  0.0125501,  5.20034e-05,    -1.00051e-05,
+//                0.4968, 0.0123198,  -9.80735e-05,   9.22397e-06,
+//                0.5571, 0.0120308,  4.02857e-05,    -5.2901e-06,
+//                0.6176, 0.0120369,  -3.90662e-05,   7.36117e-07,
+//                0.6769, 0.0117015,  -2.80246e-05,   -8.54283e-07,
+//                0.7346, 0.0113572,  -4.08389e-05,   -5.18524e-07,
+//                0.7903, 0.0109099,  -4.86169e-05,   -1.0718e-06,
+//                0.8435, 0.0103433,  -6.46934e-05,   5.36384e-09,
+//                0.8936, 0.00969679, -6.46129e-05,   -8.54894e-06,
+//                0.9394, 0.00840949, -0.000192847,   -4.21023e-06,
+//                0.9761, 0.00616525, -0.000256001,   -4.21021e-06,
+//                1., 0.,0.,0 };
+//        
+//        for (int i = 0; i < X.length; i++) {
+//            System.out.println(X[i].c0 == px[i * 4]);
+//            System.out.println(X[i].c1 == px[i * 4 + 1]);
+//            System.out.println(X[i].c2 == px[i * 4 + 2]);
+//            System.out.println(X[i].c3 == px[i * 4 + 3]);
+//        }
+//        
+//        for (int i = 0; i < Y.length; i++) {
+//            System.out.println(Y[i].c0 == py[i * 4]);
+//            System.out.println(Y[i].c1 == py[i * 4 + 1]);
+//            System.out.println(Y[i].c2 == py[i * 4 + 2]);
+//            System.out.println(Y[i].c3 == py[i * 4 + 3]);
+//        }
+//    }
+    
+    public static void main(String[] args) {
+        System.out.println(PI / 2d);
+    }
+}
diff --git 
a/modules/library/referencing/src/main/resources/META-INF/services/org.geotools.referencing.operation.MathTransformProvider
 
b/modules/library/referencing/src/main/resources/META-INF/services/org.geotools.referencing.operation.MathTransformProvider
index 0098e8a..e4a0b11 100644
--- 
a/modules/library/referencing/src/main/resources/META-INF/services/org.geotools.referencing.operation.MathTransformProvider
+++ 
b/modules/library/referencing/src/main/resources/META-INF/services/org.geotools.referencing.operation.MathTransformProvider
@@ -40,3 +40,4 @@ org.geotools.referencing.operation.projection.Krovak$Provider
 org.geotools.referencing.operation.projection.CassiniSoldner$Provider
 org.geotools.referencing.operation.projection.EquidistantConic$Provider
 org.geotools.referencing.operation.projection.Polyconic$Provider
+org.geotools.referencing.operation.projection.Robinson$Provider
diff --git 
a/modules/library/referencing/src/test/java/org/geotools/referencing/ScriptTest.java
 
b/modules/library/referencing/src/test/java/org/geotools/referencing/ScriptTest.java
index 5a4018d..7b10116 100644
--- 
a/modules/library/referencing/src/test/java/org/geotools/referencing/ScriptTest.java
+++ 
b/modules/library/referencing/src/test/java/org/geotools/referencing/ScriptTest.java
@@ -16,11 +16,14 @@
  */
 package org.geotools.referencing;
 
+import java.io.IOException;
 import java.io.LineNumberReader;
-import org.geotools.test.TestData;
 
-import org.junit.*;
-import static org.junit.Assert.*;
+import org.geotools.test.TestData;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.operation.TransformException;
 
 
 /**
@@ -209,6 +212,15 @@ public final class ScriptTest {
     public void testPolyconic() throws Exception {
         runScript("scripts/Polyconic.txt");
     }
+    
+    /**
+     * Run "Robinson.txt"
+     * @throws Exception
+     */
+    @Test
+    public void testRobinson() throws Exception {
+        runScript("scripts/Robinson.txt");
+    }
 
     /**
      * Run "OpenGIS.txt".
diff --git 
a/modules/library/referencing/src/test/resources/org/geotools/referencing/test-data/scripts/Robinson.txt
 
b/modules/library/referencing/src/test/resources/org/geotools/referencing/test-data/scripts/Robinson.txt
new file mode 100644
index 0000000..e94d53c
--- /dev/null
+++ 
b/modules/library/referencing/src/test/resources/org/geotools/referencing/test-data/scripts/Robinson.txt
@@ -0,0 +1,51 @@
+// Test points for the Robinson projection
+//
+// (C) 2004-2008, Open Source Geospatial Foundation (OSGeo)
+//
+// The following test points were calculated with libproj4 utility "cs2cs" 
+// cs2cs -v +datum=WGS84 +proj=lonlat +to +datum=WGS84 +proj=robin
+//
+// Andrea Aime - March 20 2010
+//
+// --------------------------------------------------------------------------
+// How to run this script:
+//
+//    chdir org/geotools/referencing/test-data/scripts
+//    java -ea org.geotools.referencing.ScriptRunner Robinson.txt
+//
+// A test is performed every time a "target pt" statement occurs. If the 
target point computed
+// by Geotools is different from the target point declared in this script by 
an amount greater
+// than the value specified in the last "test tolerance" statement, then a 
failure is reported.
+// Inverse transforms are tested if java assertions are enabled.
+// If some test fails, "print" statements can be added in this script for 
debugging purpose:
+//
+//    print crs            (prints the source and target CRS, and the 
transform between them)
+//    print pts            (prints the source and target points, and their 
transformed points)
+
+
+// CRS used for the test 
+set _WGS84_  = GEOGCS["WGS84",  DATUM["WGS84",  SPHEROID["WGS84",  6378137.0, 
298.257223563]], PRIMEM["Greenwich", 0.0], UNIT["degree",0.017453292519943295], 
AXIS["Longitude",EAST], AXIS["Latitude",NORTH]]
+
+////////////////////////////////////////////
+// Robinson
+
+set _robinson_ = PROJCS["Robinson", _WGS84_, PROJECTION["Robinson"], UNIT["m", 
1.0], AXIS["Easting", EAST], AXIS["Northing", NORTH]]
+
+source crs = _WGS84_
+target crs = _robinson_
+// hmm... looked everywhere and cannot find a significant difference between 
GeoTools code
+// and the proj one. Simply assuming the difference in double handling
+//  shows up quite badly in this projection
+test tolerance = (1, 1)
+
+source pt = (0, 0)
+target pt = (0, 0)
+
+source pt = (10, 10)
+target pt = (940422.59,  1069519.16)
+
+source pt = (30, 30)
+target pt = (2720933.27, 3208557.61)
+
+source pt = (-180, 90)
+target pt = (-9050503.94, 8625154.47)
\ No newline at end of file
------------------------------------------------------------------------------
Magic Quadrant for Content-Aware Data Loss Prevention
Research study explores the data loss prevention market. Includes in-depth
analysis on the changes within the DLP market, and the criteria used to
evaluate the strengths and weaknesses of these DLP solutions.
http://www.accelacomm.com/jaw/sfnl/114/51385063/
_______________________________________________
Geoserver-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geoserver-users

Reply via email to