This is an automated email from the ASF dual-hosted git repository. desruisseaux pushed a commit to branch geoapi-4.0 in repository https://gitbox.apache.org/repos/asf/sis.git
commit a7331c907e1a349650c4f0b30ae864d13bebc0b5 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Sat Oct 28 19:10:10 2023 +0200 Remove the deprecated `InterpolatedMolodenskyTransform` class. --- .../provider/FranceGeocentricInterpolation.java | 23 +- .../provider/MolodenskyInterpolation.java | 105 ----- .../operation/transform/DatumShiftTransform.java | 32 +- .../transform/InterpolatedGeocentricTransform.java | 30 +- .../transform/InterpolatedMolodenskyTransform.java | 458 --------------------- .../InterpolatedMolodenskyTransform2D.java | 139 ------- .../operation/transform/MolodenskyFormula.java | 47 +-- .../operation/transform/MolodenskyTransform.java | 2 +- .../operation/transform/package-info.java | 2 +- .../operation/provider/ProvidersTest.java | 1 - .../InterpolatedMolodenskyTransformTest.java | 130 ------ 11 files changed, 42 insertions(+), 927 deletions(-) diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolation.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolation.java index 81254b185f..8ecac1c44e 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolation.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolation.java @@ -226,9 +226,8 @@ public class FranceGeocentricInterpolation extends GeodeticOperation { /** * Returns the provider for the specified combination of source and target dimensions. */ - // TODO: make final after removal of deprecated `MolodenskyInterpolation` subclass. @Override - GeodeticOperation redimensioned(int indexOfDim) { + final GeodeticOperation redimensioned(int indexOfDim) { return REDIMENSIONED[indexOfDim]; } @@ -357,12 +356,11 @@ public class FranceGeocentricInterpolation extends GeodeticOperation { // NumberFormatException, ArithmeticException, NoSuchElementException, and more. throw DatumShiftGridLoader.canNotLoad(HEADER, file, e); } - MathTransform tr = createGeodeticTransformation(factory, + MathTransform tr = InterpolatedGeocentricTransform.createGeodeticTransformation(factory, createEllipsoid(pg, Molodensky.TGT_SEMI_MAJOR, - Molodensky.TGT_SEMI_MINOR, CommonCRS.ETRS89.ellipsoid()), // GRS 1980 ellipsoid + Molodensky.TGT_SEMI_MINOR, CommonCRS.ETRS89.ellipsoid()), withHeights, // GRS 1980 ellipsoid createEllipsoid(pg, Molodensky.SRC_SEMI_MAJOR, - Molodensky.SRC_SEMI_MINOR, null), // Clarke 1880 (IGN) ellipsoid - withHeights, grid); + Molodensky.SRC_SEMI_MINOR, null), withHeights, grid); // Clarke 1880 (IGN) ellipsoid try { tr = tr.inverse(); } catch (NoninvertibleTransformException e) { @@ -371,19 +369,6 @@ public class FranceGeocentricInterpolation extends GeodeticOperation { return tr; } - /** - * Creates the actual math transform. The default implementation delegates to the static method defined in - * {@link InterpolatedGeocentricTransform}, but the {@link MolodenskyInterpolation} subclass will rather - * delegate to {@link org.apache.sis.referencing.operation.transform.InterpolatedMolodenskyTransform}. - */ - MathTransform createGeodeticTransformation(final MathTransformFactory factory, - final Ellipsoid source, final Ellipsoid target, final boolean withHeights, - final DatumShiftGridFile<Angle,Length> grid) throws FactoryException - { - return InterpolatedGeocentricTransform.createGeodeticTransformation( - factory, source, withHeights, target, withHeights, grid); - } - /** * Returns the grid of the given name. This method returns the cached instance if it still exists, * or load the grid otherwise. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/MolodenskyInterpolation.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/MolodenskyInterpolation.java deleted file mode 100644 index 1630d9161a..0000000000 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/MolodenskyInterpolation.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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.provider; - -import java.util.Arrays; -import jakarta.xml.bind.annotation.XmlTransient; -import javax.measure.quantity.Angle; -import javax.measure.quantity.Length; -import org.opengis.util.FactoryException; -import org.opengis.referencing.datum.Ellipsoid; -import org.opengis.referencing.operation.MathTransform; -import org.opengis.referencing.operation.MathTransformFactory; -import org.opengis.parameter.ParameterDescriptorGroup; -import org.opengis.parameter.ParameterValueGroup; -import org.apache.sis.util.internal.Constants; -import org.apache.sis.referencing.operation.transform.InterpolatedMolodenskyTransform; - - -/** - * An approximation of geocentric interpolations which uses {@link InterpolatedMolodenskyTransform} - * instead of {@link org.apache.sis.referencing.operation.transform.InterpolatedGeocentricTransform}. - * - * <p>This operation method is not standard, and as of SIS 0.7 not yet registered in the operation methods - * provided by {@link org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory}. - * This class extends {@code FranceGeocentricInterpolation} for now because the latter is currently - * the only operation performing interpolation in the geocentric domain. - * However, this class hierarchy may be revisited in any future SIS version.</p> - * - * @author Martin Desruisseaux (Geomatys) - * - * @see <a href="https://issues.apache.org/jira/browse/SIS-500">Deprecate (for removal) InterpolatedMolodenskyTransform</a> - */ -@XmlTransient -@Deprecated(since="1.4", forRemoval=true) -// Note: after removal, delete overrideable method in parent class. -public final class MolodenskyInterpolation extends FranceGeocentricInterpolation { - /** - * Serial number for inter-operability with different versions. - */ - private static final long serialVersionUID = 4265894749866901286L; - - /** - * The providers for all combinations between 2D and 3D cases. - */ - private static final MolodenskyInterpolation[] REDIMENSIONED = new MolodenskyInterpolation[4]; - static { - final ParameterDescriptorGroup parameters = builder().setCodeSpace(null, Constants.SIS) - .addName("Molodensky interpolation").createGroupWithSameParameters(PARAMETERS); - Arrays.setAll(REDIMENSIONED, (i) -> new MolodenskyInterpolation(parameters, i)); - } - - /** - * Returns the provider for the specified combination of source and target dimensions. - */ - @Override - final GeodeticOperation redimensioned(int indexOfDim) { - return REDIMENSIONED[indexOfDim]; - } - - /** - * Creates a copy of this provider. - * - * @deprecated This is a temporary constructor before replacement by a {@code provider()} method with JDK9. - */ - @Deprecated - public MolodenskyInterpolation() { - super(REDIMENSIONED[INDEX_OF_2D]); - } - - /** - * Constructs a provider for the given number of dimensions. - */ - @SuppressWarnings("removal") - private MolodenskyInterpolation(ParameterDescriptorGroup parameters, int indexOfDim) { - super(parameters, indexOfDim); - } - - /** - * Invoked by {@link #createMathTransform(MathTransformFactory, ParameterValueGroup)} - * after all parameters have been processed. - */ - @Override - @SuppressWarnings("removal") - MathTransform createGeodeticTransformation(final MathTransformFactory factory, - final Ellipsoid source, final Ellipsoid target, final boolean withHeights, - final DatumShiftGridFile<Angle,Length> grid) throws FactoryException - { - return InterpolatedMolodenskyTransform.createGeodeticTransformation( - factory, source, withHeights, target, withHeights, grid); - } -} diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DatumShiftTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DatumShiftTransform.java index 2a914108ce..578c24069d 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DatumShiftTransform.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/DatumShiftTransform.java @@ -27,15 +27,12 @@ import org.opengis.referencing.datum.Ellipsoid; import org.opengis.referencing.operation.Matrix; import org.opengis.parameter.ParameterValueGroup; import org.opengis.parameter.ParameterDescriptorGroup; -import org.opengis.geometry.MismatchedDimensionException; import org.apache.sis.referencing.datum.DatumShiftGrid; import org.apache.sis.referencing.operation.matrix.Matrices; -import org.apache.sis.referencing.internal.Resources; import org.apache.sis.referencing.operation.provider.Molodensky; import org.apache.sis.measure.Units; import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.Debug; -import org.apache.sis.util.resources.Errors; /** @@ -65,15 +62,14 @@ import org.apache.sis.util.resources.Errors; * * <p>Some countries go one step further and allow the above geocentric translations to be non-constant. * Instead, a different geocentric translation is interpolated for each geographic input coordinates. - * This case is handled by the {@link InterpolatedGeocentricTransform} subclass, or its - * {@link InterpolatedMolodenskyTransform} variant if a few centimetres accuracy lost can be afforded.</p> + * This case is handled by the {@link InterpolatedGeocentricTransform} subclass.</p> * * <p>A simpler alternative to the above is to interpolate translations to apply directly on geographic coordinates. * This is the approach taken by NADCON and NTv2 grids. * SIS handles those datum shifts with the {@link InterpolatedTransform} subclass.</p> * * @author Martin Desruisseaux (Geomatys) - * @version 1.0 + * @version 1.5 * * @see DatumShiftGrid * @@ -204,30 +200,6 @@ public abstract class DatumShiftTransform extends AbstractMathTransform implemen return m.getElement(j, j); } - /** - * Ensures that the {@link #grid} performs geocentric translations in the given units. - * This method is invoked by constructor for validation of given arguments. - * - * <p>This method is defined here in order to ensure a consistent behavior of - * {@link InterpolatedGeocentricTransform} with {@link InterpolatedMolodenskyTransform}.</p> - * - * @param grid the grid to validate. - * @param unit the unit of semi-axis length of the <strong>source</strong> ellipsoid. - * @throws IllegalArgumentException if the given grid is not valid. - */ - static void ensureGeocentricTranslation(final DatumShiftGrid<?,?> grid, final Unit<Length> unit) - throws IllegalArgumentException - { - final int dim = grid.getTranslationDimensions(); - if (dim != 3) { - throw new MismatchedDimensionException(Errors.format(Errors.Keys.MismatchedDimension_3, "grid", 3, dim)); - } - Object unitLabel = "ratio"; - if (grid.isCellValueRatio() || (unitLabel = grid.getTranslationUnit()) != unit) { - throw new IllegalArgumentException(Resources.format(Resources.Keys.IllegalUnitFor_2, "translation", unitLabel)); - } - } - /** * Sets the semi-axis length in the {@link #context} parameters. * This is a helper method for constructors in some (not all) subclasses. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java index d122b52f1f..68135b8bf1 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java @@ -22,6 +22,7 @@ import javax.measure.quantity.Length; import org.opengis.util.FactoryException; import org.opengis.parameter.ParameterDescriptor; import org.opengis.parameter.ParameterDescriptorGroup; +import org.opengis.geometry.MismatchedDimensionException; import org.opengis.referencing.datum.Ellipsoid; import org.opengis.referencing.operation.Matrix; import org.opengis.referencing.operation.MathTransform; @@ -31,11 +32,13 @@ import org.opengis.referencing.operation.TransformException; import org.apache.sis.referencing.operation.provider.FranceGeocentricInterpolation; import org.apache.sis.referencing.operation.provider.Molodensky; import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.resources.Errors; import org.apache.sis.util.internal.Constants; import org.apache.sis.metadata.iso.citation.Citations; import org.apache.sis.parameter.ParameterBuilder; import org.apache.sis.referencing.datum.DatumShiftGrid; import org.apache.sis.referencing.operation.matrix.Matrices; +import org.apache.sis.referencing.internal.Resources; /** @@ -73,16 +76,10 @@ import org.apache.sis.referencing.operation.matrix.Matrices; * because the {@code DatumShiftGrid} inputs are geographic coordinates even if the interpolated * grid values are in geocentric space.</p> * - * <h2>Performance consideration</h2> - * {@link InterpolatedMolodenskyTransform} performs the same calculation more efficiently at the cost of - * a few centimetres error. Both classes are instantiated in the same way and expect the same inputs. - * * @author Simon Reynard (Geomatys) * @author Martin Desruisseaux (Geomatys) * @version 1.0 * - * @see InterpolatedMolodenskyTransform - * * @since 0.7 */ public class InterpolatedGeocentricTransform extends DatumShiftTransform { @@ -284,6 +281,27 @@ public class InterpolatedGeocentricTransform extends DatumShiftTransform { this.inverse = inverse; } + /** + * Ensures that the {@link #grid} performs geocentric translations in the given units. + * This method is invoked by constructor for validation of given arguments. + * + * @param grid the grid to validate. + * @param unit the unit of semi-axis length of the <strong>source</strong> ellipsoid. + * @throws IllegalArgumentException if the given grid is not valid. + */ + private static void ensureGeocentricTranslation(final DatumShiftGrid<?,?> grid, final Unit<Length> unit) + throws IllegalArgumentException + { + final int dim = grid.getTranslationDimensions(); + if (dim != 3) { + throw new MismatchedDimensionException(Errors.format(Errors.Keys.MismatchedDimension_3, "grid", 3, dim)); + } + Object unitLabel = "ratio"; + if (grid.isCellValueRatio() || (unitLabel = grid.getTranslationUnit()) != unit) { + throw new IllegalArgumentException(Resources.format(Resources.Keys.IllegalUnitFor_2, "translation", unitLabel)); + } + } + /** * Delegates to {@link ContextualParameters#completeTransform(MathTransformFactory, MathTransform)} * for this transformation and for its dependencies as well. diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform.java deleted file mode 100644 index 512dae1395..0000000000 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform.java +++ /dev/null @@ -1,458 +0,0 @@ -/* - * 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.transform; - -import java.util.Arrays; -import javax.measure.Unit; -import javax.measure.quantity.Angle; -import javax.measure.quantity.Length; -import org.opengis.util.FactoryException; -import org.opengis.parameter.ParameterDescriptor; -import org.opengis.parameter.ParameterDescriptorGroup; -import org.opengis.referencing.datum.Ellipsoid; -import org.opengis.referencing.operation.Matrix; -import org.opengis.referencing.operation.MathTransform; -import org.opengis.referencing.operation.MathTransformFactory; -import org.opengis.referencing.operation.TransformException; -import org.apache.sis.referencing.operation.provider.FranceGeocentricInterpolation; -import org.apache.sis.referencing.operation.provider.Molodensky; -import org.apache.sis.util.ArgumentChecks; -import org.apache.sis.util.Debug; -import org.apache.sis.util.internal.Constants; -import org.apache.sis.metadata.iso.citation.Citations; -import org.apache.sis.parameter.Parameters; -import org.apache.sis.parameter.ParameterBuilder; -import org.apache.sis.referencing.datum.DatumShiftGrid; -import org.apache.sis.measure.Units; - - -/** - * Transforms between two geographic CRS by performing geocentric translations interpolated from a grid file, but using - * Molodensky approximation. This transformation is conceptually defined as a translation in geocentric coordinates - * as performed by {@link InterpolatedGeocentricTransform}, but uses the {@linkplain MolodenskyTransform Molodensy} - * (non-abridged) approximation for performance reasons. - * Errors are less than 3 centimetres for the <cite>"France geocentric interpolation"</cite> (ESPG:9655). - * By comparison, the finest accuracy reported in the grid file for France is 5 centimetres. - * - * <h2>Algorithm</h2> - * This class transforms two- or three- dimensional coordinates from a geographic CRS to another geographic CRS. - * The changes between source and target coordinates are small (usually less than 400 metres), but vary for every - * position. Those changes are provided in a {@linkplain DatumShiftGrid datum shift grid}, usually loaded from one - * or two files. - * - * <p>Many datum shift grids like NADCON and NTv2 apply the interpolated translations directly on geographic coordinates. - * This relatively simple case is handled by {@link InterpolatedTransform}. - * But in the {@code InterpolatedMolodenskyTransform} case, the interpolated translations are rather the - * ({@linkplain #tX}, {@linkplain #tY}, {@linkplain #tZ}) parameters of a Molodensky transformation.</p> - * - * @deprecated This operation method is non-standard, of little use and has greater errors than intended. - * - * @author Martin Desruisseaux (Geomatys) - * @version 1.0 - * - * @see <a href="https://issues.apache.org/jira/browse/SIS-500">Deprecate (for removal) InterpolatedMolodenskyTransform</a> - * @see InterpolatedGeocentricTransform - * - * @since 0.7 - */ -@Deprecated(since="1.4", forRemoval=true) -public class InterpolatedMolodenskyTransform extends MolodenskyFormula { - /** - * Serial number for inter-operability with different versions. - */ - private static final long serialVersionUID = -5691721806681489940L; - - /** - * Parameter descriptor to use with the contextual parameters for the forward and inverse transformations. - * We do not use directly the <cite>"France geocentric interpolation"</cite> (ESPG:9655) descriptor because - * this {@code InterpolatedMolodenskyTransform} is an approximation of {@link InterpolatedGeocentricTransform} - * and the conventions used by SIS are different than EPSG:9655 ones. - */ - private static final ParameterDescriptorGroup DESCRIPTOR, INVERSE; - static { - final ParameterBuilder builder = new ParameterBuilder() - .setRequired(true).setCodeSpace(Citations.SIS, Constants.SIS); - DESCRIPTOR = builder.addName("Molodensky interpolation") - .createGroupWithSameParameters(InterpolatedGeocentricTransform.DESCRIPTOR); - INVERSE = builder.addName("Molodensky inverse interpolation") - .createGroupWithSameParameters(InterpolatedGeocentricTransform.DESCRIPTOR); - } - - /** - * The inverse of this interpolated Molodensky transform. - * - * @see #inverse() - */ - private final InterpolatedMolodenskyTransform inverse; - - /** - * Constructs the inverse of an interpolated Molodensky transform. - * - * @param inverse the transform for which to create the inverse. - * @param source the source ellipsoid of the given {@code inverse} transform. - * @param target the target ellipsoid of the given {@code inverse} transform. - */ - InterpolatedMolodenskyTransform(final InterpolatedMolodenskyTransform inverse, Ellipsoid source, Ellipsoid target) { - super(inverse, source, target, INVERSE); - this.inverse = inverse; - } - - /** - * Creates a transform from the specified parameters. - * This {@code InterpolatedMolodenskyTransform} class expects coordinate values in the following order and units: - * <ol> - * <li>longitudes in <strong>radians</strong> relative to the prime meridian (usually Greenwich),</li> - * <li>latitudes in <strong>radians</strong>,</li> - * <li>optionally heights above the ellipsoid, in same units than the source ellipsoid axes.</li> - * </ol> - * - * For converting geographic coordinates in degrees, {@code InterpolatedMolodenskyTransform} instances - * need to be concatenated with the following affine transforms: - * - * <ul> - * <li><cite>Normalization</cite> before {@code InterpolatedMolodenskyTransform}:<ul> - * <li>Conversion of (λ,φ) from degrees to radians.</li> - * </ul></li> - * <li><cite>Denormalization</cite> after {@code InterpolatedMolodenskyTransform}:<ul> - * <li>Conversion of (λ,φ) from radians to degrees.</li> - * </ul></li> - * </ul> - * - * After {@code InterpolatedMolodenskyTransform} construction, - * the full conversion chain including the above affine transforms can be created by - * <code>{@linkplain #getContextualParameters()}.{@linkplain ContextualParameters#completeTransform - * completeTransform}(factory, this)}</code>. - * - * @param source the source ellipsoid. - * @param isSource3D {@code true} if the source coordinates have a height. - * @param target the target ellipsoid. - * @param isTarget3D {@code true} if the target coordinates have a height. - * @param grid the grid of datum shifts from source to target datum. - * The {@link DatumShiftGrid#interpolateInCell DatumShiftGrid.interpolateInCell(…)} method - * shall compute (ΔX, ΔY, ΔZ) translations from <em>source</em> to <em>target</em> in the - * unit of source ellipsoid axes. - * - * @see #createGeodeticTransformation(MathTransformFactory, Ellipsoid, boolean, Ellipsoid, boolean, DatumShiftGrid) - */ - @SuppressWarnings("removal") - protected InterpolatedMolodenskyTransform(final Ellipsoid source, final boolean isSource3D, - final Ellipsoid target, final boolean isTarget3D, - final DatumShiftGrid<Angle,Length> grid) - { - super(source, isSource3D, - target, isTarget3D, - grid.getCellMean(0), - grid.getCellMean(1), - grid.getCellMean(2), - grid, false, DESCRIPTOR); - - ensureGeocentricTranslation(grid, source.getAxisUnit()); - if (isSource3D || isTarget3D) { - inverse = new Inverse(this, source, target); - } else { - inverse = new InterpolatedMolodenskyTransform2D.Inverse(this, source, target); - } - } - - /** - * Creates a transformation between two geographic CRS. This factory method combines the - * {@code InterpolatedMolodenskyTransform} instance with the steps needed for converting values between - * degrees to radians. The transform works with input and output coordinates in the following units: - * - * <ol> - * <li>longitudes in <strong>degrees</strong> relative to the prime meridian (usually Greenwich),</li> - * <li>latitudes in <strong>degrees</strong>,</li> - * <li>optionally heights above the ellipsoid, in same units than the source ellipsoids axes.</li> - * </ol> - * - * Note however that the given {@code grid} instance shall expect geographic coordinates (λ,φ) - * in <strong>radians</strong>. - * - * @param factory the factory to use for creating the transform. - * @param source the source ellipsoid. - * @param isSource3D {@code true} if the source coordinates have a height. - * @param target the target ellipsoid. - * @param isTarget3D {@code true} if the target coordinates have a height. - * @param grid the grid of datum shifts from source to target datum. - * The {@link DatumShiftGrid#interpolateInCell DatumShiftGrid.interpolateInCell(…)} method - * shall compute (ΔX, ΔY, ΔZ) translations from <em>source</em> to <em>target</em> in the - * unit of source ellipsoid axes. - * @return the transformation between geographic coordinates in degrees. - * @throws FactoryException if an error occurred while creating a transform. - */ - @SuppressWarnings("removal") - public static MathTransform createGeodeticTransformation(final MathTransformFactory factory, - final Ellipsoid source, final boolean isSource3D, - final Ellipsoid target, final boolean isTarget3D, - final DatumShiftGrid<Angle,Length> grid) throws FactoryException - { - ArgumentChecks.ensureNonNull("grid", grid); - final InterpolatedMolodenskyTransform tr; - if (isSource3D || isTarget3D) { - tr = new InterpolatedMolodenskyTransform(source, isSource3D, target, isTarget3D, grid); - } else { - tr = new InterpolatedMolodenskyTransform2D(source, target, grid); - } - tr.inverse.context.completeTransform(factory, null); - return tr.context.completeTransform(factory, tr); - } - - /** - * Invoked by constructor and by {@link #getParameterValues()} for setting all parameters other than axis lengths. - * - * @param pg where to set the parameters. - * @param semiMinor the semi minor axis length, in unit of {@code unit}. - * @param unit the unit of measurement to declare. - * @param Δf ignored. - */ - @Override - final void completeParameters(final Parameters pg, final double semiMinor, final Unit<?> unit, double Δf) { - super.completeParameters(pg, semiMinor, unit, Δf); - if (pg != context) { - Δf = Δfmod / semiMinor; - pg.getOrCreate(Molodensky.AXIS_LENGTH_DIFFERENCE).setValue(Δa, unit); - pg.getOrCreate(Molodensky.FLATTENING_DIFFERENCE) .setValue(Δf, Units.UNITY); - } - grid.getParameterValues(pg); - } - - /** - * Transforms the (λ,φ) or (λ,φ,<var>h</var>) coordinates between two geographic CRS, - * and optionally returns the derivative at that location. - * - * @return {@inheritDoc} - * @throws TransformException if the point cannot be transformed or - * if a problem occurred while calculating the derivative. - */ - @Override - public Matrix transform(final double[] srcPts, final int srcOff, - final double[] dstPts, final int dstOff, - final boolean derivate) throws TransformException - { - final double[] vector = new double[3]; - final double λ = srcPts[srcOff]; - final double φ = srcPts[srcOff+1]; - grid.interpolateInCell(normalizedToGridX(λ), - normalizedToGridY(φ), vector); - return transform(λ, φ, isSource3D ? srcPts[srcOff+2] : 0, - dstPts, dstOff, vector[0], vector[1], vector[2], null, derivate); - } - - /** - * Transforms the (λ,φ) or (λ,φ,<var>h</var>) coordinates between two geographic CRS. - * This method performs the same work than the above - * {@link #transform(double[], int, double[], int, boolean) transform(…)} method, - * but on an arbitrary number of coordinate tuples and without computing derivative. - * - * @throws TransformException if a point cannot be transformed. - */ - @Override - public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws TransformException { - int srcInc = isSource3D ? 3 : 2; - int dstInc = isTarget3D ? 3 : 2; - int offFinal = 0; - double[] dstFinal = null; - if (srcPts == dstPts) { - switch (IterationStrategy.suggest(srcOff, srcInc, dstOff, dstInc, numPts)) { - case ASCENDING: { - break; - } - case DESCENDING: { - srcOff += (numPts-1) * srcInc; srcInc = -srcInc; - dstOff += (numPts-1) * dstInc; dstInc = -dstInc; - break; - } - default: { // BUFFER_SOURCE, but also a reasonable default for any case. - srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcInc); - srcOff = 0; - break; - } - case BUFFER_TARGET: { - dstFinal = dstPts; - offFinal = dstOff; - dstPts = new double[numPts * dstInc]; - dstOff = 0; - break; - } - } - } - final double[] offset = new double[3]; - while (--numPts >= 0) { - final double λ = srcPts[srcOff ]; - final double φ = srcPts[srcOff+1]; - grid.interpolateInCell(normalizedToGridX(λ), - normalizedToGridY(φ), offset); - transform(λ, φ, isSource3D ? srcPts[srcOff+2] : 0, - dstPts, dstOff, offset[0], offset[1], offset[2], null, false); - srcOff += srcInc; - dstOff += dstInc; - } - if (dstFinal != null) { - System.arraycopy(dstPts, 0, dstFinal, offFinal, dstPts.length); - } - } - - /* - * NOTE: we do not bother to override the methods expecting a 'float' array because those methods should - * be rarely invoked. Since there is usually LinearTransforms before and after this transform, the - * conversion between float and double will be handled by those LinearTransforms. If nevertheless - * this MolodenskyTransform is at the beginning or the end of a transformation chain, the methods - * inherited from the subclass will work (but may be slightly slower). - */ - - /** - * Returns the inverse of this interpolated Molodensky transform. - * The source ellipsoid of the returned transform will be the target ellipsoid of this transform, and conversely. - * - * @return a transform from the target ellipsoid to the source ellipsoid of this transform. - */ - @Override - public MathTransform inverse() { - return inverse; - } - - - - - - /** - * The inverse of the enclosing {@link InterpolatedMolodenskyTransform}. - * This transform applies an algorithm similar to the one documented in the enclosing class, - * with the following differences: - * - * <ol> - * <li>First, target coordinates are estimated using the ({@link #tX}, {@link #tY}, {@link #tZ}) translation.</li> - * <li>A new ({@code ΔX}, {@code ΔY}, {@code ΔZ}) translation is interpolated at the geographic coordinates found - * in above step, and target coordinates are recomputed again using that new translation.</li> - * </ol> - * - * @author Martin Desruisseaux (Geomatys) - */ - static class Inverse extends InterpolatedMolodenskyTransform { - /** - * Serial number for inter-operability with different versions. - */ - private static final long serialVersionUID = -3520896803296425651L; - - /** - * Constructs the inverse of an interpolated Molodensky transform. - * - * @param inverse the transform for which to create the inverse. - * @param source the source ellipsoid of the given {@code inverse} transform. - * @param target the target ellipsoid of the given {@code inverse} transform. - */ - Inverse(final InterpolatedMolodenskyTransform inverse, final Ellipsoid source, final Ellipsoid target) { - super(inverse, source, target); - } - - /** - * Transforms the (λ,φ) or (λ,φ,<var>h</var>) coordinates between two geographic CRS, - * and optionally returns the derivative at that location. - * - * @return {@inheritDoc} - * @throws TransformException if the point cannot be transformed or - * if a problem occurred while calculating the derivative. - */ - @Override - public Matrix transform(final double[] srcPts, final int srcOff, - final double[] dstPts, final int dstOff, - final boolean derivate) throws TransformException - { - return transform(srcPts[srcOff], srcPts[srcOff+1], isSource3D ? srcPts[srcOff+2] : 0, - dstPts, dstOff, tX, tY, tZ, new double[3], derivate); - } - - /** - * Transforms the (λ,φ) or (λ,φ,<var>h</var>) coordinates between two geographic CRS. - * This method performs the same work than the above - * {@link #transform(double[], int, double[], int, boolean) transform(…)} method, - * but on an arbitrary number of coordinate tuples and without computing derivative. - * - * @throws TransformException if a point cannot be transformed. - */ - @Override - public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws TransformException { - int srcInc = isSource3D ? 3 : 2; - int dstInc = isTarget3D ? 3 : 2; - int offFinal = 0; - double[] dstFinal = null; - if (srcPts == dstPts) { - switch (IterationStrategy.suggest(srcOff, srcInc, dstOff, dstInc, numPts)) { - case ASCENDING: { - break; - } - case DESCENDING: { - srcOff += (numPts-1) * srcInc; srcInc = -srcInc; - dstOff += (numPts-1) * dstInc; dstInc = -dstInc; - break; - } - default: { // BUFFER_SOURCE, but also a reasonable default for any case. - srcPts = Arrays.copyOfRange(srcPts, srcOff, srcOff + numPts*srcInc); - srcOff = 0; - break; - } - case BUFFER_TARGET: { - dstFinal = dstPts; - offFinal = dstOff; - dstPts = new double[numPts * dstInc]; - dstOff = 0; - break; - } - } - } - final double[] offset = new double[3]; - while (--numPts >= 0) { - transform(srcPts[srcOff], srcPts[srcOff+1], isSource3D ? srcPts[srcOff+2] : 0, - dstPts, dstOff, tX, tY, tZ, offset, false); - srcOff += srcInc; - dstOff += dstInc; - } - if (dstFinal != null) { - System.arraycopy(dstPts, 0, dstFinal, offFinal, dstPts.length); - } - } - } - - /** - * Returns a description of the internal parameters of this {@code InterpolatedMolodenskyTransform} transform. - * The returned group contains parameters for the source ellipsoid semi-axis lengths and the differences between - * source and target ellipsoid parameters. - * - * <h4>Usage note</h4> - * This method is mostly for {@linkplain org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes} - * since the isolation of non-linear parameters in this class is highly implementation dependent. - * Most GIS applications will instead be interested in the {@linkplain #getContextualParameters() - * contextual parameters}. - * - * @return a description of the internal parameters. - */ - @Debug - @Override - public ParameterDescriptorGroup getParameterDescriptors() { - final ParameterDescriptor<?>[] param = new ParameterDescriptor<?>[] { - Molodensky.DIMENSION, - Molodensky.SRC_SEMI_MAJOR, - Molodensky.SRC_SEMI_MINOR, - Molodensky.AXIS_LENGTH_DIFFERENCE, - Molodensky.FLATTENING_DIFFERENCE, - FranceGeocentricInterpolation.FILE - }; - return new ParameterBuilder().setRequired(true) - .setCodeSpace(Citations.SIS, Constants.SIS) - .addName(context.getDescriptor().getName().getCode() + " (radians domain)").createGroup(param); - } -} diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform2D.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform2D.java deleted file mode 100644 index 8bd3785d52..0000000000 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransform2D.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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.transform; - -import java.awt.Shape; -import java.awt.geom.Point2D; -import javax.measure.quantity.Angle; -import javax.measure.quantity.Length; -import org.opengis.referencing.datum.Ellipsoid; -import org.opengis.referencing.operation.Matrix; -import org.opengis.referencing.operation.MathTransform2D; -import org.opengis.referencing.operation.TransformException; -import org.apache.sis.referencing.datum.DatumShiftGrid; - - -/** - * An interpolated Molodensky transform for two-dimensional input and output coordinates. - * - * @author Martin Desruisseaux (Geomatys) - * - * @see <a href="https://issues.apache.org/jira/browse/SIS-500">Deprecate (for removal) InterpolatedMolodenskyTransform</a> - */ -@SuppressWarnings("removal") -@Deprecated(since="1.4", forRemoval=true) -final class InterpolatedMolodenskyTransform2D extends InterpolatedMolodenskyTransform implements MathTransform2D { - /** - * Serial number for compatibility with different versions. - */ - private static final long serialVersionUID = 3050077982181110135L; - - /** - * Constructs a 2D transform. - */ - InterpolatedMolodenskyTransform2D(final Ellipsoid source, final Ellipsoid target, final DatumShiftGrid<Angle,Length> grid) { - super(source, false, target, false, grid); - } - - /** - * Computes the derivative at the given position. - */ - @Override - public Matrix derivative(Point2D point) throws TransformException { - return AbstractMathTransform2D.derivative(this, point); - } - - /** - * Transforms a single point. - */ - @Override - public Point2D transform(Point2D ptSrc, Point2D ptDst) throws TransformException { - return AbstractMathTransform2D.transform(this, ptSrc, ptDst); - } - - /** - * Transforms the given shape. - */ - @Override - public Shape createTransformedShape(Shape shape) throws TransformException { - return AbstractMathTransform2D.createTransformedShape(this, shape, null, null, false); - } - - /** - * Returns the inverse transform of this transform. - */ - @Override - public MathTransform2D inverse() { - return (MathTransform2D) super.inverse(); - } - - /** - * The inverse of the enclosing {@link InterpolatedMolodenskyTransform2D}. - * - * @author Martin Desruisseaux (Geomatys) - */ - @SuppressWarnings("removal") - static final class Inverse extends InterpolatedMolodenskyTransform.Inverse implements MathTransform2D { - /** - * Serial number for inter-operability with different versions. - */ - private static final long serialVersionUID = 3175846640786132902L; - - /** - * Constructs the inverse of an interpolated Molodensky transform. - * - * @param inverse the transform for which to create the inverse. - * @param source the source ellipsoid of the given {@code inverse} transform. - * @param target the target ellipsoid of the given {@code inverse} transform. - */ - Inverse(final InterpolatedMolodenskyTransform inverse, final Ellipsoid source, final Ellipsoid target) { - super(inverse, source, target); - } - - /** - * Computes the derivative at the given position. - */ - @Override - public Matrix derivative(Point2D point) throws TransformException { - return AbstractMathTransform2D.derivative(this, point); - } - - /** - * Transforms a single point. - */ - @Override - public Point2D transform(Point2D ptSrc, Point2D ptDst) throws TransformException { - return AbstractMathTransform2D.transform(this, ptSrc, ptDst); - } - - /** - * Transforms the given shape. - */ - @Override - public Shape createTransformedShape(Shape shape) throws TransformException { - return AbstractMathTransform2D.createTransformedShape(this, shape, null, null, false); - } - - /** - * Returns the inverse transform of this transform. - */ - @Override - public MathTransform2D inverse() { - return (MathTransform2D) super.inverse(); - } - } -} diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java index b9ef61ccfe..63c0a9f3e9 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java @@ -37,14 +37,7 @@ import static java.lang.Math.*; /** - * Implementation of Molodensky formulas. This class is used by: - * - * <ul> - * <li>The "real" {@link MolodenskyTransform} (see that class for documentation about Molodensky transform).</li> - * <li>{@link InterpolatedMolodenskyTransform}, which conceptually works on geocentric coordinates but - * is implemented in Apache SIS using Molodensky (never abridged) formulas for performance reasons. - * However, this implementation choice should be hidden to users (except by mention in javadoc).</li> - * </ul> + * Implementation of Molodensky formulas. * * @author Martin Desruisseaux (Geomatys) */ @@ -295,13 +288,7 @@ abstract class MolodenskyFormula extends DatumShiftTransform { /** * Implementation of {@link #transform(double[], int, double[], int, boolean)} with possibility * to override some field values. In this method signature, parameters having the same name than - * fields have the same value, except in some special circumstances: - * - * <ul> - * <li>{@code tX}, {@code tY} and {@code tZ} parameters always have the values of {@link #tX}, {@link #tY} - * and {@link #tZ} fields when this method is invoked by {@link MolodenskyTransform}. But those values - * may be slightly different when this method is invoked by {@link InterpolatedMolodenskyTransform}.</li> - * </ul> + * fields have the same value. * * @param λ longitude (radians). * @param φ latitude (radians). @@ -311,12 +298,11 @@ abstract class MolodenskyFormula extends DatumShiftTransform { * @param tX the {@link #tX} field value (or a slightly different value during geocentric interpolation). * @param tY the {@link #tY} field value (or a slightly different value during geocentric interpolation). * @param tZ the {@link #tZ} field value (or a slightly different value during geocentric interpolation). - * @param offset an array of length 3 if this method should use the interpolation grid, or {@code null} otherwise. * @param derivate {@code true} for computing the derivative, or {@code false} if not needed. * @throws TransformException if a point cannot be transformed. */ final Matrix transform(final double λ, final double φ, final double h, final double[] dstPts, int dstOff, - double tX, double tY, double tZ, double[] offset, final boolean derivate) + double tX, double tY, double tZ, final boolean derivate) throws TransformException { /* @@ -350,26 +336,13 @@ abstract class MolodenskyFormula extends DatumShiftTransform { t = t*(0.5/νden + 0.5/ρden) // = Δf⋅[ν⋅(b/a) + ρ⋅(a/b)] (without the +h in ν and ρ) + Δa*eccentricitySquared/νden; // = Δa⋅[ℯ²⋅ν/a] } - double spcλ, cmsλ, cmsφ, scaleX, scaleY; // Intermediate terms to be reused by the derivative - double λt, φt; // The target geographic coordinates - do { - spcλ = tY*sinλ + tX*cosλ; // "spc" stands for "sin plus cos" - cmsλ = tY*cosλ - tX*sinλ; // "cms" stands for "cos minus sin" - cmsφ = (tZ + t*sinφ)*cosφ - spcλ*sinφ; - scaleX = ANGULAR_SCALE / (ν*cosφ); - scaleY = ANGULAR_SCALE / ρ; - λt = λ + (cmsλ * scaleX); - φt = φ + (cmsφ * scaleY); - if (offset == null) break; - /* - * Following is executed only in InterpolatedMolodenskyTransform case. - */ - grid.interpolateInCell(normalizedToGridX(λt), normalizedToGridY(φt), offset); - tX = -offset[0]; - tY = -offset[1]; - tZ = -offset[2]; - offset = null; - } while (true); + final double spcλ = tY*sinλ + tX*cosλ; // "spc" stands for "sin plus cos" + final double cmsλ = tY*cosλ - tX*sinλ; // "cms" stands for "cos minus sin" + final double cmsφ = (tZ + t*sinφ)*cosφ - spcλ*sinφ; + final double scaleX = ANGULAR_SCALE / (ν*cosφ); + final double scaleY = ANGULAR_SCALE / ρ; + final double λt = λ + (cmsλ * scaleX); // The target geographic coordinates + final double φt = φ + (cmsφ * scaleY); if (dstPts != null) { dstPts[dstOff++] = λt; dstPts[dstOff++] = φt; diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java index 4d5f1ac4d2..f8039f182b 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java @@ -272,7 +272,7 @@ public class MolodenskyTransform extends MolodenskyFormula { final boolean derivate) throws TransformException { return transform(srcPts[srcOff], srcPts[srcOff+1], isSource3D ? srcPts[srcOff+2] : 0, - dstPts, dstOff, tX, tY, tZ, null, derivate); + dstPts, dstOff, tX, tY, tZ, derivate); } /** diff --git a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/package-info.java b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/package-info.java index 23dc01ce24..a04776ec81 100644 --- a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/package-info.java +++ b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/package-info.java @@ -61,7 +61,7 @@ * * @author Martin Desruisseaux (IRD, Geomatys) * @author Adrian Custer (Geomatys) - * @version 1.4 + * @version 1.5 * @since 0.5 */ package org.apache.sis.referencing.operation.transform; diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/ProvidersTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/ProvidersTest.java index e143efddc0..f1365ba0e9 100644 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/ProvidersTest.java +++ b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/ProvidersTest.java @@ -125,7 +125,6 @@ public final class ProvidersTest extends TestCase { NTv1.class, NADCON.class, FranceGeocentricInterpolation.class, - MolodenskyInterpolation.class, Interpolation1D.class, Wraparound.class }; diff --git a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransformTest.java b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransformTest.java deleted file mode 100644 index 5558f43830..0000000000 --- a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/transform/InterpolatedMolodenskyTransformTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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.transform; - -import org.opengis.util.FactoryException; -import org.opengis.referencing.operation.TransformException; -import org.apache.sis.referencing.operation.provider.MolodenskyInterpolation; -import org.apache.sis.referencing.operation.provider.FranceGeocentricInterpolationTest; -import org.apache.sis.referencing.operation.provider.GeocentricTranslationTest; -import org.apache.sis.referencing.util.Formulas; - -// Test dependencies -import org.junit.Test; -import org.apache.sis.test.DependsOn; - - -/** - * Tests {@link InterpolatedMolodenskyTransform}. The accuracy of using the Molodensky approximation - * instead of the real geocentric translation is verified by the following tests: - * - * <ul> - * <li>{@link GeocentricTranslationTest#testFranceGeocentricInterpolationPoint()}</li> - * <li>{@link MolodenskyTransformTest#testFranceGeocentricInterpolationPoint()}</li> - * </ul> - * - * @author Martin Desruisseaux (Geomatys) - */ -@DependsOn({ - MolodenskyTransformTest.class, - GeocentricTranslationTest.class, - InterpolatedGeocentricTransformTest.class -}) -public final class InterpolatedMolodenskyTransformTest extends InterpolatedGeocentricTransformTest { - /** - * Creates a new test case. - */ - public InterpolatedMolodenskyTransformTest() { - } - - /** - * Creates an approximation of the <cite>"France geocentric interpolation"</cite> transform - * using the Molodensky transform. This method relax slightly the tolerance threshold since - * Molodensky transformations are approximation of translations in geocentric domain. - * - * @throws FactoryException if an error occurred while loading the grid. - */ - @Override - final void createGeodeticTransformation() throws FactoryException { - createGeodeticTransformation(new MolodenskyInterpolation()); - tolerance = Formulas.ANGULAR_TOLERANCE; // Relax tolerance threshold. - } - - /** - * Tests the Well Known Text (version 1) formatting. - * The result is what we show to users, but may quite different than what SIS has in memory. - * - * @throws FactoryException if an error occurred while creating a transform. - * @throws TransformException should never happen. - */ - @Test - @Override - public void testWKT() throws FactoryException, TransformException { - createGeodeticTransformation(); - transform = transform.inverse(); - assertWktEqualsRegex("(?m)\\Q" + - "PARAM_MT[“Molodensky interpolation”,\n" + - " PARAMETER[“dim”, 2],\n" + - " PARAMETER[“src_semi_major”, 6378137.0],\n" + - " PARAMETER[“src_semi_minor”, 6356752.314140356],\n" + - " PARAMETER[“tgt_semi_major”, 6378249.2],\n" + - " PARAMETER[“tgt_semi_minor”, 6356515.0],\n" + - " PARAMETER[“Geocentric translation file”, “\\E.*\\W\\Q" + - FranceGeocentricInterpolationTest.TEST_FILE + "”]]\\E"); - - transform = transform.inverse(); - assertWktEqualsRegex("(?m)\\Q" + - "PARAM_MT[“Molodensky inverse interpolation”,\n" + - " PARAMETER[“dim”, 2],\n" + - " PARAMETER[“src_semi_major”, 6378249.2],\n" + - " PARAMETER[“src_semi_minor”, 6356515.0],\n" + - " PARAMETER[“tgt_semi_major”, 6378137.0],\n" + - " PARAMETER[“tgt_semi_minor”, 6356752.314140356],\n" + - " PARAMETER[“Geocentric translation file”, “\\E.*\\W\\Q" + - FranceGeocentricInterpolationTest.TEST_FILE + "”]]\\E"); - } - - /** - * Tests the internal Well Known Text formatting. - * This WKT shows what SIS has in memory for debugging purpose. - * This is normally not what we show to users. - * - * @throws FactoryException if an error occurred while creating a transform. - * @throws TransformException should never happen. - */ - @Test - @Override - public void testInternalWKT() throws FactoryException, TransformException { - createGeodeticTransformation(); - assertInternalWktEqualsRegex("(?m)\\Q" + - "Concat_MT[\n" + - " Param_MT[“Affine parametric transformation”,\n" + - " Parameter[“A0”, 0.017453292519943295, Id[“EPSG”, 8623]],\n" + // Degrees to radians conversion - " Parameter[“B1”, 0.017453292519943295, Id[“EPSG”, 8640]]],\n" + - " Param_MT[“Molodensky inverse interpolation (radians domain)”,\n" + - " Parameter[“src_semi_major”, 6378249.2],\n" + - " Parameter[“src_semi_minor”, 6356515.0],\n" + - " Parameter[“Semi-major axis length difference”, -112.2, Id[“EPSG”, 8654]],\n" + - " Parameter[“Flattening difference”, -5.4738838833299144E-5, Id[“EPSG”, 8655]],\n" + - " ParameterFile[“Geocentric translation file”, “\\E.*\\W\\Q" + - FranceGeocentricInterpolationTest.TEST_FILE + "”, Id[“EPSG”, 8727]],\n" + - " Parameter[“dim”, 2]],\n" + - " Param_MT[“Affine parametric transformation”,\n" + - " Parameter[“A0”, 57.29577951308232, Id[“EPSG”, 8623]],\n" + // Radians to degrees conversion - " Parameter[“B1”, 57.29577951308232, Id[“EPSG”, 8640]]]]\\E"); - } -}