sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1673222 [3/5] - in /sis/ip-review: ./ rev/09215/ rev/10796/ rev/11372/ rev/20874/
Date Mon, 13 Apr 2015 15:20:45 GMT
Added: sis/ip-review/rev/09215/LambertConformalBelgium.xhtml
URL: http://svn.apache.org/viewvc/sis/ip-review/rev/09215/LambertConformalBelgium.xhtml?rev=1673222&view=auto
==============================================================================
--- sis/ip-review/rev/09215/LambertConformalBelgium.xhtml (added)
+++ sis/ip-review/rev/09215/LambertConformalBelgium.xhtml Mon Apr 13 15:20:44 2015
@@ -0,0 +1,521 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta charset="UTF-8"/>
+    <title>LambertConformalBelgium changes for revisions 9214:9215</title>
+    <style type="text/css" media="all">
+      @import url("../../reports.css");
+    </style>
+  </head>
+  <body>
+    <div>
+      <h1>LambertConformalBelgium changes for revisions 9214:9215</h1>
+<p>
+  This commit appears as a new addition because the committer forgot to use the <code>svn copy</code> command,
+  but that class exited at least 5 years before this commit.
+  This commit has been applied on the <code>LambertConformal</code> class, but appear here as a side effect of SVN history.
+  See <code><a href="LambertConformal.xhtml">LambertConformal</a></code> for more analysis.
+</p>
+<p><b>Command line:</b></p>
+<blockquote><code>svn diff --extensions "--unified --ignore-space-change --ignore-all-space --ignore-eol-style" -r9214:9215 http://svn.osgeo.org/geotools/trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/LambertConformalBelgium.java</code></blockquote>
+<table class="changes">
+<tr><th>Revision 9214</th><th>Revision 9215</th></tr>
+<tr><td><pre></pre></td>
+<td><pre><span class="add">/*</span>
+<span class="add"> * Geotools - OpenSource mapping toolkit</span>
+<span class="add"> * (C) 2003, 2004 Geotools Project Managment Committee (PMC)</span>
+<span class="add"> * (C) 2001, Institut de Recherche pour le Développement</span>
+<span class="add"> * (C) 1999, Fisheries and Oceans Canada</span>
+<span class="add"> *</span>
+<span class="add"> *    This library is free software; you can redistribute it and/or</span>
+<span class="add"> *    modify it under the terms of the GNU Lesser General Public</span>
+<span class="add"> *    License as published by the Free Software Foundation; either</span>
+<span class="add"> *    version 2.1 of the License, or (at your option) any later version.</span>
+<span class="add"> *</span>
+<span class="add"> *    This library is distributed in the hope that it will be useful,</span>
+<span class="add"> *    but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
+<span class="add"> *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</span>
+<span class="add"> *    Lesser General Public License for more details.</span>
+<span class="add"> *</span>
+<span class="add"> *    You should have received a copy of the GNU Lesser General Public</span>
+<span class="add"> *    License along with this library; if not, write to the Free Software</span>
+<span class="add"> *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</span>
+<span class="add"> *</span>
+<span class="add"> *</span>
+<span class="add"> *    This package contains formulas from the PROJ package of USGS.</span>
+<span class="add"> *    USGS's work is fully acknowledged here.</span>
+<span class="add"> */</span>
+<span class="add">package org.geotools.referencing.operation.projection;</span>
+<span class="add"></span>
+<span class="add">// J2SE dependencies and extensions</span>
+<span class="add">import java.util.Collection;</span>
+<span class="add">import java.awt.geom.Point2D;</span>
+<span class="add">import javax.units.NonSI;</span>
+<span class="add"></span>
+<span class="add">// OpenGIS dependencies</span>
+<span class="add">import org.opengis.parameter.ParameterDescriptor;</span>
+<span class="add">import org.opengis.parameter.ParameterValueGroup;</span>
+<span class="add">import org.opengis.parameter.ParameterDescriptorGroup;</span>
+<span class="add">import org.opengis.parameter.ParameterNotFoundException;</span>
+<span class="add">import org.opengis.referencing.operation.MathTransform;</span>
+<span class="add"></span>
+<span class="add">// Geotools dependencies</span>
+<span class="add">import org.geotools.measure.Latitude;</span>
+<span class="add">import org.geotools.referencing.Identifier;</span>
+<span class="add">import org.geotools.metadata.citation.Citation;</span>
+<span class="add">import org.geotools.resources.cts.ResourceKeys;</span>
+<span class="add">import org.geotools.resources.cts.Resources;</span>
+<span class="add"></span>
+<span class="add">/**</span>
+<span class="add"> * Lambert Conical Conformal Projection.  Areas and shapes are deformed</span>
+<span class="add"> * as one moves away from standard parallels.  The angles are true in</span>
+<span class="add"> * a limited area.  This projection is used for the charts of North America.</span>
+<span class="add"> * It uses a default central latitude of 40°N.</span>
+<span class="add"> * &lt;br&gt;&lt;br&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * This implementation provides transforms for three cases of the lambert conic</span>
+<span class="add"> * conformal projection:</span>
+<span class="add"> * &lt;ul&gt;</span>
+<span class="add"> *   &lt;li&gt;&lt;code&gt;Lambert_Conformal_Conic_1SP&lt;/code&gt; (EPSG code 9801)&lt;/li&gt;</span>
+<span class="add"> *   &lt;li&gt;&lt;code&gt;Lambert_Conformal_Conic_2SP&lt;/code&gt; (EPSG code 9802)&lt;/li&gt;</span>
+<span class="add"> *   &lt;li&gt;&lt;code&gt;Lambert_Conic_Conformal_2SP_Belgium&lt;/code&gt; (EPSG code 9803)&lt;/li&gt;</span>
+<span class="add"> * &lt;/ul&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * For the 1SP case the latitude of origin is used as the standard parallel (SP).</span>
+<span class="add"> * To use a 1SP with a latitude of origin different from the SP, use the 2SP</span>
+<span class="add"> * and set both the SP1 and SP2 to the single SP.</span>
+<span class="add"> * &lt;br&gt;&lt;br&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * &lt;strong&gt;References:&lt;/strong&gt;&lt;ul&gt;</span>
+<span class="add"> *   &lt;li&gt;John P. Snyder (Map Projections - A Working Manual,&lt;br&gt;</span>
+<span class="add"> *       U.S. Geological Survey Professional Paper 1395, 1987)&lt;/li&gt;</span>
+<span class="add"> *   &lt;li&gt;"Coordinate Conversions and Transformations including Formulas",&lt;br&gt;</span>
+<span class="add"> *       EPSG Guidence Note Number 7, Version 19.&lt;/li&gt;</span>
+<span class="add"> * &lt;/ul&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * @see &lt;A HREF="http://mathworld.wolfram.com/LambertConformalConicProjection.html"&gt;Lambert conformal conic projection on MathWorld&lt;/A&gt;</span>
+<span class="add"> * @see &lt;A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_1sp.html"&gt;lambert_conic_conformal_1sp&lt;/A&gt;</span>
+<span class="add"> * @see &lt;A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp.html"&gt;lambert_conic_conformal_2sp&lt;/A&gt;</span>
+<span class="add"> * @see &lt;A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp_belgium.html"&gt;lambert_conic_conformal_2sp_belgium&lt;/A&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * @version $Id$</span>
+<span class="add"> * @author André Gosselin</span>
+<span class="add"> * @author Martin Desruisseaux</span>
+<span class="add"> * @author Rueben Schulz</span>
+<span class="add"> */</span>
+<span class="add">public class LambertConformal extends MapProjection{</span>
+<span class="add">    /**</span>
+<span class="add">     * Constant for the belgium 2SP case. This is 29.2985 seconds, given</span>
+<span class="add">     * here in radians.</span>
+<span class="add">     */</span>
+<span class="add">    private static final double BELGE_A = 0.00014204313635987700;</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Standards parallels in radians, for {@link #getParameterValues} implementation.</span>
+<span class="add">     */</span>
+<span class="add">    protected final double phi1, phi2;</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Internal variables for computation.</span>
+<span class="add">     */</span>
+<span class="add">    private final double n,F,rho0;</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * &lt;code&gt;true&lt;/code&gt; for 2SP, or &lt;code&gt;false&lt;/code&gt; for 1SP projection.</span>
+<span class="add">     */</span>
+<span class="add">    private final boolean sp2;</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * &lt;code&gt;true&lt;/code&gt; for Belgium 2SP.</span>
+<span class="add">     */</span>
+<span class="add">    private final boolean belgium;</span>
+<span class="add"></span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * The {@link MathTransformProvider} for a {@link LambertConformal} 1SP projection.</span>
+<span class="add">     *</span>
+<span class="add">     * @see MathTransformFactory</span>
+<span class="add">     *</span>
+<span class="add">     * @version $Id$</span>
+<span class="add">     * @author Martin Desruisseaux</span>
+<span class="add">     * @author Rueben Schulz</span>
+<span class="add">     */</span>
+<span class="add">    public static final class Provider1SP extends Provider {</span>
+<span class="add">        /**</span>
+<span class="add">         * The parameters group.</span>
+<span class="add">         */</span>
+<span class="add">        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new Identifier[] {</span>
+<span class="add">                new Identifier(Citation.OPEN_GIS, "Lambert_Conformal_Conic_1SP"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "Lambert Conic Conformal (1SP)"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "9801"),</span>
+<span class="add">                new Identifier(Citation.GEOTIFF,  "CT_LambertConfConic_1SP"),</span>
+<span class="add">                new Identifier(Citation.GEOTOOLS, Resources.formatInternational(</span>
+<span class="add">                                                  ResourceKeys.LAMBERT_CONFORMAL_PROJECTION))</span>
+<span class="add">            }, new ParameterDescriptor[] {</span>
+<span class="add">                SEMI_MAJOR,          SEMI_MINOR,</span>
+<span class="add">                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,</span>
+<span class="add">                SCALE_FACTOR,</span>
+<span class="add">                FALSE_EASTING,       FALSE_NORTHING</span>
+<span class="add">            });</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Construct a new provider.</span>
+<span class="add">         */</span>
+<span class="add">        public Provider1SP() {</span>
+<span class="add">            super(PARAMETERS);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Creates a transform from the specified group of parameter values.</span>
+<span class="add">         *</span>
+<span class="add">         * @param  parameters The group of parameter values.</span>
+<span class="add">         * @return The created math transform.</span>
+<span class="add">         * @throws ParameterNotFoundException if a required parameter was not found.</span>
+<span class="add">         */</span>
+<span class="add">        protected MathTransform createMathTransform(final ParameterValueGroup parameters)</span>
+<span class="add">                throws ParameterNotFoundException</span>
+<span class="add">        {</span>
+<span class="add">            final Collection descriptors = PARAMETERS.descriptors();</span>
+<span class="add">            return new LambertConformal(parameters, descriptors, false, false);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * The {@link MathTransformProvider} for a {@link LambertConformal} 2SP projection.</span>
+<span class="add">     *</span>
+<span class="add">     * @see MathTransformFactory</span>
+<span class="add">     *</span>
+<span class="add">     * @version $Id$</span>
+<span class="add">     * @author Martin Desruisseaux</span>
+<span class="add">     * @author Rueben Schulz</span>
+<span class="add">     */</span>
+<span class="add">    public static class Provider2SP extends Provider {</span>
+<span class="add">        /**</span>
+<span class="add">         * The operation parameter descriptor for the {@link #phi1 standard parallel 1}</span>
+<span class="add">         * parameter value. Valid values range is from -90 to 90°. Default value is 0.</span>
+<span class="add">         */</span>
+<span class="add">        public static final ParameterDescriptor STANDARD_PARALLEL_1 = createDescriptor(</span>
+<span class="add">                new Identifier[] {</span>
+<span class="add">                    new Identifier(Citation.OPEN_GIS, "standard_parallel_1"),</span>
+<span class="add">                    new Identifier(Citation.EPSG,     "Latitude of 1st standard parallel"),</span>
+<span class="add">                    new Identifier(Citation.GEOTIFF,  "StdParallel1")</span>
+<span class="add">                },</span>
+<span class="add">                0, -90, 90, NonSI.DEGREE_ANGLE);</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * The operation parameter descriptor for the {@link #phi2 standard parallel 2}</span>
+<span class="add">         * parameter value. Valid values range is from -90 to 90°. Default value is 0.</span>
+<span class="add">         */</span>
+<span class="add">        public static final ParameterDescriptor STANDARD_PARALLEL_2 = createDescriptor(</span>
+<span class="add">                new Identifier[] {</span>
+<span class="add">                    new Identifier(Citation.OPEN_GIS, "standard_parallel_2"),</span>
+<span class="add">                    new Identifier(Citation.EPSG,     "Latitude of 2nd standard parallel"),</span>
+<span class="add">                    new Identifier(Citation.GEOTIFF,  "StdParallel2")</span>
+<span class="add">                },</span>
+<span class="add">                0, -90, 90, NonSI.DEGREE_ANGLE);</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * The parameters group.</span>
+<span class="add">         * @task REVISIT: ESRI also included the scale factor as a parameter</span>
+<span class="add">         */</span>
+<span class="add">        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new Identifier[] {</span>
+<span class="add">                new Identifier(Citation.OPEN_GIS, "Lambert_Conformal_Conic_2SP"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "Lambert Conic Conformal (2SP)"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "9802"),</span>
+<span class="add">                new Identifier(Citation.GEOTIFF,  "CT_LambertConfConic_2SP"),</span>
+<span class="add">                new Identifier(Citation.GEOTIFF,  "CT_LambertConfConic"),</span>
+<span class="add">                new Identifier(Citation.ESRI,     "Lambert_Conformal_Conic"),</span>
+<span class="add">                new Identifier(Citation.GEOTOOLS, Resources.formatInternational(</span>
+<span class="add">                                                  ResourceKeys.LAMBERT_CONFORMAL_PROJECTION))</span>
+<span class="add">            }, new ParameterDescriptor[] {</span>
+<span class="add">                SEMI_MAJOR,          SEMI_MINOR,</span>
+<span class="add">                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,</span>
+<span class="add">                STANDARD_PARALLEL_1, STANDARD_PARALLEL_2,</span>
+<span class="add">                FALSE_EASTING,       FALSE_NORTHING</span>
+<span class="add">            });</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Construct a new provider.</span>
+<span class="add">         */</span>
+<span class="add">        public Provider2SP() {</span>
+<span class="add">            super(PARAMETERS);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Construct a new provider.</span>
+<span class="add">         */</span>
+<span class="add">        protected Provider2SP(final ParameterDescriptorGroup params) {</span>
+<span class="add">            super(params);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Creates a transform from the specified group of parameter values.</span>
+<span class="add">         *</span>
+<span class="add">         * @param  parameters The group of parameter values.</span>
+<span class="add">         * @return The created math transform.</span>
+<span class="add">         * @throws ParameterNotFoundException if a required parameter was not found.</span>
+<span class="add">         */</span>
+<span class="add">        protected MathTransform createMathTransform(final ParameterValueGroup parameters)</span>
+<span class="add">                throws ParameterNotFoundException</span>
+<span class="add">        {</span>
+<span class="add">            final Collection descriptors = PARAMETERS.descriptors();</span>
+<span class="add">            return new LambertConformal(parameters, descriptors, true, false);</span>
+<span class="add">        }</span>
+<span class="add">     }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * The {@link MathTransformProvider} for a {@link LambertConformal} 2SP</span>
+<span class="add">     * Belgium projection.</span>
+<span class="add">     *</span>
+<span class="add">     * @see MathTransformFactory</span>
+<span class="add">     *</span>
+<span class="add">     * @version $Id$</span>
+<span class="add">     * @author Rueben Schulz</span>
+<span class="add">     */</span>
+<span class="add">     public static final class Provider2SP_Belgium extends Provider2SP {</span>
+<span class="add"></span>
+<span class="add">         /**</span>
+<span class="add">         * The parameters group.</span>
+<span class="add">         */</span>
+<span class="add">        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new Identifier[] {</span>
+<span class="add">                new Identifier(Citation.OPEN_GIS, "Lambert_Conformal_Conic_2SP_Belgium"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "Lambert Conic Conformal (2SP Belgium)"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "9803"),</span>
+<span class="add">                new Identifier(Citation.GEOTOOLS, Resources.formatInternational(</span>
+<span class="add">                                                  ResourceKeys.LAMBERT_CONFORMAL_PROJECTION))</span>
+<span class="add">            }, new ParameterDescriptor[] {</span>
+<span class="add">                SEMI_MAJOR,          SEMI_MINOR,</span>
+<span class="add">                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,</span>
+<span class="add">                STANDARD_PARALLEL_1, STANDARD_PARALLEL_2,</span>
+<span class="add">                FALSE_EASTING,       FALSE_NORTHING</span>
+<span class="add">            });</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Construct a new provider.</span>
+<span class="add">         */</span>
+<span class="add">        public Provider2SP_Belgium() {</span>
+<span class="add">            super(PARAMETERS);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Creates a transform from the specified group of parameter values.</span>
+<span class="add">         *</span>
+<span class="add">         * @param  parameters The group of parameter values.</span>
+<span class="add">         * @return The created math transform.</span>
+<span class="add">         * @throws ParameterNotFoundException if a required parameter was not found.</span>
+<span class="add">         */</span>
+<span class="add">        protected MathTransform createMathTransform(final ParameterValueGroup parameters)</span>
+<span class="add">                throws ParameterNotFoundException</span>
+<span class="add">        {</span>
+<span class="add">            final Collection descriptors = PARAMETERS.descriptors();</span>
+<span class="add">            return new LambertConformal(parameters, descriptors, true, true);</span>
+<span class="add">        }</span>
+<span class="add">     }</span>
+<span class="add"></span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Construct a new map projection from the supplied parameters.</span>
+<span class="add">     *</span>
+<span class="add">     * @param  parameters The parameter values in standard units.</span>
+<span class="add">     * @param  The expected parameter descriptors.</span>
+<span class="add">     * @param  sp2 &lt;code&gt;true&lt;/code&gt; for 2SP, or &lt;code&gt;false&lt;/code&gt; for 1SP.</span>
+<span class="add">     * @param  belgium &lt;code&gt;true&lt;/code&gt; for the Belgium 2SP case.</span>
+<span class="add">     * @throws ParameterNotFoundException if a mandatory parameter is missing.</span>
+<span class="add">     *</span>
+<span class="add">     * @task REVISIT: set phi2 = phi1 if no SP2 value is given by user (an 1sp projection)</span>
+<span class="add">     */</span>
+<span class="add">    public LambertConformal(final ParameterValueGroup parameters, final Collection expected,</span>
+<span class="add">                            final boolean sp2, final boolean belgium)</span>
+<span class="add">    {</span>
+<span class="add">        //Fetch parameters</span>
+<span class="add">        super(parameters, expected);</span>
+<span class="add">        this.sp2         = sp2;</span>
+<span class="add">        this.belgium     = belgium;</span>
+<span class="add">        if (sp2) {</span>
+<span class="add">            phi1 = doubleValue(expected, Provider2SP.STANDARD_PARALLEL_1, parameters);</span>
+<span class="add">            phi2 = doubleValue(expected, Provider2SP.STANDARD_PARALLEL_2, parameters);</span>
+<span class="add">        } else {</span>
+<span class="add">            if (belgium) {</span>
+<span class="add">                throw new IllegalArgumentException();</span>
+<span class="add">            }</span>
+<span class="add">            // EPSG says the 1SP case uses the latitude of origin as the SP</span>
+<span class="add">            phi1 = phi2 = latitudeOfOrigin;</span>
+<span class="add">        }</span>
+<span class="add">        // Compute constants</span>
+<span class="add">        if (Math.abs(phi1 + phi2) &lt; EPS) {</span>
+<span class="add">            throw new IllegalArgumentException(Resources.format(</span>
+<span class="add">                    ResourceKeys.ERROR_ANTIPODE_LATITUDES_$2,</span>
+<span class="add">                    new Latitude(Math.toDegrees(phi1)),</span>
+<span class="add">                    new Latitude(Math.toDegrees(phi2))));</span>
+<span class="add">        }</span>
+<span class="add">        final double  cosphi1 = Math.cos(phi1);</span>
+<span class="add">        final double  sinphi1 = Math.sin(phi1);</span>
+<span class="add">        final boolean  secant = Math.abs(phi1-phi2) &gt; EPS; // Should be 'true' for 2SP case.</span>
+<span class="add">        if (isSpherical) {</span>
+<span class="add">            if (secant) {</span>
+<span class="add">                n = Math.log(cosphi1 / Math.cos(phi2)) /</span>
+<span class="add">                    Math.log(Math.tan((Math.PI/4) + 0.5*phi2) /</span>
+<span class="add">                             Math.tan((Math.PI/4) + 0.5*phi1));</span>
+<span class="add">            } else {</span>
+<span class="add">                n = sinphi1;</span>
+<span class="add">            }</span>
+<span class="add">            F = cosphi1 * Math.pow(Math.tan((Math.PI/4) + 0.5*phi1), n) / n;</span>
+<span class="add">            if (Math.abs(Math.abs(latitudeOfOrigin) - (Math.PI/2)) &gt;= EPS) {</span>
+<span class="add">                rho0 = F * Math.pow(Math.tan((Math.PI/4) + 0.5*latitudeOfOrigin), -n);</span>
+<span class="add">            } else {</span>
+<span class="add">                rho0 = 0.0;</span>
+<span class="add">            }</span>
+<span class="add">        } else {</span>
+<span class="add">            final double m1 = msfn(sinphi1, cosphi1);</span>
+<span class="add">            final double t1 = tsfn(phi1, sinphi1);</span>
+<span class="add">            if (secant) {</span>
+<span class="add">                final double sinphi2 = Math.sin(phi2);</span>
+<span class="add">                final double m2 = msfn(sinphi2, Math.cos(phi2));</span>
+<span class="add">                final double t2 = tsfn(phi2, sinphi2);</span>
+<span class="add">                n = Math.log(m1/m2) / Math.log(t1/t2);</span>
+<span class="add">            } else {</span>
+<span class="add">                n = sinphi1;</span>
+<span class="add">            }</span>
+<span class="add">            F = m1 * Math.pow(t1, -n) / n;</span>
+<span class="add">            if (Math.abs(Math.abs(latitudeOfOrigin) - (Math.PI/2)) &gt;= EPS) {</span>
+<span class="add">                rho0 = F * Math.pow(tsfn(latitudeOfOrigin, Math.sin(latitudeOfOrigin)), n);</span>
+<span class="add">            } else {</span>
+<span class="add">                rho0 = 0.0;</span>
+<span class="add">            }</span>
+<span class="add">        }</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * {@inheritDoc}</span>
+<span class="add">     */</span>
+<span class="add">    protected ParameterDescriptorGroup getParameterDescriptors() {</span>
+<span class="add">        return (belgium) ?</span>
+<span class="add">                    Provider2SP_Belgium.PARAMETERS :</span>
+<span class="add">                    ((sp2) ? Provider2SP.PARAMETERS : Provider1SP.PARAMETERS);</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * {@inheritDoc}</span>
+<span class="add">     */</span>
+<span class="add">    public ParameterValueGroup getParameterValues() {</span>
+<span class="add">        final ParameterValueGroup values = super.getParameterValues();</span>
+<span class="add">        if (sp2) {</span>
+<span class="add">            final Collection expected = getParameterDescriptors().descriptors();</span>
+<span class="add">            set(expected, Provider2SP.STANDARD_PARALLEL_1, values, phi1);</span>
+<span class="add">            set(expected, Provider2SP.STANDARD_PARALLEL_2, values, phi2);</span>
+<span class="add">        }</span>
+<span class="add">        return values;</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Transforms the specified (&lt;var&gt;x&lt;/var&gt;,&lt;var&gt;y&lt;/var&gt;) coordinate (units in radians)</span>
+<span class="add">     * and stores the result in &lt;code&gt;ptDst&lt;/code&gt; (linear distance on a unit sphere).</span>
+<span class="add">     */</span>
+<span class="add">    protected Point2D transformNormalized(double x, double y, Point2D ptDst)</span>
+<span class="add">            throws ProjectionException</span>
+<span class="add">    {</span>
+<span class="add">        double rho;</span>
+<span class="add">        //Snyder p. 108</span>
+<span class="add">        if (Math.abs(Math.abs(y) - (Math.PI/2)) &lt; EPS) {</span>
+<span class="add">            if (y*n &lt;= 0) {</span>
+<span class="add">                throw new ProjectionException(Resources.format(</span>
+<span class="add">                        ResourceKeys.ERROR_POLE_PROJECTION_$1,</span>
+<span class="add">                        new Latitude(Math.toDegrees(y))));</span>
+<span class="add">            } else {</span>
+<span class="add">                rho = 0;</span>
+<span class="add">            }</span>
+<span class="add">        } else if (isSpherical) {</span>
+<span class="add">            rho = F * Math.pow(Math.tan((Math.PI/4) + 0.5*y), -n);</span>
+<span class="add">        } else {</span>
+<span class="add">            rho = F * Math.pow(tsfn(y, Math.sin(y)), n);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        x *= n;</span>
+<span class="add">        if (belgium) {</span>
+<span class="add">            x -= BELGE_A;</span>
+<span class="add">        }</span>
+<span class="add">        y = rho0 - rho * Math.cos(x);</span>
+<span class="add">        x =        rho * Math.sin(x);</span>
+<span class="add"></span>
+<span class="add">        if (ptDst != null) {</span>
+<span class="add">            ptDst.setLocation(x,y);</span>
+<span class="add">            return ptDst;</span>
+<span class="add">        }</span>
+<span class="add">        return new Point2D.Double(x,y);</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Transforms the specified (&lt;var&gt;x&lt;/var&gt;,&lt;var&gt;y&lt;/var&gt;) coordinate</span>
+<span class="add">     * and stores the result in &lt;code&gt;ptDst&lt;/code&gt;.</span>
+<span class="add">     */</span>
+<span class="add">    protected Point2D inverseTransformNormalized(double x, double y, Point2D ptDst)</span>
+<span class="add">            throws ProjectionException</span>
+<span class="add">    {</span>
+<span class="add">        double theta;</span>
+<span class="add">        y = rho0 - y;</span>
+<span class="add">        double rho = Math.sqrt(x*x + y*y);  // Zero when the latitude is 90 degrees.</span>
+<span class="add">        if (rho &gt; EPS) {</span>
+<span class="add">            if (n &lt; 0) {</span>
+<span class="add">                rho = -rho;</span>
+<span class="add">                x = -x;</span>
+<span class="add">                y = -y;</span>
+<span class="add">            }</span>
+<span class="add">            theta = Math.atan2(x, y);</span>
+<span class="add">            if (belgium) {</span>
+<span class="add">                theta += BELGE_A;</span>
+<span class="add">            }</span>
+<span class="add">            x = theta/n;</span>
+<span class="add">            if (isSpherical) {</span>
+<span class="add">                y = 2.0 * Math.atan(Math.pow(F/rho, 1.0/n)) - (Math.PI/2);</span>
+<span class="add">            } else {</span>
+<span class="add">                y = cphi2(Math.pow(rho/F, 1.0/n));</span>
+<span class="add">            }</span>
+<span class="add">        } else {</span>
+<span class="add">            x = 0.0;</span>
+<span class="add">            y = n &lt; 0 ? -(Math.PI/2) : (Math.PI/2);</span>
+<span class="add">        }</span>
+<span class="add">        if (ptDst != null) {</span>
+<span class="add">            ptDst.setLocation(x,y);</span>
+<span class="add">            return ptDst;</span>
+<span class="add">        }</span>
+<span class="add">        return new Point2D.Double(x,y);</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Returns a hash value for this projection.</span>
+<span class="add">     */</span>
+<span class="add">    public int hashCode() {</span>
+<span class="add">        /*</span>
+<span class="add">         * This code should be computed fast. Consequently, we do not use all fields</span>
+<span class="add">         * in this object.  Two &lt;code&gt;LambertConformal&lt;/code&gt; objects with different</span>
+<span class="add">         * {@link #phi1} and {@link #phi2} should compute a F value different enough.</span>
+<span class="add">         */</span>
+<span class="add">        final long code = Double.doubleToLongBits(F);</span>
+<span class="add">        return ((int)code ^ (int)(code &gt;&gt;&gt; 32)) + 37*super.hashCode();</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Compares the specified object with this map projection for equality.</span>
+<span class="add">     */</span>
+<span class="add">    public boolean equals(final Object object) {</span>
+<span class="add">        if (object == this) {</span>
+<span class="add">            // Slight optimization</span>
+<span class="add">            return true;</span>
+<span class="add">        }</span>
+<span class="add">        if (super.equals(object)) {</span>
+<span class="add">            final LambertConformal that = (LambertConformal) object;</span>
+<span class="add">            return (this.sp2 == that.sp2) &amp;&amp; (this.belgium == that.belgium) &amp;&amp;</span>
+<span class="add">                   equals(this.n,      that.n)    &amp;&amp;</span>
+<span class="add">                   equals(this.F,      that.F)    &amp;&amp;</span>
+<span class="add">                   equals(this.rho0,   that.rho0) &amp;&amp;</span>
+<span class="add">                   equals(this.phi1,   that.phi1) &amp;&amp;</span>
+<span class="add">                   equals(this.phi2,   that.phi2);</span>
+<span class="add">        }</span>
+<span class="add">        return false;</span>
+<span class="add">    }</span>
+<span class="add">}</span></pre></td></tr>
+</table>
+    </div>
+  </body>
+</html>

Propchange: sis/ip-review/rev/09215/LambertConformalBelgium.xhtml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/ip-review/rev/09215/LambertConformalBelgium.xhtml
------------------------------------------------------------------------------
    svn:mime-type = text/html

Added: sis/ip-review/rev/09215/LambertConformalESRI.xhtml
URL: http://svn.apache.org/viewvc/sis/ip-review/rev/09215/LambertConformalESRI.xhtml?rev=1673222&view=auto
==============================================================================
--- sis/ip-review/rev/09215/LambertConformalESRI.xhtml (added)
+++ sis/ip-review/rev/09215/LambertConformalESRI.xhtml Mon Apr 13 15:20:44 2015
@@ -0,0 +1,521 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta charset="UTF-8"/>
+    <title>LambertConformalESRI changes for revisions 9214:9215</title>
+    <style type="text/css" media="all">
+      @import url("../../reports.css");
+    </style>
+  </head>
+  <body>
+    <div>
+      <h1>LambertConformalESRI changes for revisions 9214:9215</h1>
+<p>
+  This commit appears as a new addition because the committer forgot to use the <code>svn copy</code> command,
+  but that class exited at least 5 years before this commit.
+  This commit has been applied on the <code>LambertConformal</code> class, but appear here as a side effect of SVN history.
+  See <code><a href="LambertConformal.xhtml">LambertConformal</a></code> for more analysis.
+</p>
+<p><b>Command line:</b></p>
+<blockquote><code>svn diff --extensions "--unified --ignore-space-change --ignore-all-space --ignore-eol-style" -r9214:9215 http://svn.osgeo.org/geotools/trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/projection/LambertConformalESRI.java</code></blockquote>
+<table class="changes">
+<tr><th>Revision 9214</th><th>Revision 9215</th></tr>
+<tr><td><pre></pre></td>
+<td><pre><span class="add">/*</span>
+<span class="add"> * Geotools - OpenSource mapping toolkit</span>
+<span class="add"> * (C) 2003, 2004 Geotools Project Managment Committee (PMC)</span>
+<span class="add"> * (C) 2001, Institut de Recherche pour le Développement</span>
+<span class="add"> * (C) 1999, Fisheries and Oceans Canada</span>
+<span class="add"> *</span>
+<span class="add"> *    This library is free software; you can redistribute it and/or</span>
+<span class="add"> *    modify it under the terms of the GNU Lesser General Public</span>
+<span class="add"> *    License as published by the Free Software Foundation; either</span>
+<span class="add"> *    version 2.1 of the License, or (at your option) any later version.</span>
+<span class="add"> *</span>
+<span class="add"> *    This library is distributed in the hope that it will be useful,</span>
+<span class="add"> *    but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
+<span class="add"> *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</span>
+<span class="add"> *    Lesser General Public License for more details.</span>
+<span class="add"> *</span>
+<span class="add"> *    You should have received a copy of the GNU Lesser General Public</span>
+<span class="add"> *    License along with this library; if not, write to the Free Software</span>
+<span class="add"> *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</span>
+<span class="add"> *</span>
+<span class="add"> *</span>
+<span class="add"> *    This package contains formulas from the PROJ package of USGS.</span>
+<span class="add"> *    USGS's work is fully acknowledged here.</span>
+<span class="add"> */</span>
+<span class="add">package org.geotools.referencing.operation.projection;</span>
+<span class="add"></span>
+<span class="add">// J2SE dependencies and extensions</span>
+<span class="add">import java.util.Collection;</span>
+<span class="add">import java.awt.geom.Point2D;</span>
+<span class="add">import javax.units.NonSI;</span>
+<span class="add"></span>
+<span class="add">// OpenGIS dependencies</span>
+<span class="add">import org.opengis.parameter.ParameterDescriptor;</span>
+<span class="add">import org.opengis.parameter.ParameterValueGroup;</span>
+<span class="add">import org.opengis.parameter.ParameterDescriptorGroup;</span>
+<span class="add">import org.opengis.parameter.ParameterNotFoundException;</span>
+<span class="add">import org.opengis.referencing.operation.MathTransform;</span>
+<span class="add"></span>
+<span class="add">// Geotools dependencies</span>
+<span class="add">import org.geotools.measure.Latitude;</span>
+<span class="add">import org.geotools.referencing.Identifier;</span>
+<span class="add">import org.geotools.metadata.citation.Citation;</span>
+<span class="add">import org.geotools.resources.cts.ResourceKeys;</span>
+<span class="add">import org.geotools.resources.cts.Resources;</span>
+<span class="add"></span>
+<span class="add">/**</span>
+<span class="add"> * Lambert Conical Conformal Projection.  Areas and shapes are deformed</span>
+<span class="add"> * as one moves away from standard parallels.  The angles are true in</span>
+<span class="add"> * a limited area.  This projection is used for the charts of North America.</span>
+<span class="add"> * It uses a default central latitude of 40°N.</span>
+<span class="add"> * &lt;br&gt;&lt;br&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * This implementation provides transforms for three cases of the lambert conic</span>
+<span class="add"> * conformal projection:</span>
+<span class="add"> * &lt;ul&gt;</span>
+<span class="add"> *   &lt;li&gt;&lt;code&gt;Lambert_Conformal_Conic_1SP&lt;/code&gt; (EPSG code 9801)&lt;/li&gt;</span>
+<span class="add"> *   &lt;li&gt;&lt;code&gt;Lambert_Conformal_Conic_2SP&lt;/code&gt; (EPSG code 9802)&lt;/li&gt;</span>
+<span class="add"> *   &lt;li&gt;&lt;code&gt;Lambert_Conic_Conformal_2SP_Belgium&lt;/code&gt; (EPSG code 9803)&lt;/li&gt;</span>
+<span class="add"> * &lt;/ul&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * For the 1SP case the latitude of origin is used as the standard parallel (SP).</span>
+<span class="add"> * To use a 1SP with a latitude of origin different from the SP, use the 2SP</span>
+<span class="add"> * and set both the SP1 and SP2 to the single SP.</span>
+<span class="add"> * &lt;br&gt;&lt;br&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * &lt;strong&gt;References:&lt;/strong&gt;&lt;ul&gt;</span>
+<span class="add"> *   &lt;li&gt;John P. Snyder (Map Projections - A Working Manual,&lt;br&gt;</span>
+<span class="add"> *       U.S. Geological Survey Professional Paper 1395, 1987)&lt;/li&gt;</span>
+<span class="add"> *   &lt;li&gt;"Coordinate Conversions and Transformations including Formulas",&lt;br&gt;</span>
+<span class="add"> *       EPSG Guidence Note Number 7, Version 19.&lt;/li&gt;</span>
+<span class="add"> * &lt;/ul&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * @see &lt;A HREF="http://mathworld.wolfram.com/LambertConformalConicProjection.html"&gt;Lambert conformal conic projection on MathWorld&lt;/A&gt;</span>
+<span class="add"> * @see &lt;A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_1sp.html"&gt;lambert_conic_conformal_1sp&lt;/A&gt;</span>
+<span class="add"> * @see &lt;A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp.html"&gt;lambert_conic_conformal_2sp&lt;/A&gt;</span>
+<span class="add"> * @see &lt;A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp_belgium.html"&gt;lambert_conic_conformal_2sp_belgium&lt;/A&gt;</span>
+<span class="add"> *</span>
+<span class="add"> * @version $Id$</span>
+<span class="add"> * @author André Gosselin</span>
+<span class="add"> * @author Martin Desruisseaux</span>
+<span class="add"> * @author Rueben Schulz</span>
+<span class="add"> */</span>
+<span class="add">public class LambertConformal extends MapProjection{</span>
+<span class="add">    /**</span>
+<span class="add">     * Constant for the belgium 2SP case. This is 29.2985 seconds, given</span>
+<span class="add">     * here in radians.</span>
+<span class="add">     */</span>
+<span class="add">    private static final double BELGE_A = 0.00014204313635987700;</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Standards parallels in radians, for {@link #getParameterValues} implementation.</span>
+<span class="add">     */</span>
+<span class="add">    protected final double phi1, phi2;</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Internal variables for computation.</span>
+<span class="add">     */</span>
+<span class="add">    private final double n,F,rho0;</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * &lt;code&gt;true&lt;/code&gt; for 2SP, or &lt;code&gt;false&lt;/code&gt; for 1SP projection.</span>
+<span class="add">     */</span>
+<span class="add">    private final boolean sp2;</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * &lt;code&gt;true&lt;/code&gt; for Belgium 2SP.</span>
+<span class="add">     */</span>
+<span class="add">    private final boolean belgium;</span>
+<span class="add"></span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * The {@link MathTransformProvider} for a {@link LambertConformal} 1SP projection.</span>
+<span class="add">     *</span>
+<span class="add">     * @see MathTransformFactory</span>
+<span class="add">     *</span>
+<span class="add">     * @version $Id$</span>
+<span class="add">     * @author Martin Desruisseaux</span>
+<span class="add">     * @author Rueben Schulz</span>
+<span class="add">     */</span>
+<span class="add">    public static final class Provider1SP extends Provider {</span>
+<span class="add">        /**</span>
+<span class="add">         * The parameters group.</span>
+<span class="add">         */</span>
+<span class="add">        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new Identifier[] {</span>
+<span class="add">                new Identifier(Citation.OPEN_GIS, "Lambert_Conformal_Conic_1SP"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "Lambert Conic Conformal (1SP)"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "9801"),</span>
+<span class="add">                new Identifier(Citation.GEOTIFF,  "CT_LambertConfConic_1SP"),</span>
+<span class="add">                new Identifier(Citation.GEOTOOLS, Resources.formatInternational(</span>
+<span class="add">                                                  ResourceKeys.LAMBERT_CONFORMAL_PROJECTION))</span>
+<span class="add">            }, new ParameterDescriptor[] {</span>
+<span class="add">                SEMI_MAJOR,          SEMI_MINOR,</span>
+<span class="add">                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,</span>
+<span class="add">                SCALE_FACTOR,</span>
+<span class="add">                FALSE_EASTING,       FALSE_NORTHING</span>
+<span class="add">            });</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Construct a new provider.</span>
+<span class="add">         */</span>
+<span class="add">        public Provider1SP() {</span>
+<span class="add">            super(PARAMETERS);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Creates a transform from the specified group of parameter values.</span>
+<span class="add">         *</span>
+<span class="add">         * @param  parameters The group of parameter values.</span>
+<span class="add">         * @return The created math transform.</span>
+<span class="add">         * @throws ParameterNotFoundException if a required parameter was not found.</span>
+<span class="add">         */</span>
+<span class="add">        protected MathTransform createMathTransform(final ParameterValueGroup parameters)</span>
+<span class="add">                throws ParameterNotFoundException</span>
+<span class="add">        {</span>
+<span class="add">            final Collection descriptors = PARAMETERS.descriptors();</span>
+<span class="add">            return new LambertConformal(parameters, descriptors, false, false);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * The {@link MathTransformProvider} for a {@link LambertConformal} 2SP projection.</span>
+<span class="add">     *</span>
+<span class="add">     * @see MathTransformFactory</span>
+<span class="add">     *</span>
+<span class="add">     * @version $Id$</span>
+<span class="add">     * @author Martin Desruisseaux</span>
+<span class="add">     * @author Rueben Schulz</span>
+<span class="add">     */</span>
+<span class="add">    public static class Provider2SP extends Provider {</span>
+<span class="add">        /**</span>
+<span class="add">         * The operation parameter descriptor for the {@link #phi1 standard parallel 1}</span>
+<span class="add">         * parameter value. Valid values range is from -90 to 90°. Default value is 0.</span>
+<span class="add">         */</span>
+<span class="add">        public static final ParameterDescriptor STANDARD_PARALLEL_1 = createDescriptor(</span>
+<span class="add">                new Identifier[] {</span>
+<span class="add">                    new Identifier(Citation.OPEN_GIS, "standard_parallel_1"),</span>
+<span class="add">                    new Identifier(Citation.EPSG,     "Latitude of 1st standard parallel"),</span>
+<span class="add">                    new Identifier(Citation.GEOTIFF,  "StdParallel1")</span>
+<span class="add">                },</span>
+<span class="add">                0, -90, 90, NonSI.DEGREE_ANGLE);</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * The operation parameter descriptor for the {@link #phi2 standard parallel 2}</span>
+<span class="add">         * parameter value. Valid values range is from -90 to 90°. Default value is 0.</span>
+<span class="add">         */</span>
+<span class="add">        public static final ParameterDescriptor STANDARD_PARALLEL_2 = createDescriptor(</span>
+<span class="add">                new Identifier[] {</span>
+<span class="add">                    new Identifier(Citation.OPEN_GIS, "standard_parallel_2"),</span>
+<span class="add">                    new Identifier(Citation.EPSG,     "Latitude of 2nd standard parallel"),</span>
+<span class="add">                    new Identifier(Citation.GEOTIFF,  "StdParallel2")</span>
+<span class="add">                },</span>
+<span class="add">                0, -90, 90, NonSI.DEGREE_ANGLE);</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * The parameters group.</span>
+<span class="add">         * @task REVISIT: ESRI also included the scale factor as a parameter</span>
+<span class="add">         */</span>
+<span class="add">        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new Identifier[] {</span>
+<span class="add">                new Identifier(Citation.OPEN_GIS, "Lambert_Conformal_Conic_2SP"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "Lambert Conic Conformal (2SP)"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "9802"),</span>
+<span class="add">                new Identifier(Citation.GEOTIFF,  "CT_LambertConfConic_2SP"),</span>
+<span class="add">                new Identifier(Citation.GEOTIFF,  "CT_LambertConfConic"),</span>
+<span class="add">                new Identifier(Citation.ESRI,     "Lambert_Conformal_Conic"),</span>
+<span class="add">                new Identifier(Citation.GEOTOOLS, Resources.formatInternational(</span>
+<span class="add">                                                  ResourceKeys.LAMBERT_CONFORMAL_PROJECTION))</span>
+<span class="add">            }, new ParameterDescriptor[] {</span>
+<span class="add">                SEMI_MAJOR,          SEMI_MINOR,</span>
+<span class="add">                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,</span>
+<span class="add">                STANDARD_PARALLEL_1, STANDARD_PARALLEL_2,</span>
+<span class="add">                FALSE_EASTING,       FALSE_NORTHING</span>
+<span class="add">            });</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Construct a new provider.</span>
+<span class="add">         */</span>
+<span class="add">        public Provider2SP() {</span>
+<span class="add">            super(PARAMETERS);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Construct a new provider.</span>
+<span class="add">         */</span>
+<span class="add">        protected Provider2SP(final ParameterDescriptorGroup params) {</span>
+<span class="add">            super(params);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Creates a transform from the specified group of parameter values.</span>
+<span class="add">         *</span>
+<span class="add">         * @param  parameters The group of parameter values.</span>
+<span class="add">         * @return The created math transform.</span>
+<span class="add">         * @throws ParameterNotFoundException if a required parameter was not found.</span>
+<span class="add">         */</span>
+<span class="add">        protected MathTransform createMathTransform(final ParameterValueGroup parameters)</span>
+<span class="add">                throws ParameterNotFoundException</span>
+<span class="add">        {</span>
+<span class="add">            final Collection descriptors = PARAMETERS.descriptors();</span>
+<span class="add">            return new LambertConformal(parameters, descriptors, true, false);</span>
+<span class="add">        }</span>
+<span class="add">     }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * The {@link MathTransformProvider} for a {@link LambertConformal} 2SP</span>
+<span class="add">     * Belgium projection.</span>
+<span class="add">     *</span>
+<span class="add">     * @see MathTransformFactory</span>
+<span class="add">     *</span>
+<span class="add">     * @version $Id$</span>
+<span class="add">     * @author Rueben Schulz</span>
+<span class="add">     */</span>
+<span class="add">     public static final class Provider2SP_Belgium extends Provider2SP {</span>
+<span class="add"></span>
+<span class="add">         /**</span>
+<span class="add">         * The parameters group.</span>
+<span class="add">         */</span>
+<span class="add">        static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new Identifier[] {</span>
+<span class="add">                new Identifier(Citation.OPEN_GIS, "Lambert_Conformal_Conic_2SP_Belgium"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "Lambert Conic Conformal (2SP Belgium)"),</span>
+<span class="add">                new Identifier(Citation.EPSG,     "9803"),</span>
+<span class="add">                new Identifier(Citation.GEOTOOLS, Resources.formatInternational(</span>
+<span class="add">                                                  ResourceKeys.LAMBERT_CONFORMAL_PROJECTION))</span>
+<span class="add">            }, new ParameterDescriptor[] {</span>
+<span class="add">                SEMI_MAJOR,          SEMI_MINOR,</span>
+<span class="add">                CENTRAL_MERIDIAN,    LATITUDE_OF_ORIGIN,</span>
+<span class="add">                STANDARD_PARALLEL_1, STANDARD_PARALLEL_2,</span>
+<span class="add">                FALSE_EASTING,       FALSE_NORTHING</span>
+<span class="add">            });</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Construct a new provider.</span>
+<span class="add">         */</span>
+<span class="add">        public Provider2SP_Belgium() {</span>
+<span class="add">            super(PARAMETERS);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        /**</span>
+<span class="add">         * Creates a transform from the specified group of parameter values.</span>
+<span class="add">         *</span>
+<span class="add">         * @param  parameters The group of parameter values.</span>
+<span class="add">         * @return The created math transform.</span>
+<span class="add">         * @throws ParameterNotFoundException if a required parameter was not found.</span>
+<span class="add">         */</span>
+<span class="add">        protected MathTransform createMathTransform(final ParameterValueGroup parameters)</span>
+<span class="add">                throws ParameterNotFoundException</span>
+<span class="add">        {</span>
+<span class="add">            final Collection descriptors = PARAMETERS.descriptors();</span>
+<span class="add">            return new LambertConformal(parameters, descriptors, true, true);</span>
+<span class="add">        }</span>
+<span class="add">     }</span>
+<span class="add"></span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Construct a new map projection from the supplied parameters.</span>
+<span class="add">     *</span>
+<span class="add">     * @param  parameters The parameter values in standard units.</span>
+<span class="add">     * @param  The expected parameter descriptors.</span>
+<span class="add">     * @param  sp2 &lt;code&gt;true&lt;/code&gt; for 2SP, or &lt;code&gt;false&lt;/code&gt; for 1SP.</span>
+<span class="add">     * @param  belgium &lt;code&gt;true&lt;/code&gt; for the Belgium 2SP case.</span>
+<span class="add">     * @throws ParameterNotFoundException if a mandatory parameter is missing.</span>
+<span class="add">     *</span>
+<span class="add">     * @task REVISIT: set phi2 = phi1 if no SP2 value is given by user (an 1sp projection)</span>
+<span class="add">     */</span>
+<span class="add">    public LambertConformal(final ParameterValueGroup parameters, final Collection expected,</span>
+<span class="add">                            final boolean sp2, final boolean belgium)</span>
+<span class="add">    {</span>
+<span class="add">        //Fetch parameters</span>
+<span class="add">        super(parameters, expected);</span>
+<span class="add">        this.sp2         = sp2;</span>
+<span class="add">        this.belgium     = belgium;</span>
+<span class="add">        if (sp2) {</span>
+<span class="add">            phi1 = doubleValue(expected, Provider2SP.STANDARD_PARALLEL_1, parameters);</span>
+<span class="add">            phi2 = doubleValue(expected, Provider2SP.STANDARD_PARALLEL_2, parameters);</span>
+<span class="add">        } else {</span>
+<span class="add">            if (belgium) {</span>
+<span class="add">                throw new IllegalArgumentException();</span>
+<span class="add">            }</span>
+<span class="add">            // EPSG says the 1SP case uses the latitude of origin as the SP</span>
+<span class="add">            phi1 = phi2 = latitudeOfOrigin;</span>
+<span class="add">        }</span>
+<span class="add">        // Compute constants</span>
+<span class="add">        if (Math.abs(phi1 + phi2) &lt; EPS) {</span>
+<span class="add">            throw new IllegalArgumentException(Resources.format(</span>
+<span class="add">                    ResourceKeys.ERROR_ANTIPODE_LATITUDES_$2,</span>
+<span class="add">                    new Latitude(Math.toDegrees(phi1)),</span>
+<span class="add">                    new Latitude(Math.toDegrees(phi2))));</span>
+<span class="add">        }</span>
+<span class="add">        final double  cosphi1 = Math.cos(phi1);</span>
+<span class="add">        final double  sinphi1 = Math.sin(phi1);</span>
+<span class="add">        final boolean  secant = Math.abs(phi1-phi2) &gt; EPS; // Should be 'true' for 2SP case.</span>
+<span class="add">        if (isSpherical) {</span>
+<span class="add">            if (secant) {</span>
+<span class="add">                n = Math.log(cosphi1 / Math.cos(phi2)) /</span>
+<span class="add">                    Math.log(Math.tan((Math.PI/4) + 0.5*phi2) /</span>
+<span class="add">                             Math.tan((Math.PI/4) + 0.5*phi1));</span>
+<span class="add">            } else {</span>
+<span class="add">                n = sinphi1;</span>
+<span class="add">            }</span>
+<span class="add">            F = cosphi1 * Math.pow(Math.tan((Math.PI/4) + 0.5*phi1), n) / n;</span>
+<span class="add">            if (Math.abs(Math.abs(latitudeOfOrigin) - (Math.PI/2)) &gt;= EPS) {</span>
+<span class="add">                rho0 = F * Math.pow(Math.tan((Math.PI/4) + 0.5*latitudeOfOrigin), -n);</span>
+<span class="add">            } else {</span>
+<span class="add">                rho0 = 0.0;</span>
+<span class="add">            }</span>
+<span class="add">        } else {</span>
+<span class="add">            final double m1 = msfn(sinphi1, cosphi1);</span>
+<span class="add">            final double t1 = tsfn(phi1, sinphi1);</span>
+<span class="add">            if (secant) {</span>
+<span class="add">                final double sinphi2 = Math.sin(phi2);</span>
+<span class="add">                final double m2 = msfn(sinphi2, Math.cos(phi2));</span>
+<span class="add">                final double t2 = tsfn(phi2, sinphi2);</span>
+<span class="add">                n = Math.log(m1/m2) / Math.log(t1/t2);</span>
+<span class="add">            } else {</span>
+<span class="add">                n = sinphi1;</span>
+<span class="add">            }</span>
+<span class="add">            F = m1 * Math.pow(t1, -n) / n;</span>
+<span class="add">            if (Math.abs(Math.abs(latitudeOfOrigin) - (Math.PI/2)) &gt;= EPS) {</span>
+<span class="add">                rho0 = F * Math.pow(tsfn(latitudeOfOrigin, Math.sin(latitudeOfOrigin)), n);</span>
+<span class="add">            } else {</span>
+<span class="add">                rho0 = 0.0;</span>
+<span class="add">            }</span>
+<span class="add">        }</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * {@inheritDoc}</span>
+<span class="add">     */</span>
+<span class="add">    protected ParameterDescriptorGroup getParameterDescriptors() {</span>
+<span class="add">        return (belgium) ?</span>
+<span class="add">                    Provider2SP_Belgium.PARAMETERS :</span>
+<span class="add">                    ((sp2) ? Provider2SP.PARAMETERS : Provider1SP.PARAMETERS);</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * {@inheritDoc}</span>
+<span class="add">     */</span>
+<span class="add">    public ParameterValueGroup getParameterValues() {</span>
+<span class="add">        final ParameterValueGroup values = super.getParameterValues();</span>
+<span class="add">        if (sp2) {</span>
+<span class="add">            final Collection expected = getParameterDescriptors().descriptors();</span>
+<span class="add">            set(expected, Provider2SP.STANDARD_PARALLEL_1, values, phi1);</span>
+<span class="add">            set(expected, Provider2SP.STANDARD_PARALLEL_2, values, phi2);</span>
+<span class="add">        }</span>
+<span class="add">        return values;</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Transforms the specified (&lt;var&gt;x&lt;/var&gt;,&lt;var&gt;y&lt;/var&gt;) coordinate (units in radians)</span>
+<span class="add">     * and stores the result in &lt;code&gt;ptDst&lt;/code&gt; (linear distance on a unit sphere).</span>
+<span class="add">     */</span>
+<span class="add">    protected Point2D transformNormalized(double x, double y, Point2D ptDst)</span>
+<span class="add">            throws ProjectionException</span>
+<span class="add">    {</span>
+<span class="add">        double rho;</span>
+<span class="add">        //Snyder p. 108</span>
+<span class="add">        if (Math.abs(Math.abs(y) - (Math.PI/2)) &lt; EPS) {</span>
+<span class="add">            if (y*n &lt;= 0) {</span>
+<span class="add">                throw new ProjectionException(Resources.format(</span>
+<span class="add">                        ResourceKeys.ERROR_POLE_PROJECTION_$1,</span>
+<span class="add">                        new Latitude(Math.toDegrees(y))));</span>
+<span class="add">            } else {</span>
+<span class="add">                rho = 0;</span>
+<span class="add">            }</span>
+<span class="add">        } else if (isSpherical) {</span>
+<span class="add">            rho = F * Math.pow(Math.tan((Math.PI/4) + 0.5*y), -n);</span>
+<span class="add">        } else {</span>
+<span class="add">            rho = F * Math.pow(tsfn(y, Math.sin(y)), n);</span>
+<span class="add">        }</span>
+<span class="add"></span>
+<span class="add">        x *= n;</span>
+<span class="add">        if (belgium) {</span>
+<span class="add">            x -= BELGE_A;</span>
+<span class="add">        }</span>
+<span class="add">        y = rho0 - rho * Math.cos(x);</span>
+<span class="add">        x =        rho * Math.sin(x);</span>
+<span class="add"></span>
+<span class="add">        if (ptDst != null) {</span>
+<span class="add">            ptDst.setLocation(x,y);</span>
+<span class="add">            return ptDst;</span>
+<span class="add">        }</span>
+<span class="add">        return new Point2D.Double(x,y);</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Transforms the specified (&lt;var&gt;x&lt;/var&gt;,&lt;var&gt;y&lt;/var&gt;) coordinate</span>
+<span class="add">     * and stores the result in &lt;code&gt;ptDst&lt;/code&gt;.</span>
+<span class="add">     */</span>
+<span class="add">    protected Point2D inverseTransformNormalized(double x, double y, Point2D ptDst)</span>
+<span class="add">            throws ProjectionException</span>
+<span class="add">    {</span>
+<span class="add">        double theta;</span>
+<span class="add">        y = rho0 - y;</span>
+<span class="add">        double rho = Math.sqrt(x*x + y*y);  // Zero when the latitude is 90 degrees.</span>
+<span class="add">        if (rho &gt; EPS) {</span>
+<span class="add">            if (n &lt; 0) {</span>
+<span class="add">                rho = -rho;</span>
+<span class="add">                x = -x;</span>
+<span class="add">                y = -y;</span>
+<span class="add">            }</span>
+<span class="add">            theta = Math.atan2(x, y);</span>
+<span class="add">            if (belgium) {</span>
+<span class="add">                theta += BELGE_A;</span>
+<span class="add">            }</span>
+<span class="add">            x = theta/n;</span>
+<span class="add">            if (isSpherical) {</span>
+<span class="add">                y = 2.0 * Math.atan(Math.pow(F/rho, 1.0/n)) - (Math.PI/2);</span>
+<span class="add">            } else {</span>
+<span class="add">                y = cphi2(Math.pow(rho/F, 1.0/n));</span>
+<span class="add">            }</span>
+<span class="add">        } else {</span>
+<span class="add">            x = 0.0;</span>
+<span class="add">            y = n &lt; 0 ? -(Math.PI/2) : (Math.PI/2);</span>
+<span class="add">        }</span>
+<span class="add">        if (ptDst != null) {</span>
+<span class="add">            ptDst.setLocation(x,y);</span>
+<span class="add">            return ptDst;</span>
+<span class="add">        }</span>
+<span class="add">        return new Point2D.Double(x,y);</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Returns a hash value for this projection.</span>
+<span class="add">     */</span>
+<span class="add">    public int hashCode() {</span>
+<span class="add">        /*</span>
+<span class="add">         * This code should be computed fast. Consequently, we do not use all fields</span>
+<span class="add">         * in this object.  Two &lt;code&gt;LambertConformal&lt;/code&gt; objects with different</span>
+<span class="add">         * {@link #phi1} and {@link #phi2} should compute a F value different enough.</span>
+<span class="add">         */</span>
+<span class="add">        final long code = Double.doubleToLongBits(F);</span>
+<span class="add">        return ((int)code ^ (int)(code &gt;&gt;&gt; 32)) + 37*super.hashCode();</span>
+<span class="add">    }</span>
+<span class="add"></span>
+<span class="add">    /**</span>
+<span class="add">     * Compares the specified object with this map projection for equality.</span>
+<span class="add">     */</span>
+<span class="add">    public boolean equals(final Object object) {</span>
+<span class="add">        if (object == this) {</span>
+<span class="add">            // Slight optimization</span>
+<span class="add">            return true;</span>
+<span class="add">        }</span>
+<span class="add">        if (super.equals(object)) {</span>
+<span class="add">            final LambertConformal that = (LambertConformal) object;</span>
+<span class="add">            return (this.sp2 == that.sp2) &amp;&amp; (this.belgium == that.belgium) &amp;&amp;</span>
+<span class="add">                   equals(this.n,      that.n)    &amp;&amp;</span>
+<span class="add">                   equals(this.F,      that.F)    &amp;&amp;</span>
+<span class="add">                   equals(this.rho0,   that.rho0) &amp;&amp;</span>
+<span class="add">                   equals(this.phi1,   that.phi1) &amp;&amp;</span>
+<span class="add">                   equals(this.phi2,   that.phi2);</span>
+<span class="add">        }</span>
+<span class="add">        return false;</span>
+<span class="add">    }</span>
+<span class="add">}</span></pre></td></tr>
+</table>
+    </div>
+  </body>
+</html>

Propchange: sis/ip-review/rev/09215/LambertConformalESRI.xhtml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/ip-review/rev/09215/LambertConformalESRI.xhtml
------------------------------------------------------------------------------
    svn:mime-type = text/html



Mime
View raw message