/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2011-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2011-2012, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.referencing.operation.projection; import java.awt.geom.Point2D; import org.apache.sis.test.DependsOn; import org.opengis.referencing.operation.TransformException; import org.apache.sis.referencing.operation.transform.AbstractMathTransform1D; import org.junit.*; import static java.lang.StrictMath.*; import static org.junit.Assert.*; /** * Tests the {@link CassiniOrMercator} class. This class uses {@link CassiniSoldner} * for testing purpose. * * @author Martin Desruisseaux (Geomatys) * @author Rémi Maréchal (Geomatys) * * @since 3.18 */ @DependsOn(UnitaryProjectionTest.class) public final strictfp class CassiniOrMercatorTest extends ProjectionTestBase { /** * Creates a default test suite. */ public CassiniOrMercatorTest() { super(CassiniOrMercator.class, null); } /** * Tests some identities related to the {@link CassiniOrMercator#mlfn} method. * * @throws TransformException Should never happen. */ @Test public void testDmlfn() throws TransformException { final CassiniSoldner cassini = CassiniSoldnerTest.create(false); // assertEquals("Expected spherical projection.", 0, cassini.excentricity, 0); for (double φ = -PI/3; φ <= PI/3; φ += 0.01) { assertEquals("When excentricity=0, mlfn(φ, sinφ, cosφ) simplify to φ.", φ, cassini.mlfn(φ, sin(φ), cos(φ)), 1E-9); } /* * Now fix φ=45°, which implies tan(φ)=1. * Test using the CassiniSoldner spherical equation. */ final Point2D.Double point = new Point2D.Double(); final double domain = toRadians(5); final double step = domain/100; for (double λ=-domain; λ<=domain; λ+=step) { final double yFromSimplified = PI/2 - atan(cos(λ)); point.x = λ; point.y = PI/4; assertSame(point, cassini.transform(point, point)); assertEquals("Given excentricity=0 and φ=45°, the spherical equation should simplify to a " + "very simple expression, which we are testing here.", yFromSimplified, point.y, 1E-9); /* * In the equation below, PI/4 is actually mlfn(φ) where the excentricity=0 and φ=45°. * In our simplified case, the equation using the ellipsoidal formula seems to be an * approximation of PI/2 - atan(cos(λ)). This looks like a sine function (but is not * exactly a sine function). */ final double λ2 = λ*λ; final double yEllps = PI/4 + λ2*(0.25 + λ2*0.41666666666666666666); // CassiniSoldner.C3 assertEquals("Approximation of PI/2 - atan(cos(λ)", yFromSimplified, yEllps, 3E-5); } } /** * Tests the {@link CassiniOrMercator#dmlfn_dφ} method. * * @throws TransformException Should never happen. */ @Test public void testDmlfn_dφ() throws TransformException { isInverseTransformSupported = false; derivativeDeltas = new double[] {2E-8}; tolerance = 1E-7; boolean ellipse = false; do { final CassiniOrMercator cassini = CassiniSoldnerTest.create(ellipse); transform = new AbstractMathTransform1D() { @Override public double transform (final double φ) { return cassini.mlfn(φ, sin(φ), cos(φ)); } @Override public double derivative(final double φ) { final double sinφ = sin(φ); final double cosφ = cos(φ); return cassini.dmlfn_dφ(sinφ*sinφ, cosφ*cosφ); } }; verifyInDomain(new double[] {-PI/3}, new double[] {PI/3}, new int[] {100}, null); } while ((ellipse = !ellipse) == true); } }