blob: 5952a8a0fb9746bdaf0dc0c6057c8ebff5693ffd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sis.referencing.operation.projection;
import java.util.Random;
import org.opengis.util.FactoryException;
import org.opengis.referencing.operation.TransformException;
import org.apache.sis.internal.referencing.Formulas;
import org.apache.sis.internal.referencing.provider.TransverseMercatorSouth;
import org.apache.sis.parameter.Parameters;
import org.apache.sis.referencing.operation.transform.CoordinateDomain;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.junit.Test;
import static java.lang.Double.NaN;
import static java.lang.StrictMath.toRadians;
import static org.apache.sis.test.Assert.*;
/**
* Tests the {@link TransverseMercator} class.
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.6
* @version 0.7
* @module
*/
@DependsOn(NormalizedProjectionTest.class)
public final strictfp class TransverseMercatorTest extends MapProjectionTestCase {
/**
* Creates a new instance of {@link TransverseMercator}.
*
* @param ellipse {@code false} for a sphere, or {@code true} for WGS84 ellipsoid.
*/
private void createNormalizedProjection(final boolean ellipse, final double latitudeOfOrigin) {
final org.apache.sis.internal.referencing.provider.TransverseMercator method =
new org.apache.sis.internal.referencing.provider.TransverseMercator();
final Parameters parameters = parameters(method, ellipse);
parameters.getOrCreate(org.apache.sis.internal.referencing.provider.TransverseMercator.LATITUDE_OF_ORIGIN).setValue(latitudeOfOrigin);
transform = new TransverseMercator(method, parameters);
tolerance = NORMALIZED_TOLERANCE;
validate();
}
/**
* Tests the <cite>Transverse Mercator</cite> case (EPSG:9807).
* This test is defined in GeoAPI conformance test suite.
*
* @throws FactoryException if an error occurred while creating the map projection.
* @throws TransformException if an error occurred while projecting a coordinate.
*
* @see org.opengis.test.referencing.ParameterizedTransformTest#testTransverseMercator()
*/
@Test
public void testTransverseMercator() throws FactoryException, TransformException {
createGeoApiTest(new org.apache.sis.internal.referencing.provider.TransverseMercator()).testTransverseMercator();
}
/**
* Tests the <cite>Transverse Mercator (South Orientated)</cite> case (EPSG:9808).
* This test is defined in GeoAPI conformance test suite.
*
* @throws FactoryException if an error occurred while creating the map projection.
* @throws TransformException if an error occurred while projecting a coordinate.
*
* @see org.opengis.test.referencing.ParameterizedTransformTest#testTransverseMercatorSouthOrientated()
*/
@Test
@DependsOnMethod("testTransverseMercator")
public void testTransverseMercatorSouthOrientated() throws FactoryException, TransformException {
createGeoApiTest(new TransverseMercatorSouth()).testTransverseMercatorSouthOrientated();
}
/**
* Verifies the consistency of elliptical formulas with the spherical formulas.
* This test compares the results of elliptical formulas with the spherical ones
* for some random points.
*
* @throws FactoryException if an error occurred while creating the map projection.
* @throws TransformException if an error occurred while projecting a coordinate.
*/
@Test
@DependsOnMethod("testTransverseMercator")
public void compareEllipticalWithSpherical() throws FactoryException, TransformException {
createCompleteProjection(new org.apache.sis.internal.referencing.provider.TransverseMercator(),
6371007, // Semi-major axis length
6371007, // Semi-minor axis length
0.5, // Central meridian
2.5, // Latitude of origin
NaN, // Standard parallel 1 (none)
NaN, // Standard parallel 1 (none)
0.997, // Scale factor
200, // False easting
100); // False northing
tolerance = Formulas.LINEAR_TOLERANCE;
compareEllipticalWithSpherical(CoordinateDomain.RANGE_10, 0);
}
/**
* Creates a projection and derivates a few points.
*
* @throws TransformException if an error occurred while projecting a point.
*/
@Test
public void testSphericalDerivative() throws TransformException {
createNormalizedProjection(false, 0);
tolerance = 1E-9;
final double delta = toRadians(100.0 / 60) / 1852; // Approximatively 100 metres.
derivativeDeltas = new double[] {delta, delta};
verifyDerivative(toRadians( 0), toRadians( 0));
verifyDerivative(toRadians(-3), toRadians(30));
verifyDerivative(toRadians(+6), toRadians(60));
}
/**
* Creates a projection and derivates a few points.
*
* @throws TransformException if an error occurred while projecting a point.
*/
@Test
public void testEllipsoidalDerivative() throws TransformException {
createNormalizedProjection(true, 0);
tolerance = 1E-9;
final double delta = toRadians(100.0 / 60) / 1852; // Approximatively 100 metres.
derivativeDeltas = new double[] {delta, delta};
verifyDerivative(toRadians( 0), toRadians( 0));
verifyDerivative(toRadians(-3), toRadians(30));
verifyDerivative(toRadians(+6), toRadians(60));
}
/**
* Verifies that deserialized projections work as expected. This implies that deserialization
* recomputed the internal transient fields, especially the series expansion coefficients.
*
* @throws FactoryException if an error occurred while creating the map projection.
* @throws TransformException if an error occurred while projecting a coordinate.
*/
@Test
@DependsOnMethod("testTransverseMercator")
public void testSerialization() throws FactoryException, TransformException {
createNormalizedProjection(true, 40);
/*
* Use a fixed seed for the random number generator in this test, because in case of failure this class will not
* report which seed it used. This limitation exists because this test class does not extend the SIS TestCase.
*/
final double[] source = CoordinateDomain.GEOGRAPHIC_RADIANS_HALF_λ.generateRandomInput(new Random(5346144739450824145L), 2, 10);
final double[] target = new double[source.length];
for (int i=0; i<source.length; i+=2) {
// A longitude range of [-90 … +90]° is still too wide for Transverse Mercator. Reduce to [-45 … +45]°.
source[i] /= 2;
}
transform.transform(source, 0, target, 0, 10);
transform = assertSerializedEquals(transform);
tolerance = Formulas.LINEAR_TOLERANCE;
verifyTransform(source, target);
}
}