You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2015/11/20 16:45:54 UTC

svn commit: r1715380 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/internal/referencing/provider/ main/java/org/apache/sis/referencing/operation/transform/ test/java/org/apache/sis/internal/referencing/provider/ test/java/o...

Author: desruisseaux
Date: Fri Nov 20 15:45:54 2015
New Revision: 1715380

URL: http://svn.apache.org/viewvc?rev=1715380&view=rev
Log:
Apply the France-specific TX, TY, TZ geocentric translation terms only if we detect that the datum grid shift file is "GR3DF97A".

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridCompressed.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java
    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/operation/transform/InterpolatedGeocentricTransform.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolationTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/resources/org/apache/sis/internal/referencing/provider/GR3DF97A.txt

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridCompressed.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridCompressed.java?rev=1715380&r1=1715379&r2=1715380&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridCompressed.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridCompressed.java [UTF-8] Fri Nov 20 15:45:54 2015
@@ -80,10 +80,13 @@ final class DatumShiftGridCompressed ext
             averages = new double[data.length];
         }
         for (int dim = 0; dim < data.length; dim++) {
+            final double average;
             if (computeAverages) {
-                averages[dim] = grid.getAverageOffset(dim);
+                average = Math.rint(grid.getAverageOffset(dim) / scale);
+                averages[dim] = average * scale;
+            } else {
+                average = averages[dim] / scale;
             }
-            final double average = averages[dim] / scale;
             final float[] offsets = grid.offsets[dim];
             final short[] compressed = new short[offsets.length];
             for (int i=0; i<offsets.length; i++) {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java?rev=1715380&r1=1715379&r2=1715380&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java [UTF-8] Fri Nov 20 15:45:54 2015
@@ -17,12 +17,14 @@
 package org.apache.sis.internal.referencing.provider;
 
 import java.util.Arrays;
-import java.nio.file.Path;
 import java.lang.reflect.Array;
 import org.apache.sis.math.DecimalFunctions;
 import org.apache.sis.util.collection.Cache;
 import org.apache.sis.referencing.datum.DatumShiftGrid;
 
+// Branch-specific imports
+import java.nio.file.Path;
+
 
 /**
  * A datum shift grid loaded from a file.
@@ -66,7 +68,7 @@ public abstract class DatumShiftGridFile
      * (except for {@link #equals(Object)} and {@link #hashCode()}), but can be used by math
      * transform for setting the parameter values.
      */
-    private final String file;
+    public final Path file;
 
     /**
      * Creates a new datum shift grid for the given grid geometry.
@@ -85,7 +87,7 @@ public abstract class DatumShiftGridFile
                        final Path file)
     {
         super(x0, y0, Δx, Δy, nx, ny);
-        this.file = file.getFileName().toString();
+        this.file = file;
     }
 
     /**
@@ -135,7 +137,7 @@ public abstract class DatumShiftGridFile
      */
     @Override
     public String toString() {
-        return file;
+        return file.getFileName().toString();
     }
 
 

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=1715380&r1=1715379&r2=1715380&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] Fri Nov 20 15:45:54 2015
@@ -25,9 +25,6 @@ import java.util.logging.LogRecord;
 import java.io.BufferedReader;
 import java.io.EOFException;
 import java.io.IOException;
-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.parameter.ParameterValueGroup;
@@ -54,6 +51,11 @@ import org.apache.sis.referencing.operat
 
 import static java.lang.Float.parseFloat;
 
+// Branch-specific imports
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.Files;
+
 
 /**
  * The provider for <cite>"France geocentric interpolation"</cite> (ESPG:9655).
@@ -63,6 +65,19 @@ import static java.lang.Float.parseFloat
  * <cite>"Grille de paramètres de transformation de coordonnées"</cite>
  * at <a href="http://www.ign.fr">http://www.ign.fr</a>.</p>
  *
+ * In principle, this operation method is designed specifically for the French mapping
+ * (e.g. EPSG:1053 <cite>"NTF to RGF93 (1)"</cite>) using the following hard-coded parameters:
+ * <ul>
+ *   <li>Source ellipsoid: Clarke 1880</li>
+ *   <li>Target ellipsoid: RGF93</li>
+ *   <li>Initial X-axis translation: {@value #TX} (sign reversed)</li>
+ *   <li>Initial Y-axis translation: {@value #TY} (sign reversed)</li>
+ *   <li>Initial Z-axis translation: {@value #TZ} (sign reversed)</li>
+ * </ul>
+ *
+ * However the Apache SIS implementation is designed in such a way that this operation method
+ * could be used for other areas.
+ *
  * @author  Simon Reynard (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
@@ -77,11 +92,38 @@ public final class FranceGeocentricInter
     private static final long serialVersionUID = -4707304160205218546L;
 
     /**
+     * Geocentric translation parameters to use as a first guess before to use the grid in France.
+     * The values of those parameters are specified by the NTG_88 document and apply only for France.
+     * If the geocentric interpolation is used for other area, other parameter values will be needed.
+     *
+     * <p>The values used by SIS are from source (RGF93) to target (NTF). This is the opposite of the
+     * direction defined in NTG_88. Consequently the signs need to be the opposite of NTG_88 values.</p>
+     */
+    public static final double TX = 168, TY = 60, TZ = -320;
+
+    /**
+     * Precision of offset values in the grid file. The "GR3DF97A.txt" file uses a precision of 0.001.
+     * But we define here one more digit in case a user gives a more accurate grid.
+     *
+     * Note that value of {@code ulp((float) max(|TX|, |TY|, |TZ|))} is about 3E-5. Consequently the
+     * value of {@code PRECISION} should not be lower than 1E-4 (assuming that we want a power of 10).
+     */
+    static final double PRECISION = 0.0001;
+
+    /**
      * The keyword expected at the beginning of every lines in the header.
      */
     private static final String HEADER = "GR3D";
 
     /**
+     * Name of the default grid file, as mentioned in the NTG_88 document.
+     * We use the 5 first characters ({@code "gr3df"}) as a sentinel value for French grid file.
+     *
+     * @see #isRecognized(Path)
+     */
+    private static final String DEFAULT = "gr3df97a.txt";
+
+    /**
      * The operation parameter descriptor for the <cite>Geocentric translations file</cite> parameter value.
      */
     public static final ParameterDescriptor<Path> FILE;
@@ -97,7 +139,7 @@ public final class FranceGeocentricInter
         FILE = builder
                 .addIdentifier("8727")
                 .addName("Geocentric translations file")
-                .create(Path.class, Paths.get("gr3df97a.txt"));
+                .create(Path.class, Paths.get(DEFAULT));
         PARAMETERS = builder
                 .addIdentifier("9655")
                 .addName("France geocentric interpolation")
@@ -117,6 +159,19 @@ public final class FranceGeocentricInter
     }
 
     /**
+     * Returns {@code true} if the given path seems to be a grid published by the French mapping agency for France.
+     * In principle this <cite>"France geocentric interpolation"</cite> is designed specifically for use with the
+     * {@code "gr3df97a.txt"} grid, but in fact the Apache SIS implementation should be flexible enough for use
+     * with other area.
+     *
+     * @param file The grid file.
+     * @return {@code true} if the given file looks like a fie from the French mapping agency.
+     */
+    public static boolean isRecognized(final Path file) {
+        return file.getFileName().toString().regionMatches(true, 0, DEFAULT, 0, 5);
+    }
+
+    /**
      * Returns the base interface of the {@code CoordinateOperation} instances that use this method.
      *
      * @return Fixed to {@link Transformation}.
@@ -191,12 +246,8 @@ public final class FranceGeocentricInter
             case 3:  withHeights = true; break;
             default: throw new InvalidParameterValueException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "dim", dim), "dim", dim);
         }
-        /*
-         * Array contains average translation parameters from source (RGF93) to target (NTF).
-         * The numerical values are given by operation EPSG:1651, but SIS implementation
-         * uses the opposite signs (because we reverse the direction of the operation).
-         */
-        final DatumShiftGridFile grid = getOrLoad(pg.getValue(FILE), new double[] {168, 60, -320}, 0.001);
+        final Path file = pg.getValue(FILE);
+        final DatumShiftGridFile grid = getOrLoad(file, !isRecognized(file) ? null : new double[] {TX, TY, TZ}, PRECISION);
         return InterpolatedGeocentricTransform.createGeodeticTransformation(factory,
                 createEllipsoid(pg, Molodensky.TGT_SEMI_MAJOR,
                                     Molodensky.TGT_SEMI_MINOR, CommonCRS.ETRS89.ellipsoid()), withHeights, // GRS 1980 ellipsoid

Modified: 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=1715380&r1=1715379&r2=1715380&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransform.java [UTF-8] Fri Nov 20 15:45:54 2015
@@ -39,6 +39,9 @@ import org.apache.sis.util.resources.Err
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Debug;
 
+// Branch-specific imports
+import java.nio.file.Path;
+
 
 /**
  * Transforms between two geographic CRS by performing geocentric translations interpolated from a grid file.
@@ -205,7 +208,10 @@ public class InterpolatedGeocentricTrans
      */
     private static ParameterDescriptorGroup descriptor(final DatumShiftGrid grid) {
         if (grid instanceof DatumShiftGridFile) {
-            return FranceGeocentricInterpolation.PARAMETERS;        // Defined by EPSG.
+            final Path file = ((DatumShiftGridFile) grid).file;
+            if ((FranceGeocentricInterpolation.isRecognized(file))) {
+                return FranceGeocentricInterpolation.PARAMETERS;        // Defined by EPSG.
+            }
         }
         synchronized (InterpolatedGeocentricTransform.class) {
             if (DESCRIPTOR == null) {

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=1715380&r1=1715379&r2=1715380&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] Fri Nov 20 15:45:54 2015
@@ -104,6 +104,9 @@ public final strictfp class FranceGeocen
         try (final BufferedReader in = Files.newBufferedReader(file)) {
             grid = FranceGeocentricInterpolation.load(in, file);
         }
+        assertEquals("getAverageOffset",  168.2587, grid.getAverageOffset(0), 1E-4);
+        assertEquals("getAverageOffset",   58.7163, grid.getAverageOffset(1), 1E-4);
+        assertEquals("getAverageOffset", -320.1801, grid.getAverageOffset(2), 1E-4);
         assertEquals("getCellValue",  168.196, grid.getCellValue(0, 2, 1), 0);
         assertEquals("getCellValue",   58.778, grid.getCellValue(1, 2, 1), 0);
         assertEquals("getCellValue", -320.127, grid.getCellValue(2, 2, 1), 0);
@@ -122,8 +125,15 @@ public final strictfp class FranceGeocen
      */
     @TestStep
     private static DatumShiftGridFile testGridAsShorts(DatumShiftGridFile grid) {
-        grid = DatumShiftGridCompressed.compress((DatumShiftGridFile.Float) grid, new double[] {168, 60, -320}, 0.001);
+        grid = DatumShiftGridCompressed.compress((DatumShiftGridFile.Float) grid, new double[] {
+                FranceGeocentricInterpolation.TX,           //  168 metres
+                FranceGeocentricInterpolation.TY,           //   60 metres
+                FranceGeocentricInterpolation.TZ},          // -320 metres
+                FranceGeocentricInterpolation.PRECISION);
         assertInstanceOf("Failed to compress 'float' values into 'short' values.", DatumShiftGridCompressed.class, grid);
+        assertEquals("getAverageOffset",  168, grid.getAverageOffset(0), 0);
+        assertEquals("getAverageOffset",   60, grid.getAverageOffset(1), 0);
+        assertEquals("getAverageOffset", -320, grid.getAverageOffset(2), 0);
         assertEquals("getCellValue",  168.196, ((DatumShiftGridCompressed) grid).getCellValue(0, 2, 1), 0);
         assertEquals("getCellValue",   58.778, ((DatumShiftGridCompressed) grid).getCellValue(1, 2, 1), 0);
         assertEquals("getCellValue", -320.127, ((DatumShiftGridCompressed) grid).getCellValue(2, 2, 1), 0);
@@ -163,9 +173,17 @@ public final strictfp class FranceGeocen
         final URL file = FranceGeocentricInterpolationTest.class.getResource("GR3DF97A.txt");
         assertNotNull("Test file \"GR3DF97A.txt\" not found.", file);
         final DatumShiftGridFile grid = FranceGeocentricInterpolation.getOrLoad(
-                Paths.get(file.toURI()), new double[] {168, 60, -320}, 0.001);
+                Paths.get(file.toURI()), new double[] {
+                        FranceGeocentricInterpolation.TX,
+                        FranceGeocentricInterpolation.TY,
+                        FranceGeocentricInterpolation.TZ},
+                        FranceGeocentricInterpolation.PRECISION);
         verifyGrid(grid);
         assertSame("Expected a cached value.", grid, FranceGeocentricInterpolation.getOrLoad(
-                Paths.get(file.toURI()), new double[] {168, 60, -320}, 0.001));
+                Paths.get(file.toURI()), new double[] {
+                        FranceGeocentricInterpolation.TX,
+                        FranceGeocentricInterpolation.TY,
+                        FranceGeocentricInterpolation.TZ},
+                        FranceGeocentricInterpolation.PRECISION));
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java?rev=1715380&r1=1715379&r2=1715380&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/InterpolatedGeocentricTransformTest.java [UTF-8] Fri Nov 20 15:45:54 2015
@@ -48,10 +48,11 @@ public final strictfp class Interpolated
     /**
      * Creates the <cite>"France geocentric interpolation"</cite> transform.
      *
-     * @param  file The grid to load.
      * @throws FactoryException if an error occurred while loading the grid.
      */
-    private void create(final URL file) throws FactoryException {
+    private void create() throws FactoryException {
+        final URL file = FranceGeocentricInterpolationTest.class.getResource("GR3DF97A.txt");
+        assertNotNull("Test file \"GR3DF97A.txt\" not found.", file);
         final Ellipsoid source = HardCodedDatum.NTF.getEllipsoid();     // Clarke 1880 (IGN)
         final Ellipsoid target = CommonCRS.ETRS89.ellipsoid();          // GRS 1980 ellipsoid
         final FranceGeocentricInterpolation provider = new FranceGeocentricInterpolation();
@@ -74,11 +75,8 @@ public final strictfp class Interpolated
      * @throws TransformException if an error occurred while transforming the coordinate.
      */
     @Test
-    @DependsOnMethod("testGetOrLoad")
     public void testForwardTransform() throws FactoryException, TransformException {
-        final URL file = FranceGeocentricInterpolationTest.class.getResource("GR3DF97A.txt");
-        assertNotNull("Test file \"GR3DF97A.txt\" not found.", file);
-        create(file);
+        create();
         isInverseTransformSupported = false;
         verifyTransform(FranceGeocentricInterpolationTest.samplePoint(1),
                         FranceGeocentricInterpolationTest.samplePoint(3));
@@ -88,4 +86,17 @@ public final strictfp class Interpolated
          * Actual:    2.4256718922236735   48.84451219111167
          */
     }
+
+    /**
+     * Tests transformation of sample point from NTF to RGF93.
+     *
+     * @throws FactoryException if an error occurred while loading the grid.
+     * @throws TransformException if an error occurred while transforming the coordinate.
+     */
+    @Test
+    @DependsOnMethod("testForwardTransform")
+    public void testInverseTransform() throws FactoryException, TransformException {
+        create();
+        // TODO
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/resources/org/apache/sis/internal/referencing/provider/GR3DF97A.txt
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/resources/org/apache/sis/internal/referencing/provider/GR3DF97A.txt?rev=1715380&r1=1715379&r2=1715380&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/resources/org/apache/sis/internal/referencing/provider/GR3DF97A.txt [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/resources/org/apache/sis/internal/referencing/provider/GR3DF97A.txt [UTF-8] Fri Nov 20 15:45:54 2015
@@ -3,6 +3,13 @@
 # The full file is available at http://www.ign.fr and is documented in NTG_88.pdf:
 # "Grille de paramètres de transformation de coordonnées" version 1.0, April 1997.
 #
+# Direct link to data: http://geodesie.ign.fr/contenu/fichiers/documentation/rgf93/
+# (fetched on November 2015). Full file size is 1.3 Mb. License is similar to the
+# EPSG's one (can be freely redistributed provided that commerciality is based on
+# value added by the provider). The amount of data that we reproduce here is less
+# than 0.14% of the full grid and is not for production use - those values may be
+# modified with artifical values for testing purpose in any future SIS version.
+#
 # We reproduce here only a few lines around 2.424971108°E 48.844445839°N,
 # which is the sample point used in the test documented in NTG_88.pdf.
 #