You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/04/13 17:20:45 UTC
svn commit: r1673222 [2/5] - in /sis/ip-review: ./ rev/09215/ rev/10796/
rev/11372/ rev/20874/
Added: sis/ip-review/rev/09215/LambertConformal1SP.xhtml
URL: http://svn.apache.org/viewvc/sis/ip-review/rev/09215/LambertConformal1SP.xhtml?rev=1673222&view=auto
==============================================================================
--- sis/ip-review/rev/09215/LambertConformal1SP.xhtml (added)
+++ sis/ip-review/rev/09215/LambertConformal1SP.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>LambertConformal1SP changes for revisions 9214:9215</title>
+ <style type="text/css" media="all">
+ @import url("../../reports.css");
+ </style>
+ </head>
+ <body>
+ <div>
+ <h1>LambertConformal1SP 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/LambertConformal1SP.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"> * <br><br></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"> * <ul></span>
+<span class="add"> * <li><code>Lambert_Conformal_Conic_1SP</code> (EPSG code 9801)</li></span>
+<span class="add"> * <li><code>Lambert_Conformal_Conic_2SP</code> (EPSG code 9802)</li></span>
+<span class="add"> * <li><code>Lambert_Conic_Conformal_2SP_Belgium</code> (EPSG code 9803)</li></span>
+<span class="add"> * </ul></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"> * <br><br></span>
+<span class="add"> *</span>
+<span class="add"> * <strong>References:</strong><ul></span>
+<span class="add"> * <li>John P. Snyder (Map Projections - A Working Manual,<br></span>
+<span class="add"> * U.S. Geological Survey Professional Paper 1395, 1987)</li></span>
+<span class="add"> * <li>"Coordinate Conversions and Transformations including Formulas",<br></span>
+<span class="add"> * EPSG Guidence Note Number 7, Version 19.</li></span>
+<span class="add"> * </ul></span>
+<span class="add"> *</span>
+<span class="add"> * @see <A HREF="http://mathworld.wolfram.com/LambertConformalConicProjection.html">Lambert conformal conic projection on MathWorld</A></span>
+<span class="add"> * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_1sp.html">lambert_conic_conformal_1sp</A></span>
+<span class="add"> * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp.html">lambert_conic_conformal_2sp</A></span>
+<span class="add"> * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp_belgium.html">lambert_conic_conformal_2sp_belgium</A></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"> * <code>true</code> for 2SP, or <code>false</code> 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"> * <code>true</code> 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 <code>true</code> for 2SP, or <code>false</code> for 1SP.</span>
+<span class="add"> * @param belgium <code>true</code> 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) < 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) > 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)) >= 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)) >= 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 (<var>x</var>,<var>y</var>) coordinate (units in radians)</span>
+<span class="add"> * and stores the result in <code>ptDst</code> (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)) < EPS) {</span>
+<span class="add"> if (y*n <= 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 (<var>x</var>,<var>y</var>) coordinate</span>
+<span class="add"> * and stores the result in <code>ptDst</code>.</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 > EPS) {</span>
+<span class="add"> if (n < 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 < 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 <code>LambertConformal</code> 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 >>> 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) && (this.belgium == that.belgium) &&</span>
+<span class="add"> equals(this.n, that.n) &&</span>
+<span class="add"> equals(this.F, that.F) &&</span>
+<span class="add"> equals(this.rho0, that.rho0) &&</span>
+<span class="add"> equals(this.phi1, that.phi1) &&</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/LambertConformal1SP.xhtml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/ip-review/rev/09215/LambertConformal1SP.xhtml
------------------------------------------------------------------------------
svn:mime-type = text/html
Added: sis/ip-review/rev/09215/LambertConformal2SP.xhtml
URL: http://svn.apache.org/viewvc/sis/ip-review/rev/09215/LambertConformal2SP.xhtml?rev=1673222&view=auto
==============================================================================
--- sis/ip-review/rev/09215/LambertConformal2SP.xhtml (added)
+++ sis/ip-review/rev/09215/LambertConformal2SP.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>LambertConformal2SP changes for revisions 9214:9215</title>
+ <style type="text/css" media="all">
+ @import url("../../reports.css");
+ </style>
+ </head>
+ <body>
+ <div>
+ <h1>LambertConformal2SP 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/LambertConformal2SP.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"> * <br><br></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"> * <ul></span>
+<span class="add"> * <li><code>Lambert_Conformal_Conic_1SP</code> (EPSG code 9801)</li></span>
+<span class="add"> * <li><code>Lambert_Conformal_Conic_2SP</code> (EPSG code 9802)</li></span>
+<span class="add"> * <li><code>Lambert_Conic_Conformal_2SP_Belgium</code> (EPSG code 9803)</li></span>
+<span class="add"> * </ul></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"> * <br><br></span>
+<span class="add"> *</span>
+<span class="add"> * <strong>References:</strong><ul></span>
+<span class="add"> * <li>John P. Snyder (Map Projections - A Working Manual,<br></span>
+<span class="add"> * U.S. Geological Survey Professional Paper 1395, 1987)</li></span>
+<span class="add"> * <li>"Coordinate Conversions and Transformations including Formulas",<br></span>
+<span class="add"> * EPSG Guidence Note Number 7, Version 19.</li></span>
+<span class="add"> * </ul></span>
+<span class="add"> *</span>
+<span class="add"> * @see <A HREF="http://mathworld.wolfram.com/LambertConformalConicProjection.html">Lambert conformal conic projection on MathWorld</A></span>
+<span class="add"> * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_1sp.html">lambert_conic_conformal_1sp</A></span>
+<span class="add"> * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp.html">lambert_conic_conformal_2sp</A></span>
+<span class="add"> * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/lambert_conic_conformal_2sp_belgium.html">lambert_conic_conformal_2sp_belgium</A></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"> * <code>true</code> for 2SP, or <code>false</code> 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"> * <code>true</code> 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 <code>true</code> for 2SP, or <code>false</code> for 1SP.</span>
+<span class="add"> * @param belgium <code>true</code> 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) < 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) > 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)) >= 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)) >= 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 (<var>x</var>,<var>y</var>) coordinate (units in radians)</span>
+<span class="add"> * and stores the result in <code>ptDst</code> (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)) < EPS) {</span>
+<span class="add"> if (y*n <= 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 (<var>x</var>,<var>y</var>) coordinate</span>
+<span class="add"> * and stores the result in <code>ptDst</code>.</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 > EPS) {</span>
+<span class="add"> if (n < 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 < 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 <code>LambertConformal</code> 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 >>> 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) && (this.belgium == that.belgium) &&</span>
+<span class="add"> equals(this.n, that.n) &&</span>
+<span class="add"> equals(this.F, that.F) &&</span>
+<span class="add"> equals(this.rho0, that.rho0) &&</span>
+<span class="add"> equals(this.phi1, that.phi1) &&</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/LambertConformal2SP.xhtml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sis/ip-review/rev/09215/LambertConformal2SP.xhtml
------------------------------------------------------------------------------
svn:mime-type = text/html