Return-Path: X-Original-To: apmail-sis-commits-archive@www.apache.org Delivered-To: apmail-sis-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 727D718E3B for ; Tue, 17 Nov 2015 23:04:32 +0000 (UTC) Received: (qmail 65717 invoked by uid 500); 17 Nov 2015 23:04:32 -0000 Delivered-To: apmail-sis-commits-archive@sis.apache.org Received: (qmail 65687 invoked by uid 500); 17 Nov 2015 23:04:32 -0000 Mailing-List: contact commits-help@sis.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sis-dev@sis.apache.org Delivered-To: mailing list commits@sis.apache.org Received: (qmail 65678 invoked by uid 99); 17 Nov 2015 23:04:32 -0000 Received: from Unknown (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 17 Nov 2015 23:04:32 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id DEB4D1A2CD8 for ; Tue, 17 Nov 2015 23:04:31 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.79 X-Spam-Level: * X-Spam-Status: No, score=1.79 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, T_RP_MATCHES_RCVD=-0.01] autolearn=disabled Received: from mx1-us-east.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id PC9vg-fO2kwn for ; Tue, 17 Nov 2015 23:04:27 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-us-east.apache.org (ASF Mail Server at mx1-us-east.apache.org) with ESMTP id D71A742B7B for ; Tue, 17 Nov 2015 23:04:26 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 3BDF8E03E8 for ; Tue, 17 Nov 2015 23:04:26 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 3951E3A028B for ; Tue, 17 Nov 2015 23:04:26 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r1714905 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/provider/ main/java/org/apache/sis/referencing/ main/java/org/apache/sis/referencing/operation/transform/ test/java/org/apache/sis/inte... Date: Tue, 17 Nov 2015 23:04:26 -0000 To: commits@sis.apache.org From: desruisseaux@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20151117230426.3951E3A028B@svn01-us-west.apache.org> Author: desruisseaux Date: Tue Nov 17 23:04:25 2015 New Revision: 1714905 URL: http://svn.apache.org/viewvc?rev=1714905&view=rev Log: Initial implementation of InterpolatedGeocentricTransform (forward transformation only; the inverse transformation will require an iterative approach as documented in NTG_88). Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java (with props) Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java?rev=1714905&r1=1714904&r2=1714905&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] Tue Nov 17 23:04:25 2015 @@ -16,6 +16,8 @@ */ package org.apache.sis.internal.referencing.provider; +import java.util.Map; +import java.util.HashMap; import java.util.Arrays; import java.util.Locale; import java.util.NoSuchElementException; @@ -29,6 +31,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import javax.xml.bind.annotation.XmlTransient; +import javax.measure.unit.SI; +import org.opengis.metadata.Identifier; import org.opengis.parameter.ParameterValueGroup; import org.opengis.parameter.ParameterDescriptor; import org.opengis.parameter.ParameterDescriptorGroup; @@ -45,7 +49,11 @@ import org.apache.sis.util.Workaround; import org.apache.sis.util.logging.Logging; import org.apache.sis.util.resources.Errors; import org.apache.sis.util.collection.WeakValueHashMap; +import org.apache.sis.referencing.CommonCRS; import org.apache.sis.referencing.datum.DatumShiftGrid; +import org.apache.sis.referencing.datum.DefaultEllipsoid; +import org.apache.sis.referencing.operation.transform.InterpolatedGeocentricTransform; +import org.apache.sis.metadata.iso.citation.Citations; /** @@ -77,7 +85,7 @@ public final class FranceGeocentricInter /** * The group of all parameters expected by this coordinate operation. */ - private static final ParameterDescriptorGroup PARAMETERS; + public static final ParameterDescriptorGroup PARAMETERS; static { final ParameterBuilder builder = builder(); FILE = builder @@ -153,7 +161,19 @@ public final class FranceGeocentricInter } grids.put(file, grid); } - return null; // TODO + /* + * Create the transform from RGF93 to NTF (which is the direction that use the interpolation grid + * directly without iteration), then invert it. We do not cache the ellipsoid because it will not + * be kept after construction. + */ + final Map properties = new HashMap<>(4); + properties.put(DefaultEllipsoid.NAME_KEY, "Clarke 1880 (IGN)"); + properties.put(Identifier.CODE_KEY, "7011"); + properties.put(Identifier.AUTHORITY_KEY, Citations.EPSG); + return InterpolatedGeocentricTransform.createGeodeticTransformation(factory, + CommonCRS.ETRS89.ellipsoid(), false, // GRS 1980 ellipsoid + DefaultEllipsoid.createEllipsoid(properties, 6378249.2, 6356515, SI.METRE), false, + -168, -60, 320, grid); // TODO: invert } /** @@ -273,10 +293,11 @@ public final class FranceGeocentricInter } /** - * Loads the given file. Data columns are + * Loads the given file with the sign of all data reversed. Data columns are * * (unknown), longitude, latitude, tX, tY, tZ, accuracy code, data sheet (ignored) * + * where the longitude and latitude values are in RGF93 system. * Example: * * {@preformat text @@ -285,6 +306,10 @@ public final class FranceGeocentricInter * 00002 -5.500000000 41.200000000 -165.312 -66.796 316.200 99 -0157 * } * + * Translation values in the IGN file are from NTF to RGF93, but Apache SIS implementation needs + * the opposite direction (from RGF93 to NTF). The reason is that SIS expect the source datum to + * be the datum in which longitude and latitude values are expressed. + * * @param in Reader of the RGF93 datum shift file. * @param file Path to the file being read, used only for error reporting. * @throws IOException if an I/O error occurred. @@ -300,7 +325,7 @@ public final class FranceGeocentricInter String line; while ((line = in.readLine()) != null) { final StringTokenizer t = new StringTokenizer(line.trim()); - final int n = Integer.parseInt (t.nextToken()); // Ignored + t.nextToken(); // Ignored final double x = Double.parseDouble(t.nextToken()); // Longitude final double y = Double.parseDouble(t.nextToken()); // Latitude final int i = Math.toIntExact(Math.round((x - x0) * scaleX)); // Column index @@ -315,9 +340,9 @@ public final class FranceGeocentricInter if (!Double.isNaN(tX[p]) || !Double.isNaN(tY[p]) || !Double.isNaN(tZ[p])) { throw new FactoryException(Errors.format(Errors.Keys.ValueAlreadyDefined_1, x + ", " + y)); } - tX[p] = Float.parseFloat(t.nextToken()); - tY[p] = Float.parseFloat(t.nextToken()); - tZ[p] = Float.parseFloat(t.nextToken()); + tX[p] = -Float.parseFloat(t.nextToken()); // See javadoc for the reason why we reverse the sign. + tY[p] = -Float.parseFloat(t.nextToken()); + tZ[p] = -Float.parseFloat(t.nextToken()); } } Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java?rev=1714905&r1=1714904&r2=1714905&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] Tue Nov 17 23:04:25 2015 @@ -118,6 +118,7 @@ import static org.apache.sis.internal.ut * @version 0.5 * @module */ +@SuppressWarnings("DoubleCheckedLocking") public enum CommonCRS { /** * World Geodetic System 1984. Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java?rev=1714905&view=auto ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java (added) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java [UTF-8] Tue Nov 17 23:04:25 2015 @@ -0,0 +1,157 @@ +/* + * 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.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.internal.referencing.provider.FranceGeocentricInterpolation; +import org.apache.sis.referencing.datum.DatumShiftGrid; +import org.apache.sis.util.ArgumentChecks; + + +/** + * Transforms between two geographic CRS by performing geocentric translations interpolated from a grid file. + * This transform is used by "France geocentric interpolation" (ESPG:9655) datum shift. + * + *
Implementation note: + * while this transformation is conceptually defined as a translation in geocentric coordinates, the current + * Apache SIS implementation rather uses the Molodensy (non-abridged) approximation for performance reasons. + * Errors should be lower than the grid accuracy.
+ * + * @author Simon Reynard (Geomatys) + * @author Martin Desruisseaux (Geomatys) + * @since 0.7 + * @version 0.7 + * @module + */ +public class InterpolatedGeocentricTransform extends MolodenskyFormula { + /** + * Serial number for inter-operability with different versions. + */ + private static final long serialVersionUID = -5691721806681489940L; + + /** + * The grid of datum shifts from source datum to target datum. + */ + protected final DatumShiftGrid grid; + + /** + * Creates a transform from the specified parameters. + * This {@code InterpolatedGeocentricTransform} class expects ordinate values in the following order and units: + *
    + *
  1. longitudes in radians relative to the prime meridian (usually Greenwich),
  2. + *
  3. latitudes in radians,
  4. + *
  5. optionally heights above the ellipsoid, in same units than the source ellipsoid axes.
  6. + *
+ * + * For converting geographic coordinates in degrees, {@code InterpolatedGeocentricTransform} instances + * need to be concatenated with the following affine transforms: + * + *
    + *
  • Normalization before {@code InterpolatedGeocentricTransform}:
      + *
    • Conversion of (λ,φ) from degrees to radians.
    • + *
  • + *
  • Denormalization after {@code InterpolatedGeocentricTransform}:
      + *
    • Conversion of (λ,φ) from radians to degrees.
    • + *
  • + *
+ * + * After {@code InterpolatedGeocentricTransform} construction, + * the full conversion chain including the above affine transforms can be created by + * {@linkplain #getContextualParameters()}.{@linkplain ContextualParameters#completeTransform + * completeTransform}(factory, this)}. + * + * @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 tX Initial geocentric X translation in same units than the source ellipsoid axes. + * @param tY Initial geocentric Y translation in same units than the source ellipsoid axes. + * @param tZ Initial geocentric Z translation in same units than the source ellipsoid axes. + * @param grid The grid of datum shifts from source to target datum. + * + * @see #createGeodeticTransformation(MathTransformFactory, Ellipsoid, boolean, Ellipsoid, boolean, double, double, double, DatumShiftGrid) + */ + protected InterpolatedGeocentricTransform(final Ellipsoid source, final boolean isSource3D, + final Ellipsoid target, final boolean isTarget3D, + final double tX, final double tY, final double tZ, + final DatumShiftGrid grid) + { + super(source, isSource3D, target, isTarget3D, tX, tY, tZ, false, false, FranceGeocentricInterpolation.PARAMETERS); + ArgumentChecks.ensureNonNull("grid", grid); + this.grid = grid; + } + + /** + * Creates a transformation between two from geographic CRS. This factory method combines the + * {@code InterpolatedGeocentricTransform} instance with the steps needed for converting values between + * degrees to radians. The transform works with input and output coordinates in the following units: + * + *
    + *
  1. longitudes in degrees relative to the prime meridian (usually Greenwich),
  2. + *
  3. latitudes in degrees,
  4. + *
  5. optionally heights above the ellipsoid, in same units than the source ellipsoids axes.
  6. + *
+ * + * @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 tX Initial geocentric X translation in same units than the source ellipsoid axes. + * @param tY Initial geocentric Y translation in same units than the source ellipsoid axes. + * @param tZ Initial geocentric Z translation in same units than the source ellipsoid axes. + * @param grid The grid of datum shifts from source to target datum. + * @return The transformation between geographic coordinates. + * @throws FactoryException if an error occurred while creating a transform. + */ + public static MathTransform createGeodeticTransformation(final MathTransformFactory factory, + final Ellipsoid source, final boolean isSource3D, + final Ellipsoid target, final boolean isTarget3D, + final double tX, final double tY, final double tZ, + final DatumShiftGrid grid) throws FactoryException + { + final InterpolatedGeocentricTransform tr; + tr = new InterpolatedGeocentricTransform(source, isSource3D, target, isTarget3D, tX, tY, tZ, grid); + return tr.context.completeTransform(factory, tr); + } + + /** + * Transforms the (λ,φ) or (λ,φ,h) coordinates between two geographic CRS, + * and optionally returns the derivative at that location. + * + * @return {@inheritDoc} + * @throws TransformException if the point can not 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[] offset = new double[3]; + final double λ = srcPts[srcOff]; + final double φ = srcPts[srcOff+1]; + grid.offsetAt(Math.toDegrees(λ), Math.toDegrees(φ), offset); // TODO: avoid conversion to degrees. + return transform(λ, φ, isSource3D ? srcPts[srcOff+2] : 0, isSource3D, + dstPts, dstOff, isTarget3D, offset[0], offset[1], offset[2], derivate); + } +} Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java ------------------------------------------------------------------------------ svn:mime-type = text/plain;charset=UTF-8 Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java?rev=1714905&r1=1714904&r2=1714905&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyFormula.java [UTF-8] Tue Nov 17 23:04:25 2015 @@ -164,7 +164,7 @@ abstract class MolodenskyFormula extends MolodenskyFormula(final Ellipsoid source, final boolean isSource3D, final Ellipsoid target, final boolean isTarget3D, final double tX, final double tY, final double tZ, - final boolean isAbridged, + final boolean isAbridged, final boolean setAxisLengths, final ParameterDescriptorGroup descriptor) { ArgumentChecks.ensureNonNull("source", source); @@ -192,10 +192,12 @@ abstract class MolodenskyFormula extends final UnitConverter c = target.getAxisUnit().getConverterTo(unit); context = new ContextualParameters(descriptor, isSource3D ? 4 : 3, isTarget3D ? 4 : 3); setContextualParameters(context, unit, Δf); - context.getOrCreate(Molodensky.SRC_SEMI_MAJOR).setValue(semiMajor, unit); - context.getOrCreate(Molodensky.SRC_SEMI_MINOR).setValue(semiMinor, unit); - context.getOrCreate(Molodensky.TGT_SEMI_MAJOR).setValue(c.convert(target.getSemiMajorAxis()), unit); - context.getOrCreate(Molodensky.TGT_SEMI_MINOR).setValue(c.convert(target.getSemiMinorAxis()), unit); + if (setAxisLengths) { + context.getOrCreate(Molodensky.SRC_SEMI_MAJOR).setValue(semiMajor, unit); + context.getOrCreate(Molodensky.SRC_SEMI_MINOR).setValue(semiMinor, unit); + context.getOrCreate(Molodensky.TGT_SEMI_MAJOR).setValue(c.convert(target.getSemiMajorAxis()), unit); + context.getOrCreate(Molodensky.TGT_SEMI_MINOR).setValue(c.convert(target.getSemiMinorAxis()), unit); + } /* * Prepare two affine transforms to be executed before and after the MolodenskyTransform: * @@ -282,19 +284,34 @@ abstract class MolodenskyFormula extends /** * Implementation of {@link #transform(double[], int, double[], int, boolean)} with possibility - * to override whether the source and target coordinates are two- or three-dimensional. + * to override some field values. In this method signature, parameters having the same name than + * fields have the same value, except if some special circumstances: * - * @param λ Longitude (radians). - * @param φ Latitude (radians). - * @param h Height above the ellipsoid in unit of semi-major axis. - * @param dstPts The array into which the transformed coordinate is returned. - * May be {@code null} if only the derivative matrix is desired. - * @param dstOff The offset to the location of the transformed point that is stored in the destination array. - * @param derivate {@code true} for computing the derivative, or {@code false} if not needed. + *
    + *
  • {@code isSource3D} and {@code isTarget3D} parameters have the same values than {@link #isSource3D} and + * {@link #isTarget3D} fields respectively, except when the user explicitly requested the derivative of a + * point with a different number of dimensions (this should be very rare).
  • + *
  • {@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 InterpolatedGeocentricTransform}.
  • + *
+ * + * @param λ Longitude (radians). + * @param φ Latitude (radians). + * @param h Height above the ellipsoid in unit of semi-major axis. + * @param isSource3D The {@link #isSource3D} field value (except when computing derivative). + * @param dstPts The array into which the transformed coordinate is returned, or {@code null}. + * @param dstOff The offset to the location of the transformed point that is stored in the destination array. + * @param isTarget3D The {@link #isTarget3D} field value (except when computing derivative). + * @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 derivate {@code true} for computing the derivative, or {@code false} if not needed. * @throws TransformException if a point can not be transformed. */ final Matrix transform(final double λ, final double φ, final double h, final boolean isSource3D, final double[] dstPts, int dstOff, final boolean isTarget3D, + double tX, double tY, double tZ, final boolean derivate) throws TransformException { /* Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java?rev=1714905&r1=1714904&r2=1714905&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MolodenskyTransform.java [UTF-8] Tue Nov 17 23:04:25 2015 @@ -100,11 +100,11 @@ public class MolodenskyTransform extends /** * Creates a Molodensky transform from the specified parameters. - * This {@code MolodenskyTransform} class expects ordinate values if the following order and units: + * This {@code MolodenskyTransform} class expects ordinate values in the following order and units: *
    *
  1. longitudes in radians relative to the prime meridian (usually Greenwich),
  2. *
  3. latitudes in radians,
  4. - *
  5. optionally heights above the ellipsoid, in same units than the source ellipsoids axes.
  6. + *
  7. optionally heights above the ellipsoid, in same units than the source ellipsoid axes.
  8. *
* * For converting geographic coordinates in degrees, {@code MolodenskyTransform} instances @@ -140,7 +140,7 @@ public class MolodenskyTransform extends final double tX, final double tY, final double tZ, final boolean isAbridged) { - super(source, isSource3D, target, isTarget3D, tX, tY, tZ, isAbridged, + super(source, isSource3D, target, isTarget3D, tX, tY, tZ, isAbridged, true, isAbridged ? AbridgedMolodensky.PARAMETERS : Molodensky.PARAMETERS); } @@ -241,7 +241,7 @@ public class MolodenskyTransform extends case 3: withHeight = true; h = point.getOrdinate(2); break; case 2: withHeight = false; h = 0; break; } - return transform(point.getOrdinate(0), point.getOrdinate(1), h, withHeight, null, 0, withHeight, true); + return transform(point.getOrdinate(0), point.getOrdinate(1), h, withHeight, null, 0, withHeight, tX, tY, tZ, true); } /** @@ -258,7 +258,7 @@ public class MolodenskyTransform extends final boolean derivate) throws TransformException { return transform(srcPts[srcOff], srcPts[srcOff+1], isSource3D ? srcPts[srcOff+2] : 0, - isSource3D, dstPts, dstOff, isTarget3D, derivate); + isSource3D, dstPts, dstOff, isTarget3D, tX, tY, tZ, derivate); } /** Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java?rev=1714905&r1=1714904&r2=1714905&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java [UTF-8] Tue Nov 17 23:04:25 2015 @@ -26,6 +26,7 @@ import org.opengis.util.FactoryException import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.operation.MathTransformFactory; import org.opengis.referencing.operation.TransformException; +import org.apache.sis.internal.referencing.Formulas; import org.apache.sis.internal.system.DefaultFactories; import org.apache.sis.referencing.operation.transform.MathTransformTestCase; import org.apache.sis.test.DependsOnMethod; @@ -60,12 +61,12 @@ public final strictfp class FranceGeocen 2 + (25 + 29.89599/60)/60, // 2°25′29.89599″ in RGF93 48 + (50 + 40.00502/60)/60 // 48°50′40.00502″ }; - case 2: return new double[] { - -168.253, // ΔX: Toward prime meridian - -58.609, // ΔY: Toward 90° east - 320.170 // ΔZ: Toward north pole + case 2: return new double[] { // Direction reversed compared to NTG_88 document. + 168.253, // ΔX: Toward prime meridian + 58.609, // ΔY: Toward 90° east + -320.170 // ΔZ: Toward north pole }; - case 4: return new double[] { + case 3: return new double[] { 2 + (25 + 32.4187/60)/60, // 2°25′32.4187″ in NTF 48 + (50 + 40.2441/60)/60 // 48°50′40.2441″ }; @@ -107,20 +108,24 @@ public final strictfp class FranceGeocen } /** - * Tests transformation of sample point. + * Tests transformation of sample point from RGF93 to NTF. + * We call this transformation "forward" because it uses the grid values directly, + * without doing first an approximation followed by an iteration. * * @throws FactoryException if an error occurred while loading the grid. * @throws TransformException if an error occurred while transforming the coordinate. */ -// @Test + @Test @DependsOnMethod("testGrid") - public void testTransform() throws FactoryException, TransformException { + public void testForwardTransform() throws FactoryException, TransformException { final URL file = FranceGeocentricInterpolationTest.class.getResource("GR3DF97A.txt"); assertNotNull("Test file \"GR3DF97A.txt\" not found.", file); final FranceGeocentricInterpolation provider = new FranceGeocentricInterpolation(); final ParameterValueGroup values = provider.getParameters().createValue(); values.parameter("Geocentric translations file").setValue(file); // Automatic conversion from URL to Path. transform = provider.createMathTransform(DefaultFactories.forBuildin(MathTransformFactory.class), values); - // TODO + tolerance = Formulas.ANGULAR_TOLERANCE; + isInverseTransformSupported = false; + verifyTransform(samplePoint(1), samplePoint(3)); } }