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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 1a95478b37 Move `DatumShiftGrid` implementations to a dedicated 
internal package. This is in preparation for more gridded data such as 
TestBed-19 or GGXF.
1a95478b37 is described below

commit 1a95478b3792d85b460042810db6cc1f98d22dc0
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu Dec 28 13:44:21 2023 +0100

    Move `DatumShiftGrid` implementations to a dedicated internal package.
    This is in preparation for more gridded data such as TestBed-19 or GGXF.
---
 .../CompressedGrid.java}                           |  20 +--
 .../GridGroup.java}                                |  40 ++---
 .../GridLoader.java}                               |  11 +-
 .../LoadedGrid.java}                               | 170 +++++++++++----------
 .../{provider => gridded}/package-info.java        |  10 +-
 .../operation/provider/AbstractProvider.java       |   2 +-
 .../provider/FranceGeocentricInterpolation.java    |  31 ++--
 .../sis/referencing/operation/provider/NADCON.java |  27 ++--
 .../sis/referencing/operation/provider/NTv2.java   |  58 +++----
 .../operation/provider/package-info.java           |   5 +-
 .../transform/SpecializableTransform.java          |   2 +-
 .../org/apache/sis/referencing/util/j2d/Tile.java  |   2 +-
 .../CompressedGridTest.java}                       |  12 +-
 .../LoadedGridTest.java}                           |  22 +--
 .../FranceGeocentricInterpolationTest.java         |  18 ++-
 .../referencing/operation/provider/NADCONTest.java |  18 ++-
 .../referencing/operation/provider/NTv2Test.java   |  21 +--
 17 files changed, 246 insertions(+), 223 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridCompressed.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/CompressedGrid.java
similarity index 92%
rename from 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridCompressed.java
rename to 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/CompressedGrid.java
index bb48321d08..b4c5bbcec5 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridCompressed.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/CompressedGrid.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.referencing.operation.provider;
+package org.apache.sis.referencing.operation.gridded;
 
 import java.util.Arrays;
 import javax.measure.Quantity;
@@ -34,7 +34,7 @@ import org.apache.sis.util.internal.Numerics;
  * @param <T>  dimension of the translation unit (usually {@link 
javax.measure.quantity.Angle}
  *             or {@link javax.measure.quantity.Length}).
  */
-final class DatumShiftGridCompressed<C extends Quantity<C>, T extends 
Quantity<T>> extends DatumShiftGridFile<C,T> {
+public final class CompressedGrid<C extends Quantity<C>, T extends 
Quantity<T>> extends LoadedGrid<C,T> {
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -61,7 +61,7 @@ final class DatumShiftGridCompressed<C extends Quantity<C>, T 
extends Quantity<T
     /**
      * Creates a new datum shift grid for the same geometry than the given 
grid but different data.
      */
-    private DatumShiftGridCompressed(final DatumShiftGridFile<C,T> grid, final 
double[] averages,
+    private CompressedGrid(final LoadedGrid<C,T> grid, final double[] averages,
             final short[][] data, final double scale)
     {
         super(grid);
@@ -79,8 +79,8 @@ final class DatumShiftGridCompressed<C extends Quantity<C>, T 
extends Quantity<T
      * @param  scale     the factor by which to multiply each compressed value 
before to add to the average value.
      * @return the grid to use (may or may not be compressed).
      */
-    static <C extends Quantity<C>, T extends Quantity<T>> 
DatumShiftGridFile<C,T> compress(
-            final DatumShiftGridFile.Float<C,T> grid, double[] averages, final 
double scale)
+    public static <C extends Quantity<C>, T extends Quantity<T>> 
LoadedGrid<C,T> compress(
+            final LoadedGrid.Float<C,T> grid, double[] averages, final double 
scale)
     {
         final short[][] data = new short[grid.offsets.length][];
         final boolean computeAverages = (averages == null);
@@ -109,7 +109,7 @@ final class DatumShiftGridCompressed<C extends Quantity<C>, 
T extends Quantity<T
             }
             data[dim] = compressed;
         }
-        return new DatumShiftGridCompressed<>(grid, averages, data, scale);
+        return new CompressedGrid<>(grid, averages, data, scale);
     }
 
     /**
@@ -119,8 +119,8 @@ final class DatumShiftGridCompressed<C extends Quantity<C>, 
T extends Quantity<T
      * so we can share existing data.
      */
     @Override
-    protected final DatumShiftGridFile<C,T> setData(final Object[] other) {
-        return new DatumShiftGridCompressed<>(this, averages, (short[][]) 
other, scale);
+    protected final LoadedGrid<C,T> setData(final Object[] other) {
+        return new CompressedGrid<>(this, averages, (short[][]) other, scale);
     }
 
     /**
@@ -243,13 +243,13 @@ final class DatumShiftGridCompressed<C extends 
Quantity<C>, T extends Quantity<T
      * Returns {@code true} if the given object is a grid containing the same 
data than this grid.
      *
      * @param  other  the other object to compare with this datum shift grid.
-     * @return {@code true} if the given object is non-null, an instance of 
{@code DatumShiftGridCompressed}
+     * @return {@code true} if the given object is non-null, an instance of 
{@code CompressedGrid}
      *         and contains the same data.
      */
     @Override
     public boolean equals(final Object other) {
         if (super.equals(other)) {
-            final DatumShiftGridCompressed<?,?> that = 
(DatumShiftGridCompressed<?,?>) other;
+            final CompressedGrid<?,?> that = (CompressedGrid<?,?>) other;
             return Numerics.equals(scale, that.scale) && 
Arrays.equals(averages, that.averages);
         }
         return false;
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridGroup.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridGroup.java
similarity index 89%
rename from 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridGroup.java
rename to 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridGroup.java
index 468ebc1364..2216277902 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridGroup.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridGroup.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.referencing.operation.provider;
+package org.apache.sis.referencing.operation.gridded;
 
 import java.util.Map;
 import java.util.List;
@@ -48,10 +48,10 @@ import org.apache.sis.util.collection.Containers;
  *       most appropriate grid for given coordinates. This is the class where 
to put our optimization efforts,
  *       for example by checking the last used grid before to check all other 
grids.</li>
  *   <li>Only if {@code SpecializableTransform} did not found a better 
transform, it will fallback on a transform
- *       backed by this {@code DatumShiftGridGroup}. In such case, {@link 
InterpolatedTransform} will perform its
+ *       backed by this {@code GridGroup}. In such case, {@link 
InterpolatedTransform} will perform its
  *       calculation by invoking {@link #interpolateInCell(double, double, 
double[])}. That method tries again to
  *       locate the best grid, but performance is less important there since 
that method is only a fallback.</li>
- *   <li>The default {@link DatumShiftGridFile#interpolateInCell(double, 
double, double[])} implementation invokes
+ *   <li>The default {@link LoadedGrid#interpolateInCell(double, double, 
double[])} implementation invokes
  *       {@link #getCellValue(int, int, int)}. We provide that method for 
consistency, but it should not be invoked
  *       since we overrode {@link #interpolateInCell(double, double, 
double[])}.</li>
  * </ol>
@@ -61,7 +61,7 @@ import org.apache.sis.util.collection.Containers;
  * @param <C>  dimension of the coordinate unit (usually angular).
  * @param <T>  dimension of the translation unit (usually angular or linear).
  */
-final class DatumShiftGridGroup<C extends Quantity<C>, T extends Quantity<T>> 
extends DatumShiftGridFile<C,T> {
+public final class GridGroup<C extends Quantity<C>, T extends Quantity<T>> 
extends LoadedGrid<C,T> {
     /**
      * For cross-version compatibility.
      */
@@ -70,7 +70,7 @@ final class DatumShiftGridGroup<C extends Quantity<C>, T 
extends Quantity<T>> ex
     /**
      * The bounds of a sub-grid, together with the subsampling level compared 
to the grid having the finest resolution.
      * All values in this class are integers, but nevertheless stored as 
{@code double} for avoiding to cast them every
-     * time {@link DatumShiftGridGroup#interpolateInCell(double, double, 
double[])} is executed.
+     * time {@link GridGroup#interpolateInCell(double, double, double[])} is 
executed.
      */
     @SuppressWarnings("CloneableImplementsClone")
     private static final class Region extends IntervalRectangle {
@@ -125,19 +125,19 @@ final class DatumShiftGridGroup<C extends Quantity<C>, T 
extends Quantity<T>> ex
      * @throws IOException declared because {@link Tile#getRegion()} declares 
it, but should not happen.
      */
     @SuppressWarnings({"rawtypes", "unchecked"})                        // For 
generic array creation.
-    private DatumShiftGridGroup(final Tile[] tiles,
-                                final Map<Tile,DatumShiftGridFile<C,T>> grids,
-                                final AffineTransform2D gridToCRS,
-                                final Dimension gridSize)
+    private GridGroup(final Tile[] tiles,
+                      final Map<Tile,LoadedGrid<C,T>> grids,
+                      final AffineTransform2D gridToCRS,
+                      final Dimension gridSize)
             throws IOException, NoninvertibleTransformException
     {
         super(grids.get(tiles[0]), gridToCRS, gridSize.width, gridSize.height);
         final int n = grids.size();
         regions  = new Region[n];
-        subgrids = new DatumShiftGridFile[n];
+        subgrids = new LoadedGrid[n];
         for (int i=0; i<n; i++) {
             final Tile tile = tiles[i];
-            final DatumShiftGridFile<C,T> grid = grids.get(tile);
+            final LoadedGrid<C,T> grid = grids.get(tile);
             regions [i] = new Region(tile);
             subgrids[i] = grid;
             if (grid.accuracy > accuracy) {
@@ -155,13 +155,13 @@ final class DatumShiftGridGroup<C extends Quantity<C>, T 
extends Quantity<T>> ex
      * @throws FactoryException if the sub-grid cannot be combined in a single 
mosaic or pyramid.
      * @throws IOException declared because {@link Tile#getRegion()} declares 
it, but should not happen.
      */
-    static <C extends Quantity<C>, T extends Quantity<T>> 
DatumShiftGridGroup<C,T> create(
-            final URI file, final List<DatumShiftGridFile<C,T>> subgrids)
+    public static <C extends Quantity<C>, T extends Quantity<T>> 
GridGroup<C,T> create(
+            final URI file, final List<LoadedGrid<C,T>> subgrids)
             throws IOException, FactoryException, 
NoninvertibleTransformException
     {
         final TileOrganizer mosaic = new TileOrganizer(null);
-        final Map<Tile,DatumShiftGridFile<C,T>> grids = new 
LinkedHashMap<>(Containers.hashMapCapacity(subgrids.size()));
-        for (final DatumShiftGridFile<C,T> grid : subgrids) {
+        final Map<Tile,LoadedGrid<C,T>> grids = new 
LinkedHashMap<>(Containers.hashMapCapacity(subgrids.size()));
+        for (final LoadedGrid<C,T> grid : subgrids) {
             final int[] size = grid.getGridSize();
             final Tile  tile = new Tile(new Rectangle(size[0], size[1]),
                     (AffineTransform) grid.getCoordinateToGrid().inverse());
@@ -185,14 +185,14 @@ final class DatumShiftGridGroup<C extends Quantity<C>, T 
extends Quantity<T>> ex
             throw new 
FactoryException(Resources.format(Resources.Keys.MisalignedDatumShiftGrid_1, 
file));
         }
         final Tile global = result.getKey();
-        return new DatumShiftGridGroup<>(result.getValue(), grids, 
global.getGridToCRS(), global.getSize());
+        return new GridGroup<>(result.getValue(), grids, 
global.getGridToCRS(), global.getSize());
     }
 
     /**
      * Creates a new grid sharing the same data than an existing grid.
      * This constructor is for {@link #setData(Object[])} usage only.
      */
-    private DatumShiftGridGroup(final DatumShiftGridGroup<C,T> other, final 
DatumShiftGridFile<C,T>[] data) {
+    private GridGroup(final GridGroup<C,T> other, final LoadedGrid<C,T>[] 
data) {
         super(other);
         subgrids = data;
         regions  = other.regions;
@@ -206,8 +206,8 @@ final class DatumShiftGridGroup<C extends Quantity<C>, T 
extends Quantity<T>> ex
      */
     @Override
     @SuppressWarnings("unchecked")
-    protected final DatumShiftGridFile<C,T> setData(final Object[] other) {
-        return new DatumShiftGridGroup<>(this, (DatumShiftGridFile<C,T>[]) 
other);
+    protected final LoadedGrid<C,T> setData(final Object[] other) {
+        return new GridGroup<>(this, (LoadedGrid<C,T>[]) other);
     }
 
     /**
@@ -265,7 +265,7 @@ final class DatumShiftGridGroup<C extends Quantity<C>, T 
extends Quantity<T>> ex
             }
         }
         /*
-         * May be in the valid range of this DatumShiftGridGroup but not in 
the range of a subgrid.
+         * May be in the valid range of this GridGroup but not in the range of 
a subgrid.
          * This situation may happen if there is holes in the data coverage 
provided by subgrids.
          */
         throw new IllegalArgumentException();
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridLoader.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridLoader.java
similarity index 96%
rename from 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridLoader.java
rename to 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridLoader.java
index d08196ded4..17e9e5be3f 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridLoader.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/GridLoader.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.referencing.operation.provider;
+package org.apache.sis.referencing.operation.gridded;
 
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
@@ -37,6 +37,7 @@ import org.apache.sis.system.DataDirectory;
 import org.apache.sis.referencing.internal.Resources;
 import org.apache.sis.referencing.factory.FactoryDataException;
 import org.apache.sis.referencing.factory.MissingFactoryResourceException;
+import org.apache.sis.referencing.operation.provider.AbstractProvider;
 
 
 /**
@@ -45,11 +46,11 @@ import 
org.apache.sis.referencing.factory.MissingFactoryResourceException;
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-abstract class DatumShiftGridLoader {
+public abstract class GridLoader {
     /**
      * Conversion factor from degrees to seconds.
      */
-    protected static final double DEGREES_TO_SECONDS = 3600;
+    public static final double DEGREES_TO_SECONDS = 3600;
 
     /**
      * Possible precision for offset values in seconds of angle. This value is 
used only as a hint
@@ -96,7 +97,7 @@ abstract class DatumShiftGridLoader {
      * @param  buffer   the buffer to use.
      * @param  file     path to the longitude or latitude difference file. 
Used for parameter declaration and error reporting.
      */
-    DatumShiftGridLoader(final ReadableByteChannel channel, final ByteBuffer 
buffer, final URI file) throws IOException {
+    protected GridLoader(final ReadableByteChannel channel, final ByteBuffer 
buffer, final URI file) throws IOException {
         this.file    = file;
         this.buffer  = buffer;
         this.channel = channel;
@@ -160,7 +161,7 @@ abstract class DatumShiftGridLoader {
         try {
             return Files.newByteChannel(Path.of(path));
         } catch (FileSystemNotFoundException e) {
-            Logging.ignorableException(AbstractProvider.LOGGER, 
DatumShiftGridLoader.class, "newByteChannel", e);
+            Logging.ignorableException(AbstractProvider.LOGGER, 
GridLoader.class, "newByteChannel", e);
         }
         return Channels.newChannel(path.toURL().openStream());
     }
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridFile.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/LoadedGrid.java
similarity index 82%
rename from 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridFile.java
rename to 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/LoadedGrid.java
index 2b8c69c9bd..81c85a28d7 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/DatumShiftGridFile.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/LoadedGrid.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.referencing.operation.provider;
+package org.apache.sis.referencing.operation.gridded;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -49,6 +49,7 @@ import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.referencing.datum.DatumShiftGrid;
+import org.apache.sis.referencing.operation.provider.AbstractProvider;
 import org.apache.sis.referencing.operation.matrix.AffineTransforms2D;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.operation.transform.InterpolatedTransform;
@@ -56,7 +57,7 @@ import org.apache.sis.referencing.util.j2d.AffineTransform2D;
 
 
 /**
- * A datum shift grid loaded from a file.
+ * A datum shift grid fully loaded in memory from a file.
  * The filename is usually a parameter defined in the EPSG database.
  * This class should not be in public API because it requires implementation 
to expose internal mechanic:
  * Subclasses need to give an access to their internal data (not a copy) 
through the {@link #getData()}
@@ -71,7 +72,7 @@ import org.apache.sis.referencing.util.j2d.AffineTransform2D;
  *
  * @see org.apache.sis.referencing.operation.transform.InterpolatedTransform
  */
-abstract class DatumShiftGridFile<C extends Quantity<C>, T extends 
Quantity<T>> extends DatumShiftGrid<C,T> {
+public abstract class LoadedGrid<C extends Quantity<C>, T extends Quantity<T>> 
extends DatumShiftGrid<C,T> {
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -89,14 +90,14 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
      *
      * @see #getOrLoad(URI, URI, Callable)
      */
-    private static final Cache<Object, DatumShiftGridFile<?,?>> CACHE = new 
Cache<Object, DatumShiftGridFile<?,?>>(4, 32*1024, true) {
-        @Override protected int cost(final DatumShiftGridFile<?,?> grid) {
+    private static final Cache<Object, LoadedGrid<?,?>> CACHE = new 
Cache<Object, LoadedGrid<?,?>>(4, 32*1024, true) {
+        @Override protected int cost(final LoadedGrid<?,?> grid) {
             int p = 1;
             for (final Object data : grid.getData()) {
-                if (data instanceof DatumShiftGridFile<?,?>) {
-                    p += cost((DatumShiftGridFile<?,?>) data);          // 
When `grid` is a DatumShiftGridGroup.
+                if (data instanceof LoadedGrid<?,?>) {
+                    p += cost((LoadedGrid<?,?>) data);      // When `grid` is 
a GridGroup.
                 } else {
-                    p *= Array.getLength(data);                         // 
short[], float[] or double[].
+                    p *= Array.getLength(data);             // short[], 
float[] or double[].
                 }
             }
             return p;
@@ -140,11 +141,11 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
      * The unit of measurement depends on {@link #isCellValueRatio()}.
      *
      * <p>This field is initialized to zero. It is loader responsibility to 
assign
-     * a value to this field after {@code DatumShiftGridFile} construction.</p>
+     * a value to this field after {@code LoadedGrid} construction.</p>
      *
      * @see #getCellPrecision()
      */
-    double accuracy;
+    public double accuracy;
 
     /**
      * The sub-grids, or {@code null} if none. The domain of validity of each 
sub-grid should be contained
@@ -155,14 +156,14 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
      * we do not provide sub-grids functionality in the {@link DatumShiftGrid} 
parent class because
      * the {@link MathTransform} tree will depend on assumptions about {@link 
#getCoordinateToGrid()},
      * in particular that it contains only translations and scales (no 
rotation, no shear).
-     * Those assumptions are enforced by the {@link DatumShiftGridFile} 
constructor.
+     * Those assumptions are enforced by the {@link LoadedGrid} constructor.
      *
-     * <p>This field has protected access for usage by {@link 
DatumShiftGridGroup} subclass only.
+     * <p>This field has package access for usage by {@link GridGroup} 
subclass only.
      * No access to this field should be done except by subclasses.</p>
      *
      * @see #setSubGrids(Collection)
      */
-    protected DatumShiftGridFile<C,T>[] subgrids;
+    LoadedGrid<C,T>[] subgrids;
 
     /**
      * Creates a new datum shift grid for the given grid geometry.
@@ -180,14 +181,14 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
      * @param descriptor        the parameter descriptor of the provider that 
created this grid.
      * @param files             the file(s) from which the grid has been 
loaded. This array is not cloned.
      */
-    DatumShiftGridFile(final Unit<C> coordinateUnit,
-                       final Unit<T> translationUnit,
-                       final boolean isCellValueRatio,
-                       final double x0, final double y0,
-                       final double Δx, final double Δy,
-                       final int    nx, final int    ny,
-                       final ParameterDescriptorGroup descriptor,
-                       final URI... files) throws 
NoninvertibleTransformException
+    LoadedGrid(final Unit<C> coordinateUnit,
+               final Unit<T> translationUnit,
+               final boolean isCellValueRatio,
+               final double x0, final double y0,
+               final double Δx, final double Δy,
+               final int    nx, final int    ny,
+               final ParameterDescriptorGroup descriptor,
+               final URI... files) throws NoninvertibleTransformException
     {
         super(coordinateUnit, new AffineTransform2D(Δx, 0, 0, Δy, x0, 
y0).inverse(),
               new int[] {nx, ny}, isCellValueRatio, translationUnit);
@@ -208,11 +209,11 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
 
     /**
      * Creates a new datum shift grid with the same grid geometry than the 
given grid.
-     * This is used by {@link DatumShiftGridCompressed} for replacing a grid 
by another one.
+     * This is used by {@link CompressedGrid} for replacing a grid by another 
one.
      *
      * @param  other  the other datum shift grid from which to copy the grid 
geometry.
      */
-    protected DatumShiftGridFile(final DatumShiftGridFile<C,T> other) {
+    LoadedGrid(final LoadedGrid<C,T> other) {
         super(other);
         descriptor     = other.descriptor;
         files          = other.files;
@@ -225,7 +226,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
     /**
      * Creates a new datum shift grid with the same configuration than the 
given grid,
      * except the size and transform which are set to the given values.
-     * This is used for creating a {@link DatumShiftGridGroup} containing many 
grids,
+     * This is used for creating a {@link GridGroup} containing many grids,
      * using one grid as a template for setting parameter values.
      * The {@link #accuracy} is initialized to zero and should be updated by 
the caller.
      *
@@ -234,7 +235,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
      * @param  nx         number of cells along the <var>x</var> axis in the 
grid.
      * @param  ny         number of cells along the <var>y</var> axis in the 
grid.
      */
-    DatumShiftGridFile(final DatumShiftGridFile<C,T> other, final 
AffineTransform2D gridToCRS, final int nx, final int ny)
+    LoadedGrid(final LoadedGrid<C,T> other, final AffineTransform2D gridToCRS, 
final int nx, final int ny)
             throws NoninvertibleTransformException
     {
         super(other.getCoordinateUnit(), gridToCRS.inverse(), new int[] {nx, 
ny},
@@ -257,9 +258,9 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
      * @throws Exception if an error occurred while loading the grid.
      *         Caller should handle the exception with {@code canNotLoad(…)}.
      *
-     * @see DatumShiftGridLoader#canNotLoad(Class, String, URI, Exception)
+     * @see GridLoader#canNotLoad(Class, String, URI, Exception)
      */
-    static DatumShiftGridFile<?,?> getOrLoad(final URI f1, final URI f2, final 
Callable<DatumShiftGridFile<?,?>> loader)
+    public static LoadedGrid<?,?> getOrLoad(final URI f1, final URI f2, final 
Callable<LoadedGrid<?,?>> loader)
             throws Exception
     {
         final Object key = (f2 != null) ? new 
AbstractMap.SimpleImmutableEntry<>(f1, f2) : f1;
@@ -269,23 +270,27 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
     /**
      * Sets the sub-grids that are direct children of this grid.
      * This method can be invoked only once.
+     *
+     * @param  children  the sub-grids that are direct children of this grid.
      */
     @SuppressWarnings({"rawtypes", "unchecked"})
-    final void setSubGrids(final Collection<DatumShiftGridFile<C,T>> children) 
{
+    public final void setSubGrids(final Collection<LoadedGrid<C,T>> children) {
         if (subgrids != null) throw new IllegalStateException();
-        subgrids = children.toArray(DatumShiftGridFile[]::new);
+        subgrids = children.toArray(LoadedGrid[]::new);
     }
 
     /**
      * Returns the number of grids, including this grid and all sub-grids 
counted recursively.
      * This is used for information purpose only.
      *
+     * @return number of grids, including children.
+     *
      * @see #toTree(TreeTable.Node)
      */
     private int getGridCount() {
         int n = 1;
         if (subgrids != null) {
-            for (final DatumShiftGridFile<C,T> subgrid : subgrids) {
+            for (final LoadedGrid<C,T> subgrid : subgrids) {
                 n += subgrid.getGridCount();
             }
         }
@@ -293,8 +298,8 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
     }
 
     /**
-     * Returns a string representation of this grid for debugging purpose.
-     * If this grid has children, then it will be formatted as a tree.
+     * {@return a string representation of this grid for debugging purpose}.
+     * If this grid has children, then they will be formatted as a tree.
      */
     @Override
     public final String toString() {
@@ -309,12 +314,14 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
     /**
      * Formats this grid as a tree with its children.
      * Used for building a tree representation of children nodes.
+     *
+     * @param  branch  destination where to format the tree.
      */
     private void toTree(final TreeTable.Node branch) {
         String label = super.toString();
         if (subgrids != null) {
             label = label + " (" + getGridCount() + " grids)";
-            for (final DatumShiftGridFile<C,T> subgrid : subgrids) {
+            for (final LoadedGrid<C,T> subgrid : subgrids) {
                 subgrid.toTree(branch.newChild());
             }
         }
@@ -323,16 +330,19 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
 
     /**
      * Returns {@code this} casted to the given type, after verification that 
those types are valid.
-     * This method is invoked after {@link NADCON}, {@link NTv2} or other 
providers got an existing
-     * {@code DatumShiftGridFile} instance from the {@link #CACHE}.
+     * This method is invoked after NADCON, NTv2 or other providers got an 
existing {@code LoadedGrid}
+     * instance from the {@link #CACHE}.
+     *
+     * @param  coordinateType   desired type (angle or length) of coordinate 
values.
+     * @param  translationType  desired type (angle or length) of translation 
vectors.
      */
     @SuppressWarnings("unchecked")
-    final <NC extends Quantity<NC>, NT extends Quantity<NT>> 
DatumShiftGridFile<NC,NT> castTo(
+    public final <NC extends Quantity<NC>, NT extends Quantity<NT>> 
LoadedGrid<NC,NT> castTo(
             final Class<NC> coordinateType, final Class<NT> translationType)
     {
         super.getCoordinateUnit() .asType(coordinateType);
         super.getTranslationUnit().asType(translationType);
-        return (DatumShiftGridFile<NC,NT>) this;
+        return (LoadedGrid<NC,NT>) this;
     }
 
     /**
@@ -344,9 +354,9 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
      * @see #getData()
      * @see #setData(Object[])
      */
-    protected final DatumShiftGridFile<C,T> useSharedData() {
+    public final LoadedGrid<C,T> useSharedData() {
         final Object[] data = getData();
-        for (final DatumShiftGridFile<?,?> grid : CACHE.values()) {
+        for (final LoadedGrid<?,?> grid : CACHE.values()) {
             final Object[] other = grid.getData();
             if (Arrays.deepEquals(data, other)) {
                 return setData(other);
@@ -362,10 +372,10 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
      * reference the same grid (e.g. symbolic link, lower case versus upper 
case in a case-insensitive file
      * system).
      *
-     * @param  other  data from another {@code DatumShiftGridFile} that we can 
share.
-     * @return a new {@code DatumShiftGridFile} using the given data reference.
+     * @param  other  data from another {@code LoadedGrid} that we can share.
+     * @return a new {@code LoadedGrid} using the given data reference.
      */
-    protected abstract DatumShiftGridFile<C,T> setData(Object[] other);
+    protected abstract LoadedGrid<C,T> setData(Object[] other);
 
     /**
      * Returns the data for each shift dimensions. This method is for cache 
management, {@link #equals(Object)}
@@ -389,7 +399,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
             return true;
         }
         if (super.equals(other)) {
-            final DatumShiftGridFile<?,?> that = (DatumShiftGridFile<?,?>) 
other;
+            final LoadedGrid<?,?> that = (LoadedGrid<?,?>) other;
             return Arrays.equals(files, that.files) && 
Arrays.deepEquals(getData(), that.getData());
         }
         return false;
@@ -473,19 +483,19 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
      * @see 
InterpolatedTransform#createGeodeticTransformation(MathTransformFactory, 
DatumShiftGrid)
      */
     public static MathTransform createGeodeticTransformation(final Class<? 
extends AbstractProvider> provider,
-            final MathTransformFactory factory, final 
DatumShiftGridFile<Angle,Angle> grid) throws FactoryException
+            final MathTransformFactory factory, final LoadedGrid<Angle,Angle> 
grid) throws FactoryException
     {
         MathTransform global = 
InterpolatedTransform.createGeodeticTransformation(factory, grid);
-        final DatumShiftGridFile<Angle,Angle>[] subgrids = grid.subgrids;
+        final LoadedGrid<Angle,Angle>[] subgrids = grid.subgrids;
         if (subgrids == null) {
             return global;
         }
         final Map<Envelope,MathTransform> specializations = new 
LinkedHashMap<>(Containers.hashMapCapacity(subgrids.length));
-        for (final DatumShiftGridFile<Angle,Angle> sg : subgrids) try {
+        for (final LoadedGrid<Angle,Angle> sg : subgrids) try {
             final Envelope domain = sg.getDomainOfValidity(Units.DEGREE);
             final MathTransform st = createGeodeticTransformation(provider, 
factory, sg);
             if (specializations.putIfAbsent(domain, st) != null) {
-                DatumShiftGridLoader.log(provider, 
Errors.getResources((Locale) null)
+                GridLoader.log(provider, Errors.getResources((Locale) null)
                         .getLogRecord(Level.FINE, 
Errors.Keys.DuplicatedElement_1, domain));
             }
         } catch (TransformException e) {
@@ -498,7 +508,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
 
 
     /**
-     * An implementation of {@link DatumShiftGridFile} which stores the offset 
values in {@code float[]} arrays.
+     * An implementation of {@link LoadedGrid} which stores the offset values 
in {@code float[]} arrays.
      * This class is in internal package (not public API) because it makes the 
following assumptions:
      * <ul>
      *   <li>Values <var>x₀</var>, <var>y₀</var>, <var>Δx</var> and 
<var>Δy</var>
@@ -513,7 +523,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
      * @param <C>  dimension of the coordinate unit (usually angular).
      * @param <T>  dimension of the translation unit (usually angular or 
linear).
      */
-    static final class Float<C extends Quantity<C>, T extends Quantity<T>> 
extends DatumShiftGridFile<C,T> {
+    public static final class Float<C extends Quantity<C>, T extends 
Quantity<T>> extends LoadedGrid<C,T> {
         /**
          * Serial number for inter-operability with different versions.
          */
@@ -524,7 +534,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
          * shall be the same for all {@code dim} value. Component {@code dim} 
of the translation vector at coordinate
          * {@code gridX}, {@code gridY} is {@code offsets[dim][gridX + 
gridY*scanlineStride]}.
          */
-        final float[][] offsets;
+        public final float[][] offsets;
 
         /**
          * Creates a new datum shift grid with the given grid geometry, 
filename and number of shift dimensions.
@@ -532,15 +542,15 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
          *
          * @param  dim  number of dimensions of translation vectors.
          */
-        Float(final int dim,
-              final Unit<C> coordinateUnit,
-              final Unit<T> translationUnit,
-              final boolean isCellValueRatio,
-              final double x0, final double y0,
-              final double Δx, final double Δy,
-              final int    nx, final int    ny,
-              final ParameterDescriptorGroup descriptor,
-              final URI... files) throws NoninvertibleTransformException
+        public Float(final int dim,
+                     final Unit<C> coordinateUnit,
+                     final Unit<T> translationUnit,
+                     final boolean isCellValueRatio,
+                     final double x0, final double y0,
+                     final double Δx, final double Δy,
+                     final int    nx, final int    ny,
+                     final ParameterDescriptorGroup descriptor,
+                     final URI... files) throws NoninvertibleTransformException
         {
             super(coordinateUnit, translationUnit, isCellValueRatio, x0, y0, 
Δx, Δy, nx, ny, descriptor, files);
             offsets = new float[dim][Math.multiplyExact(nx, ny)];
@@ -549,7 +559,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
         /**
          * Creates a new grid of the same geometry than the given grid but 
using a different data array.
          */
-        private Float(final DatumShiftGridFile<C,T> grid, final float[][] 
offsets) {
+        private Float(final LoadedGrid<C,T> grid, final float[][] offsets) {
             super(grid);
             this.offsets = offsets;
         }
@@ -561,7 +571,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
          * so we can share existing data.
          */
         @Override
-        protected final DatumShiftGridFile<C,T> setData(final Object[] other) {
+        protected final LoadedGrid<C,T> setData(final Object[] other) {
             return new Float<>(this, (float[][]) other);
         }
 
@@ -622,38 +632,38 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
 
 
     /**
-     * An implementation of {@link DatumShiftGridFile} which stores the offset 
values in {@code double[]} arrays.
-     * See {@link DatumShiftGridFile.Float} for more information (most 
comments apply to this class as well).
+     * An implementation of {@link LoadedGrid} which stores the offset values 
in {@code double[]} arrays.
+     * See {@link LoadedGrid.Float} for more information (most comments apply 
to this class as well).
      *
      * @author  Martin Desruisseaux (Geomatys)
      *
      * @param <C>  dimension of the coordinate unit (usually angular).
      * @param <T>  dimension of the translation unit (usually angular or 
linear).
      */
-    static final class Double<C extends Quantity<C>, T extends Quantity<T>> 
extends DatumShiftGridFile<C,T> {
+    public static final class Double<C extends Quantity<C>, T extends 
Quantity<T>> extends LoadedGrid<C,T> {
         /**
          * Serial number for inter-operability with different versions.
          */
         private static final long serialVersionUID = 3999271636016362364L;
 
         /**
-         * The translation values. See {@link 
DatumShiftGridFile.Float#offsets} for more documentation.
+         * The translation values. See {@link LoadedGrid.Float#offsets} for 
more documentation.
          */
-        final double[][] offsets;
+        public final double[][] offsets;
 
         /**
          * Creates a new datum shift grid with the given grid geometry, 
filename and number of shift dimensions.
          * All {@code double} values given to this constructor will be 
converted from degrees to radians.
          */
-        Double(final int dim,
-               final Unit<C> coordinateUnit,
-               final Unit<T> translationUnit,
-               final boolean isCellValueRatio,
-               final double x0, final double y0,
-               final double Δx, final double Δy,
-               final int    nx, final int    ny,
-               final ParameterDescriptorGroup descriptor,
-               final URI... files) throws NoninvertibleTransformException
+        public Double(final int dim,
+                      final Unit<C> coordinateUnit,
+                      final Unit<T> translationUnit,
+                      final boolean isCellValueRatio,
+                      final double x0, final double y0,
+                      final double Δx, final double Δy,
+                      final int    nx, final int    ny,
+                      final ParameterDescriptorGroup descriptor,
+                      final URI... files) throws 
NoninvertibleTransformException
         {
             super(coordinateUnit, translationUnit, isCellValueRatio, x0, y0, 
Δx, Δy, nx, ny, descriptor, files);
             offsets = new double[dim][Math.multiplyExact(nx, ny)];
@@ -662,23 +672,23 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, 
T extends Quantity<T>>
         /**
          * Creates a new grid of the same geometry than the given grid but 
using a different data array.
          */
-        private Double(final DatumShiftGridFile<C,T> grid, final double[][] 
offsets) {
+        private Double(final LoadedGrid<C,T> grid, final double[][] offsets) {
             super(grid);
             this.offsets = offsets;
         }
 
         /**
          * Returns a new grid with the same geometry than this grid but 
different data arrays.
-         * See {@link DatumShiftGridFile.Float#setData(Object[])} for more 
documentation.
+         * See {@link LoadedGrid.Float#setData(Object[])} for more 
documentation.
          */
         @Override
-        protected final DatumShiftGridFile<C,T> setData(final Object[] other) {
+        protected final LoadedGrid<C,T> setData(final Object[] other) {
             return new Double<>(this, (double[][]) other);
         }
 
         /**
          * Returns direct references (not cloned) to the data arrays.
-         * See {@link DatumShiftGridFile.Float#getData()} for more 
documentation.
+         * See {@link LoadedGrid.Float#getData()} for more documentation.
          */
         @Override
         @SuppressWarnings("ReturnOfCollectionOrArrayField")
@@ -696,7 +706,7 @@ abstract class DatumShiftGridFile<C extends Quantity<C>, T 
extends Quantity<T>>
 
         /**
          * Returns the cell value at the given dimension and grid index.
-         * See {@link DatumShiftGridFile.Float#getCellValue(int, int, int)} 
for more documentation.
+         * See {@link LoadedGrid.Float#getCellValue(int, int, int)} for more 
documentation.
          */
         @Override
         public final double getCellValue(final int dim, final int gridX, final 
int gridY) {
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/package-info.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/package-info.java
similarity index 66%
copy from 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/package-info.java
copy to 
endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/package-info.java
index 9d98743f63..b969f48dc6 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/package-info.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/gridded/package-info.java
@@ -16,13 +16,9 @@
  */
 
 /**
- * {@linkplain 
org.apache.sis.referencing.operation.transform.MathTransformProvider Math 
transform provider}
- * implementations. See {@link 
org.apache.sis.referencing.operation.transform.MathTransformProvider} for a
- * discussion of parameters.
+ * Support classes for loading of gridded data.
+ * This package is for Apache SIS internal purposes only and may change 
without notice in any future version.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @author  Matthieu Bastianelli (Geomatys)
- *
- * @see org.apache.sis.referencing.operation.transform.MathTransformProvider
  */
-package org.apache.sis.referencing.operation.provider;
+package org.apache.sis.referencing.operation.gridded;
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/AbstractProvider.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/AbstractProvider.java
index 9dd0014a2f..7f30d7f147 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/AbstractProvider.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/AbstractProvider.java
@@ -64,7 +64,7 @@ public abstract class AbstractProvider extends 
DefaultOperationMethod implements
     /**
      * The logger for coordinate operations.
      */
-    static final Logger LOGGER = 
Logger.getLogger(Loggers.COORDINATE_OPERATION);
+    public static final Logger LOGGER = 
Logger.getLogger(Loggers.COORDINATE_OPERATION);
 
     /**
      * The base interface of the {@code CoordinateOperation} instances that 
use this method.
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 4b92f06fda..c2cbceab50 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
@@ -47,6 +47,9 @@ import 
org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.opengis.util.FactoryException;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.datum.DefaultEllipsoid;
+import org.apache.sis.referencing.operation.gridded.LoadedGrid;
+import org.apache.sis.referencing.operation.gridded.GridLoader;
+import org.apache.sis.referencing.operation.gridded.CompressedGrid;
 import 
org.apache.sis.referencing.operation.transform.InterpolatedGeocentricTransform;
 import org.apache.sis.referencing.util.NilReferencingObject;
 import org.apache.sis.referencing.internal.Resources;
@@ -342,12 +345,12 @@ public final class FranceGeocentricInterpolation extends 
GeodeticOperation {
                             Errors.Keys.IllegalArgumentValue_2, DIM, dim), 
DIM, dim);
         }
         final URI file = pg.getMandatoryValue(FILE);
-        final DatumShiftGridFile<Angle,Length> grid;
+        final LoadedGrid<Angle,Length> grid;
         try {
             grid = getOrLoad(file, isRecognized(file) ? new double[] {TX, TY, 
TZ} : null, PRECISION);
         } catch (Exception e) {
             // NumberFormatException, ArithmeticException, 
NoSuchElementException, and more.
-            throw 
DatumShiftGridLoader.canNotLoad(FranceGeocentricInterpolation.class, HEADER, 
file, e);
+            throw GridLoader.canNotLoad(FranceGeocentricInterpolation.class, 
HEADER, file, e);
         }
         MathTransform tr = 
InterpolatedGeocentricTransform.createGeodeticTransformation(factory,
                 createEllipsoid(pg, Molodensky.TGT_SEMI_MAJOR,
@@ -372,13 +375,13 @@ public final class FranceGeocentricInterpolation extends 
GeodeticOperation {
      * @throws Exception if an error occurred while loading the grid.
      *         Caller should handle the exception with {@code canNotLoad(…)}.
      *
-     * @see DatumShiftGridLoader#canNotLoad(Class, String, URI, Exception)
+     * @see GridLoader#canNotLoad(Class, String, URI, Exception)
      */
-    static DatumShiftGridFile<Angle,Length> getOrLoad(final URI file, final 
double[] averages, final double scale)
+    static LoadedGrid<Angle,Length> getOrLoad(final URI file, final double[] 
averages, final double scale)
             throws Exception
     {
         final URI resolved = DataDirectory.DATUM_CHANGES.toAbsolutePath(file);
-        return DatumShiftGridFile.getOrLoad(resolved, null, new 
Loader(resolved, averages, scale))
+        return LoadedGrid.getOrLoad(resolved, null, new Loader(resolved, 
averages, scale))
                                  .castTo(Angle.class, Length.class);
     }
 
@@ -386,7 +389,7 @@ public final class FranceGeocentricInterpolation extends 
GeodeticOperation {
      * Temporary object created for loading gridded data if not present in the 
cache.
      * The data are provided in a text file, which is read with {@link 
BufferedReader}.
      */
-    static final class Loader implements Callable<DatumShiftGridFile<?,?>> {
+    static final class Loader implements Callable<LoadedGrid<?,?>> {
         /** The file to load. */
         private final URI file;
 
@@ -418,12 +421,12 @@ public final class FranceGeocentricInterpolation extends 
GeodeticOperation {
          *         {@link NoSuchElementException}, {@link 
NoninvertibleTransformException}, <i>etc</i>.
          */
         @Override
-        public DatumShiftGridFile<?,?> call() throws Exception {
-            final DatumShiftGridFile<?,?> grid;
+        public LoadedGrid<?,?> call() throws Exception {
+            final LoadedGrid<?,?> grid;
             try (BufferedReader in = newBufferedReader(file)) {
-                
DatumShiftGridLoader.startLoading(FranceGeocentricInterpolation.class, file);
-                final DatumShiftGridFile.Float<Angle,Length> g = load(in, 
file);
-                grid = DatumShiftGridCompressed.compress(g, averages, scale);
+                GridLoader.startLoading(FranceGeocentricInterpolation.class, 
file);
+                final LoadedGrid.Float<Angle,Length> g = load(in, file);
+                grid = CompressedGrid.compress(g, averages, scale);
             }
             return grid.useSharedData();
         }
@@ -439,10 +442,10 @@ public final class FranceGeocentricInterpolation extends 
GeodeticOperation {
          * @throws FactoryException if an problem is found with the file 
content.
          * @throws ArithmeticException if the width or the height exceed the 
integer capacity.
          */
-        static DatumShiftGridFile.Float<Angle,Length> load(final 
BufferedReader in, final URI file)
+        static LoadedGrid.Float<Angle,Length> load(final BufferedReader in, 
final URI file)
                 throws IOException, FactoryException, 
NoninvertibleTransformException
         {
-            DatumShiftGridFile.Float<Angle,Length> grid = null;
+            LoadedGrid.Float<Angle,Length> grid = null;
             double x0 = 0;
             double xf = 0;
             double y0 = 0;
@@ -495,7 +498,7 @@ public final class FranceGeocentricInterpolation extends 
GeodeticOperation {
                                 Δy = gridGeometry[5];
                                 nx = Math.toIntExact(Math.round((xf - x0) / Δx 
+ 1));
                                 ny = Math.toIntExact(Math.round((yf - y0) / Δy 
+ 1));
-                                grid = new DatumShiftGridFile.Float<>(3,
+                                grid = new LoadedGrid.Float<>(3,
                                         Units.DEGREE, Units.METRE, false,
                                         x0, y0, Δx, Δy, nx, ny, PARAMETERS, 
file);
                                 grid.accuracy = Double.NaN;
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NADCON.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NADCON.java
index 45305d1761..4aee4d03f4 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NADCON.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NADCON.java
@@ -36,6 +36,9 @@ import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.Transformation;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
 import org.apache.sis.referencing.factory.MissingFactoryResourceException;
+import org.apache.sis.referencing.operation.gridded.CompressedGrid;
+import org.apache.sis.referencing.operation.gridded.GridLoader;
+import org.apache.sis.referencing.operation.gridded.LoadedGrid;
 import org.apache.sis.parameter.ParameterBuilder;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.util.CharSequences;
@@ -140,7 +143,7 @@ public final class NADCON extends AbstractProvider {
     {
         final Parameters pg = Parameters.castOrWrap(values);
         try {
-            return 
DatumShiftGridFile.createGeodeticTransformation(NADCON.class, factory,
+            return LoadedGrid.createGeodeticTransformation(NADCON.class, 
factory,
                     getOrLoad(pg.getMandatoryValue(LATITUDE), 
pg.getMandatoryValue(LONGITUDE)));
         } catch (NoSuchFileException e) {
             throw new MissingFactoryResourceException(e.getMessage(), e);
@@ -157,28 +160,28 @@ public final class NADCON extends AbstractProvider {
      * @param  longitudeShifts  relative or absolute path name of the grid 
file for longitude shifts.
      * @throws Exception if an error occurred while loading the grid.
      */
-    static DatumShiftGridFile<Angle,Angle> getOrLoad(final URI latitudeShifts, 
final URI longitudeShifts)
+    static LoadedGrid<Angle,Angle> getOrLoad(final URI latitudeShifts, final 
URI longitudeShifts)
             throws Exception
     {
         final URI rlat = 
DataDirectory.DATUM_CHANGES.toAbsolutePath(latitudeShifts);
         final URI rlon = 
DataDirectory.DATUM_CHANGES.toAbsolutePath(longitudeShifts);
-        return DatumShiftGridFile.getOrLoad(rlat, rlon, () -> {
+        return LoadedGrid.getOrLoad(rlat, rlon, () -> {
             final Loader loader;
             URI file = latitudeShifts;
-            final DatumShiftGridFile<?,?> grid;
+            final LoadedGrid<?,?> grid;
             try {
                 // Note: buffer size must be divisible by the size of `float` 
data type.
                 final ByteBuffer buffer = 
ByteBuffer.allocate(4096).order(ByteOrder.LITTLE_ENDIAN);
                 final FloatBuffer fb = buffer.asFloatBuffer();
-                try (ReadableByteChannel in = 
DatumShiftGridLoader.newByteChannel(rlat)) {
-                    DatumShiftGridLoader.startLoading(NADCON.class, 
CharSequences.commonPrefix(
+                try (ReadableByteChannel in = GridLoader.newByteChannel(rlat)) 
{
+                    GridLoader.startLoading(NADCON.class, 
CharSequences.commonPrefix(
                             latitudeShifts.toString(), 
longitudeShifts.toString()).toString() + '…');
                     loader = new Loader(in, buffer, file);
                     loader.readGrid(fb, null, longitudeShifts);
                 }
                 buffer.clear();
                 file = longitudeShifts;
-                try (ReadableByteChannel in = 
DatumShiftGridLoader.newByteChannel(rlon)) {
+                try (ReadableByteChannel in = GridLoader.newByteChannel(rlon)) 
{
                     new Loader(in, buffer, file).readGrid(fb, loader, null);
                 }
             } catch (IOException | NoninvertibleTransformException | 
RuntimeException e) {
@@ -186,9 +189,9 @@ public final class NADCON extends AbstractProvider {
                  * Handle the exception here instead of by the caller
                  * because we know which of the 2 files is problematic.
                  */
-                throw DatumShiftGridLoader.canNotLoad(NADCON.class, "NADCON", 
file, e);
+                throw GridLoader.canNotLoad(NADCON.class, "NADCON", file, e);
             }
-            grid = DatumShiftGridCompressed.compress(loader.grid, null, 
loader.grid.accuracy);
+            grid = CompressedGrid.compress(loader.grid, null, 
loader.grid.accuracy);
             return grid.useSharedData();
         }).castTo(Angle.class, Angle.class);
     }
@@ -217,7 +220,7 @@ public final class NADCON extends AbstractProvider {
      * @author  Martin Desruisseaux (Geomatys)
      * @author  Rueben Schulz (UBC)
      */
-    private static final class Loader extends DatumShiftGridLoader {
+    private static final class Loader extends GridLoader {
         /**
          * The length of the description in the header, in bytes.
          * <ul>
@@ -256,7 +259,7 @@ public final class NADCON extends AbstractProvider {
         /**
          * The grid created by {@link #readGrid(FloatBuffer, Loader, URI)}.
          */
-        DatumShiftGridFile.Float<Angle,Angle> grid;
+        LoadedGrid.Float<Angle,Angle> grid;
 
         /**
          * Creates a new reader for the given channel. The file can be binary 
or ASCII.
@@ -390,7 +393,7 @@ public final class NADCON extends AbstractProvider {
             if (latitudeShifts == null) {
                 dim   = 1;                                              // 
Dimension of latitudes.
                 scale = DEGREES_TO_SECONDS * Δy;                        // 
NADCON shifts are positive north.
-                grid  = new DatumShiftGridFile.Float<>(2, Units.DEGREE, 
Units.DEGREE,
+                grid  = new LoadedGrid.Float<>(2, Units.DEGREE, Units.DEGREE,
                         true, x0, y0, Δx, Δy, nx, ny, PARAMETERS, file, 
longitudeShifts);
                 grid.accuracy = SECOND_PRECISION / DEGREES_TO_SECONDS;
             } else {
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NTv2.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NTv2.java
index 6daee0dff1..863f795653 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NTv2.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/NTv2.java
@@ -43,6 +43,10 @@ import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransformFactory;
 import org.opengis.referencing.operation.Transformation;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.apache.sis.referencing.operation.gridded.CompressedGrid;
+import org.apache.sis.referencing.operation.gridded.GridLoader;
+import org.apache.sis.referencing.operation.gridded.GridGroup;
+import org.apache.sis.referencing.operation.gridded.LoadedGrid;
 import org.apache.sis.referencing.util.Formulas;
 import org.apache.sis.referencing.internal.Resources;
 import org.apache.sis.parameter.ParameterBuilder;
@@ -143,13 +147,13 @@ public final class NTv2 extends AbstractProvider {
     {
         final Parameters pg = Parameters.castOrWrap(values);
         final URI file = pg.getMandatoryValue(FILE);
-        final DatumShiftGridFile<Angle,Angle> grid;
+        final LoadedGrid<Angle,Angle> grid;
         try {
             grid = getOrLoad(provider, file, version);
         } catch (Exception e) {
-            throw DatumShiftGridLoader.canNotLoad(provider, 
provider.getSimpleName(), file, e);
+            throw GridLoader.canNotLoad(provider, provider.getSimpleName(), 
file, e);
         }
-        return DatumShiftGridFile.createGeodeticTransformation(provider, 
factory, grid);
+        return LoadedGrid.createGeodeticTransformation(provider, factory, 
grid);
     }
 
     /**
@@ -162,16 +166,16 @@ public final class NTv2 extends AbstractProvider {
      * @throws Exception if an error occurred while loading the grid.
      *         Caller should handle the exception with {@code canNotLoad(…)}.
      *
-     * @see DatumShiftGridLoader#canNotLoad(String, URI, Exception)
+     * @see GridLoader#canNotLoad(String, URI, Exception)
      */
-    static DatumShiftGridFile<Angle,Angle> getOrLoad(final Class<? extends 
AbstractProvider> provider,
+    static LoadedGrid<Angle,Angle> getOrLoad(final Class<? extends 
AbstractProvider> provider,
             final URI file, final int version) throws Exception
     {
         final URI resolved = DataDirectory.DATUM_CHANGES.toAbsolutePath(file);
-        return DatumShiftGridFile.getOrLoad(resolved, null, () -> {
-            final DatumShiftGridFile<?,?> grid;
-            try (ReadableByteChannel in = 
DatumShiftGridLoader.newByteChannel(resolved)) {
-                DatumShiftGridLoader.startLoading(provider, file);
+        return LoadedGrid.getOrLoad(resolved, null, () -> {
+            final LoadedGrid<?,?> grid;
+            try (ReadableByteChannel in = GridLoader.newByteChannel(resolved)) 
{
+                GridLoader.startLoading(provider, file);
                 final Loader loader = new Loader(in, file, version);
                 grid = loader.readAllGrids();
                 loader.report(provider);
@@ -200,7 +204,7 @@ public final class NTv2 extends AbstractProvider {
      * @author  Simon Reynard (Geomatys)
      * @author  Martin Desruisseaux (Geomatys)
      */
-    private static final class Loader extends DatumShiftGridLoader {
+    private static final class Loader extends GridLoader {
         /**
          * Size of a record. This value applies to both the header records and 
the data records.
          * In the case of header records, this is the size of the key plus the 
size of the value.
@@ -438,9 +442,9 @@ public final class NTv2 extends AbstractProvider {
          * them in a child-parent relationship. The result is a tree with a 
single root containing
          * sub-grids (if any) as children.
          */
-        final DatumShiftGridFile<Angle,Angle> readAllGrids() throws 
IOException, FactoryException, NoninvertibleTransformException {
-            final Map<String,      DatumShiftGridFile<Angle,Angle>>  grids    
= new HashMap<>(Containers.hashMapCapacity(numGrids));
-            final Map<String, List<DatumShiftGridFile<Angle,Angle>>> children 
= new LinkedHashMap<>();   // Should have few entries.
+        final LoadedGrid<Angle,Angle> readAllGrids() throws IOException, 
FactoryException, NoninvertibleTransformException {
+            final Map<String,      LoadedGrid<Angle,Angle>>  grids    = new 
HashMap<>(Containers.hashMapCapacity(numGrids));
+            final Map<String, List<LoadedGrid<Angle,Angle>>> children = new 
LinkedHashMap<>();   // Should have few entries.
             while (grids.size() < numGrids) {
                 readGrid(grids, children);
             }
@@ -452,10 +456,10 @@ public final class NTv2 extends AbstractProvider {
              *        the grids in cycles will be lost. This is because we 
need a grid without parent for getting the
              *        graph added in the roots list. There is currently no 
mechanism for detecting those problems.
              */
-            final List<DatumShiftGridFile<Angle,Angle>> roots = new 
ArrayList<>();
-            for (final Map.Entry<String, 
List<DatumShiftGridFile<Angle,Angle>>> entry : children.entrySet()) {
-                final DatumShiftGridFile<Angle,Angle> parent = 
grids.get(entry.getKey());
-                final List<DatumShiftGridFile<Angle,Angle>> subgrids = 
entry.getValue();
+            final List<LoadedGrid<Angle,Angle>> roots = new ArrayList<>();
+            for (final Map.Entry<String, List<LoadedGrid<Angle,Angle>>> entry 
: children.entrySet()) {
+                final LoadedGrid<Angle,Angle> parent = 
grids.get(entry.getKey());
+                final List<LoadedGrid<Angle,Angle>> subgrids = 
entry.getValue();
                 if (parent != null) {
                     /*
                      * Verify that the children does not declare themselves as 
their parent.
@@ -479,7 +483,7 @@ public final class NTv2 extends AbstractProvider {
             switch (roots.size()) {
                 case 0:  throw new 
FactoryException(Errors.format(Errors.Keys.CanNotRead_1, file));
                 case 1:  return roots.get(0);
-                default: return DatumShiftGridGroup.create(file, roots);
+                default: return GridGroup.create(file, roots);
             }
         }
 
@@ -495,8 +499,8 @@ public final class NTv2 extends AbstractProvider {
          * @param  addTo     the map where to add the grid with the grid name 
as the key.
          * @param  children  the map where to add children with the parent 
name as the key.
          */
-        private void readGrid(final Map<String, 
DatumShiftGridFile<Angle,Angle>> addTo,
-                final Map<String, List<DatumShiftGridFile<Angle,Angle>>> 
children)
+        private void readGrid(final Map<String, LoadedGrid<Angle,Angle>> addTo,
+                final Map<String, List<LoadedGrid<Angle,Angle>>> children)
                 throws IOException, FactoryException, 
NoninvertibleTransformException
         {
             if (isV2) {
@@ -540,16 +544,16 @@ public final class NTv2 extends AbstractProvider {
             /*
              * Construct the grid. The sign of longitude translations will 
need to be reversed in order to have
              * longitudes increasing toward East. We set isCellValueRatio = 
true (by the arguments given to the
-             * DatumShiftGridFile constructor) because this is required by 
InterpolatedTransform implementation.
+             * LoadedGrid constructor) because this is required by 
InterpolatedTransform implementation.
              * This setting implies that we divide translation values by dx or 
dy at reading time. Note that this
              * free us from reversing the sign of longitude translations in 
the code below; instead, this reversal
              * will be handled by grid.coordinateToGrid MathTransform and its 
inverse.
              */
             final double size = Math.max(dx, dy);
-            final DatumShiftGridFile<Angle,Angle> grid;
+            final LoadedGrid<Angle,Angle> grid;
             if (isV2) {
-                final DatumShiftGridFile.Float<Angle,Angle> data;
-                data = new DatumShiftGridFile.Float<>(2, unit, unit, true,
+                final LoadedGrid.Float<Angle,Angle> data;
+                data = new LoadedGrid.Float<>(2, unit, unit, true,
                         -xmin, ymin, -dx, dy, width, height, PARAMETERS, file);
                 @SuppressWarnings("MismatchedReadAndWriteOfArray") final 
float[] tx = data.offsets[0];
                 @SuppressWarnings("MismatchedReadAndWriteOfArray") final 
float[] ty = data.offsets[1];
@@ -563,13 +567,13 @@ public final class NTv2 extends AbstractProvider {
                         data.accuracy = accuracy;                           // 
Smallest non-zero accuracy.
                     }
                 }
-                grid = DatumShiftGridCompressed.compress(data, null, precision 
/ size);
+                grid = CompressedGrid.compress(data, null, precision / size);
             } else {
                 /*
                  * NTv1: same as NTv2 but using double precision and without 
accuracy information.
                  */
-                final DatumShiftGridFile.Double<Angle,Angle> data;
-                grid = data = new DatumShiftGridFile.Double<>(2, unit, unit, 
true,
+                final LoadedGrid.Double<Angle,Angle> data;
+                grid = data = new LoadedGrid.Double<>(2, unit, unit, true,
                         -xmin, ymin, -dx, dy, width, height, PARAMETERS, file);
                 @SuppressWarnings("MismatchedReadAndWriteOfArray") final 
double[] tx = data.offsets[0];
                 @SuppressWarnings("MismatchedReadAndWriteOfArray") final 
double[] ty = data.offsets[1];
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/package-info.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/package-info.java
index 9d98743f63..01a0955e6b 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/package-info.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/provider/package-info.java
@@ -16,9 +16,8 @@
  */
 
 /**
- * {@linkplain 
org.apache.sis.referencing.operation.transform.MathTransformProvider Math 
transform provider}
- * implementations. See {@link 
org.apache.sis.referencing.operation.transform.MathTransformProvider} for a
- * discussion of parameters.
+ * Math transform provider implementations.
+ * See {@link 
org.apache.sis.referencing.operation.transform.MathTransformProvider} for a 
discussion of parameters.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Matthieu Bastianelli (Geomatys)
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
index 0207095b55..062557a45f 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
@@ -243,7 +243,7 @@ class SpecializableTransform extends AbstractMathTransform 
implements Serializab
          * All nodes should be SubArea instances, except in some circumstances 
the root node.
          * That root node may be returned by `RTreeNode.locate(…)` if given 
position is inside
          * the union of all bounding boxes, but not in the bounding box of any 
specific grid.
-         * In such case the caller will fallback on 
`DatumShiftGridGroup.interpolateInCell(…)`
+         * In such case the caller will fallback on 
`GridGroup.interpolateInCell(…)`
          * which perform a more extensive search for the nearest grid.
          */
         final RTreeNode node = RTreeNode.locate(domains, pos);
diff --git 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/j2d/Tile.java
 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/j2d/Tile.java
index adcc833c1c..070745e0bd 100644
--- 
a/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/j2d/Tile.java
+++ 
b/endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/util/j2d/Tile.java
@@ -513,7 +513,7 @@ public class Tile implements Serializable {
      * Intentionally no implementation for `equals()` and `hashCode()`. Tile 
is an "almost immutable" class
      * which can still be modified (only once) by MocaicCalculator, or by read 
operations during `getSize()`
      * or `getRegion()` execution. This causes confusing behavior when used in 
an HashMap. We are better to
-     * rely on system identity. For example, `DatumShiftGridGroup` rely on the 
capability to locate Tiles in
+     * rely on system identity. For example, `GridGroup` relies on the 
capability to locate Tiles in
      * HashMap before and after they have been processed by `TileOrganizer`.
      */
 
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftGridCompressedTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/gridded/CompressedGridTest.java
similarity index 75%
rename from 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftGridCompressedTest.java
rename to 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/gridded/CompressedGridTest.java
index c3ce14c6c9..af22006775 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftGridCompressedTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/gridded/CompressedGridTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.referencing.operation.provider;
+package org.apache.sis.referencing.operation.gridded;
 
 import javax.measure.quantity.Dimensionless;
 import org.opengis.referencing.operation.NoninvertibleTransformException;
@@ -24,16 +24,16 @@ import static org.opengis.test.Assert.assertInstanceOf;
 
 
 /**
- * Tests {@link DatumShiftGridCompressed}. This class creates a grid using 
values computed by an affine transform,
+ * Tests {@link CompressedGrid}. This class creates a grid using values 
computed by an affine transform,
  * and compare values computed by the grid using the affine transform as a 
reference.
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-public final class DatumShiftGridCompressedTest extends DatumShiftGridFileTest 
{
+public final class CompressedGridTest extends LoadedGridTest {
     /**
      * Creates a new test case.
      */
-    public DatumShiftGridCompressedTest() {
+    public CompressedGridTest() {
     }
 
     /**
@@ -44,7 +44,7 @@ public final class DatumShiftGridCompressedTest extends 
DatumShiftGridFileTest {
     @Override
     void init(final double rotation) throws NoninvertibleTransformException {
         super.init(0);      // No rotation in order to have integer values.
-        grid = 
DatumShiftGridCompressed.compress((DatumShiftGridFile.Float<Dimensionless,Dimensionless>)
 grid, null, 0.5);
-        assertInstanceOf("grid", DatumShiftGridCompressed.class, grid);
+        grid = 
CompressedGrid.compress((LoadedGrid.Float<Dimensionless,Dimensionless>) grid, 
null, 0.5);
+        assertInstanceOf("grid", CompressedGrid.class, grid);
     }
 }
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftGridFileTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/gridded/LoadedGridTest.java
similarity index 91%
rename from 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftGridFileTest.java
rename to 
endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/gridded/LoadedGridTest.java
index b0aadb964f..c32aafa913 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/DatumShiftGridFileTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/gridded/LoadedGridTest.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.referencing.operation.provider;
+package org.apache.sis.referencing.operation.gridded;
 
 import java.util.Random;
 import java.awt.geom.Point2D;
@@ -34,12 +34,12 @@ import org.apache.sis.test.DependsOnMethod;
 
 
 /**
- * Tests {@link DatumShiftGridFile}. This class creates a grid using values 
computed by an affine transform,
+ * Tests {@link LoadedGrid}. This class creates a grid using values computed 
by an affine transform,
  * and compare values computed by the grid using the affine transform as a 
reference.
  *
  * @author  Martin Desruisseaux (Geomatys)
  */
-public class DatumShiftGridFileTest extends TestCase {
+public class LoadedGridTest extends TestCase {
     /**
      * Size of the grid created for testing purpose.
      */
@@ -64,12 +64,12 @@ public class DatumShiftGridFileTest extends TestCase {
     /**
      * The grid wrapping computed from affine transform.
      */
-    DatumShiftGridFile<Dimensionless,Dimensionless> grid;
+    LoadedGrid<Dimensionless,Dimensionless> grid;
 
     /**
      * Creates a new test case.
      */
-    public DatumShiftGridFileTest() {
+    public LoadedGridTest() {
     }
 
     /**
@@ -81,7 +81,7 @@ public class DatumShiftGridFileTest extends TestCase {
     void init(final double rotation) throws NoninvertibleTransformException {
         reference = 
AffineTransform.getRotateInstance(StrictMath.toRadians(rotation), WIDTH/2, 
HEIGHT/2);
         reference.scale(2, 5);
-        final DatumShiftGridFile.Float<Dimensionless,Dimensionless> grid = new 
DatumShiftGridFile.Float<>(
+        final LoadedGrid.Float<Dimensionless,Dimensionless> grid = new 
LoadedGrid.Float<>(
                 2, Units.UNITY, Units.UNITY, true, 0, 0, 1, 1, WIDTH, HEIGHT, 
null);
         assertEquals(2, grid.offsets.length);
         final Point2D.Float point = new Point2D.Float();
@@ -102,7 +102,7 @@ public class DatumShiftGridFileTest extends TestCase {
     }
 
     /**
-     * Tests {@link DatumShiftGridFile#interpolateInCell(double, double, 
double[])}.
+     * Tests {@link LoadedGrid#interpolateInCell(double, double, double[])}.
      * This test does not perform interpolations and does not compute 
derivatives.
      *
      * @throws TransformException if an error occurred while transforming a 
coordinates.
@@ -132,7 +132,7 @@ public class DatumShiftGridFileTest extends TestCase {
     }
 
     /**
-     * Tests {@link DatumShiftGridFile#interpolateAt(double...)}.
+     * Tests {@link LoadedGrid#interpolateAt(double...)}.
      * This tests include interpolations.
      *
      * @throws TransformException if an error occurred while transforming a 
coordinates.
@@ -163,7 +163,7 @@ public class DatumShiftGridFileTest extends TestCase {
     }
 
     /**
-     * Tests {@link DatumShiftGridFile#interpolateAt(double...)} with 
opportunistic derivative calculations.
+     * Tests {@link LoadedGrid#interpolateAt(double...)} with opportunistic 
derivative calculations.
      * Since the grid is computed from an affine transform, the derivative 
should be constant everywhere.
      *
      * @throws TransformException if an error occurred while transforming a 
coordinates.
@@ -200,7 +200,7 @@ public class DatumShiftGridFileTest extends TestCase {
     }
 
     /**
-     * Tests {@link DatumShiftGridFile#interpolateAt(double...)} with some 
values outside the grid.
+     * Tests {@link LoadedGrid#interpolateAt(double...)} with some values 
outside the grid.
      * Derivatives outside the grid have different coefficients than 
derivatives inside the grid.
      * This test verifies that methods computing derivatives are 
self-consistent.
      *
@@ -229,7 +229,7 @@ public class DatumShiftGridFileTest extends TestCase {
     }
 
     /**
-     * Verifies that the matrix returned by {@link 
DatumShiftGridFile#derivativeInCell(double, double)}
+     * Verifies that the matrix returned by {@link 
LoadedGrid#derivativeInCell(double, double)}
      * contains coefficients identical to the ones in the given vector.
      */
     private void assertSameDerivative(final int x, final int y, final double[] 
vector) {
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolationTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolationTest.java
index 6395434ac1..d24a15cac0 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolationTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/FranceGeocentricInterpolationTest.java
@@ -25,6 +25,8 @@ import javax.measure.quantity.Length;
 import org.opengis.geometry.Envelope;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.operation.gridded.LoadedGrid;
+import org.apache.sis.referencing.operation.gridded.CompressedGrid;
 
 // Test dependencies
 import org.junit.Test;
@@ -130,7 +132,7 @@ public final class FranceGeocentricInterpolationTest 
extends DatumShiftTestCase
      * Tests a small grid file with interpolations in geocentric coordinates 
as {@code float} values.
      *
      * <p>This method is part of a chain.
-     * The next method is {@link #testGridAsShorts(DatumShiftGridFile)}.</p>
+     * The next method is {@link #testGridAsShorts(LoadedGrid)}.</p>
      *
      * @return the loaded grid with values as {@code float}.
      * @throws URISyntaxException if the URL to the test file is not valid.
@@ -139,11 +141,11 @@ public final class FranceGeocentricInterpolationTest 
extends DatumShiftTestCase
      * @throws TransformException if an error occurred while computing the 
envelope.
      */
     @TestStep
-    private static DatumShiftGridFile<Angle,Length> testGridAsFloats()
+    private static LoadedGrid<Angle,Length> testGridAsFloats()
             throws URISyntaxException, IOException, FactoryException, 
TransformException
     {
         final URI file = getResource(TEST_FILE);
-        final DatumShiftGridFile.Float<Angle,Length> grid;
+        final LoadedGrid.Float<Angle,Length> grid;
         try (BufferedReader in = 
FranceGeocentricInterpolation.Loader.newBufferedReader(file)) {
             grid = FranceGeocentricInterpolation.Loader.load(in, file);
         }
@@ -166,15 +168,15 @@ public final class FranceGeocentricInterpolationTest 
extends DatumShiftTestCase
      * @throws TransformException if an error occurred while computing the 
envelope.
      */
     @TestStep
-    private static DatumShiftGridFile<Angle,Length> 
testGridAsShorts(DatumShiftGridFile<Angle,Length> grid)
+    private static LoadedGrid<Angle,Length> 
testGridAsShorts(LoadedGrid<Angle,Length> grid)
             throws TransformException
     {
-        grid = 
DatumShiftGridCompressed.compress((DatumShiftGridFile.Float<Angle,Length>) 
grid, new double[] {
+        grid = CompressedGrid.compress((LoadedGrid.Float<Angle,Length>) 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);
+        assertInstanceOf("Failed to compress 'float' values into 'short' 
values.", CompressedGrid.class, grid);
         assertEquals("cellPrecision", 0.0005, grid.getCellPrecision(), STRICT);
         assertEquals("getCellMean",  168, grid.getCellMean(0), STRICT);
         assertEquals("getCellMean",   60, grid.getCellMean(1), STRICT);
@@ -188,7 +190,7 @@ public final class FranceGeocentricInterpolationTest 
extends DatumShiftTestCase
      *
      * @throws TransformException if an error occurred while computing the 
envelope.
      */
-    private static void verifyGrid(final DatumShiftGridFile<Angle,Length> 
grid) throws TransformException {
+    private static void verifyGrid(final LoadedGrid<Angle,Length> grid) throws 
TransformException {
         final Envelope envelope = grid.getDomainOfValidity();
         assertEquals("xmin",  2.2, envelope.getMinimum(0), 1E-12);
         assertEquals("xmax",  2.5, envelope.getMaximum(0), 1E-12);
@@ -231,7 +233,7 @@ public final class FranceGeocentricInterpolationTest 
extends DatumShiftTestCase
     @Test
     @DependsOnMethod("testGrid")
     public void testGetOrLoad() throws Exception {
-        final DatumShiftGridFile<Angle,Length> grid = 
FranceGeocentricInterpolation.getOrLoad(
+        final LoadedGrid<Angle,Length> grid = 
FranceGeocentricInterpolation.getOrLoad(
                 getResource(TEST_FILE), new double[] {
                         FranceGeocentricInterpolation.TX,
                         FranceGeocentricInterpolation.TY,
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NADCONTest.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NADCONTest.java
index 8606d18717..374aa14b37 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NADCONTest.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NADCONTest.java
@@ -25,6 +25,8 @@ import java.nio.file.Files;
 import javax.measure.quantity.Angle;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.operation.gridded.LoadedGrid;
+import org.apache.sis.referencing.operation.gridded.GridLoader;
 import org.apache.sis.referencing.operation.matrix.Matrix3;
 import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.geometry.Envelopes;
@@ -87,7 +89,7 @@ public final class NADCONTest extends DatumShiftTestCase {
      * The tolerance when comparing coordinates in degrees.
      * This tolerance is determined by the precision of the tools used for 
computing NAD83 coordinates.
      */
-    public static final double ANGULAR_TOLERANCE = 0.5E-5 / 
DatumShiftGridLoader.DEGREES_TO_SECONDS;
+    public static final double ANGULAR_TOLERANCE = 0.5E-5 / 
GridLoader.DEGREES_TO_SECONDS;
 
     /**
      * Name of the file without extension containing a small extract of the 
NADCON grid.
@@ -134,8 +136,8 @@ public final class NADCONTest extends DatumShiftTestCase {
             final double xmin, final double xmax, final double ymin, final 
double ymax)
             throws Exception
     {
-        final DatumShiftGridFile<Angle,Angle> grid = 
NADCON.getOrLoad(latitudeShifts, longitudeShifts);
-        assertInstanceOf("Should not be compressed.", 
DatumShiftGridFile.Float.class, grid);
+        final LoadedGrid<Angle,Angle> grid = NADCON.getOrLoad(latitudeShifts, 
longitudeShifts);
+        assertInstanceOf("Should not be compressed.", LoadedGrid.Float.class, 
grid);
         assertEquals("coordinateUnit",  Units.DEGREE, 
grid.getCoordinateUnit());
         assertEquals("translationUnit", Units.DEGREE, 
grid.getTranslationUnit());
         assertEquals("translationDimensions", 2, 
grid.getTranslationDimensions());
@@ -170,13 +172,13 @@ public final class NADCONTest extends DatumShiftTestCase {
         final double[] vector   = new double[2];
         grid.getCoordinateToGrid().transform(position, 0, indices, 0, 1);
         grid.interpolateInCell(indices[0], indices[1], vector);
-        vector[0] *= cellSize * DatumShiftGridLoader.DEGREES_TO_SECONDS;
-        vector[1] *= cellSize * DatumShiftGridLoader.DEGREES_TO_SECONDS;
+        vector[0] *= cellSize * GridLoader.DEGREES_TO_SECONDS;
+        vector[1] *= cellSize * GridLoader.DEGREES_TO_SECONDS;
         assertArrayEquals("interpolateInCell", expected, vector, 0.5E-5);
 
         // Same test than above, but let DatumShiftGrid do the conversions for 
us.
-        expected[0] /= DatumShiftGridLoader.DEGREES_TO_SECONDS;
-        expected[1] /= DatumShiftGridLoader.DEGREES_TO_SECONDS;
+        expected[0] /= GridLoader.DEGREES_TO_SECONDS;
+        expected[1] /= GridLoader.DEGREES_TO_SECONDS;
         assertArrayEquals("interpolateAt", expected, 
grid.interpolateAt(position), ANGULAR_TOLERANCE);
         assertSame("Grid should be cached.", grid, 
NADCON.getOrLoad(latitudeShifts, longitudeShifts));
     }
@@ -220,7 +222,7 @@ public final class NADCONTest extends DatumShiftTestCase {
      * @throws TransformException if an error occurred while computing the 
envelope.
      * @throws IOException if an error occurred while writing the test file.
      */
-    public static void writeSubGrid(final DatumShiftGridFile<Angle,Angle> 
grid, final Path file, final int dim,
+    public static void writeSubGrid(final LoadedGrid<Angle,Angle> grid, final 
Path file, final int dim,
             final int gridX, final int gridY, final int nx, final int ny) 
throws IOException, TransformException
     {
         Envelope envelope = new Envelope2D(null, gridX, gridY, nx - 1, ny - 1);
diff --git 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NTv2Test.java
 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NTv2Test.java
index 37dbe253b9..b28c08f035 100644
--- 
a/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NTv2Test.java
+++ 
b/endorsed/src/org.apache.sis.referencing/test/org/apache/sis/referencing/operation/provider/NTv2Test.java
@@ -28,13 +28,15 @@ import java.nio.charset.StandardCharsets;
 import javax.measure.quantity.Angle;
 import org.opengis.geometry.Envelope;
 import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.operation.gridded.LoadedGrid;
+import org.apache.sis.referencing.operation.gridded.GridGroup;
+import static 
org.apache.sis.referencing.operation.gridded.GridLoader.DEGREES_TO_SECONDS;
 import org.apache.sis.referencing.operation.matrix.Matrix3;
 import org.apache.sis.geometry.Envelope2D;
 import org.apache.sis.geometry.Envelopes;
 import org.apache.sis.measure.Units;
 import org.apache.sis.referencing.util.Formulas;
 import org.apache.sis.system.DataDirectory;
-import static 
org.apache.sis.referencing.operation.provider.DatumShiftGridLoader.DEGREES_TO_SECONDS;
 
 // Test dependencies
 import org.junit.Test;
@@ -42,6 +44,7 @@ import static org.junit.Assume.assumeTrue;
 import static org.junit.Assert.*;
 import static org.opengis.test.Assert.assertInstanceOf;
 import org.apache.sis.test.DependsOn;
+import org.apache.sis.referencing.operation.gridded.LoadedGridTest;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import static org.opengis.test.Assert.assertMatrixEquals;
@@ -49,14 +52,14 @@ import static org.opengis.test.Assert.assertMatrixEquals;
 
 /**
  * Tests the {@link NTv2} grid loader.
- * It will also indirectly tests {@link DatumShiftGridGroup} class.
+ * It will also indirectly tests {@link GridGroup} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
  *
  * @see GeocentricTranslationTest#testFranceGeocentricInterpolationPoint()
  * @see 
org.apache.sis.referencing.operation.transform.MolodenskyTransformTest#testFranceGeocentricInterpolationPoint()
  */
-@DependsOn(DatumShiftGridFileTest.class)
+@DependsOn(LoadedGridTest.class)
 public final class NTv2Test extends DatumShiftTestCase {
     /**
      * Name of the file containing a small extract of the "{@code 
NTF_R93.gsb}" file.
@@ -122,8 +125,8 @@ public final class NTv2Test extends DatumShiftTestCase {
             final double ymin, final double ymax) throws Exception
     {
         final double cellSize = 360;
-        final DatumShiftGridFile<Angle,Angle> grid = 
NTv2.getOrLoad(NTv2.class, file, 2);
-        assertInstanceOf("Should not be compressed.", 
DatumShiftGridFile.Float.class, grid);
+        final LoadedGrid<Angle,Angle> grid = NTv2.getOrLoad(NTv2.class, file, 
2);
+        assertInstanceOf("Should not be compressed.", LoadedGrid.Float.class, 
grid);
         assertEquals("coordinateUnit",  Units.ARC_SECOND, 
grid.getCoordinateUnit());
         assertEquals("translationUnit", Units.ARC_SECOND, 
grid.getTranslationUnit());
         assertEquals("translationDimensions", 2,          
grid.getTranslationDimensions());
@@ -187,8 +190,8 @@ public final class NTv2Test extends DatumShiftTestCase {
         assumeTrue(DataDirectory.getenv() != null);
         final URI file = DataDirectory.DATUM_CHANGES.toAbsolutePath(new 
URI(MULTIGRID_TEST_FILE));
         assumeTrue(Files.exists(Path.of(file)));
-        final DatumShiftGridFile<Angle,Angle> grid = 
NTv2.getOrLoad(NTv2.class, file, 2);
-        assertInstanceOf("Should contain many grids.", 
DatumShiftGridGroup.class, grid);
+        final LoadedGrid<Angle,Angle> grid = NTv2.getOrLoad(NTv2.class, file, 
2);
+        assertInstanceOf("Should contain many grids.", GridGroup.class, grid);
         assertEquals("coordinateUnit",  Units.ARC_SECOND, 
grid.getCoordinateUnit());
         assertEquals("translationUnit", Units.ARC_SECOND, 
grid.getTranslationUnit());
         assertEquals("translationDimensions", 2,          
grid.getTranslationDimensions());
@@ -238,7 +241,7 @@ public final class NTv2Test extends DatumShiftTestCase {
         result[1] = position[1] + result[1] * cellSize;
         assertArrayEquals("interpolateInCell", expected, result, 
Formulas.ANGULAR_TOLERANCE * DEGREES_TO_SECONDS);
         /*
-         * Verify that the caching mechanism works for DatumShiftGridGroup too.
+         * Verify that the caching mechanism works for GridGroup too.
          */
         assertSame("Grid should be cached.", grid, NTv2.getOrLoad(NTv2.class, 
file, 2));
     }
@@ -285,7 +288,7 @@ public final class NTv2Test extends DatumShiftTestCase {
      * @throws TransformException if an error occurred while computing the 
envelope.
      * @throws IOException if an error occurred while writing the test file.
      */
-    public static void writeSubGrid(final DatumShiftGridFile<Angle,Angle> 
grid, final Path out,
+    public static void writeSubGrid(final LoadedGrid<Angle,Angle> grid, final 
Path out,
             final int gridX, final int gridY, final int nx, final int ny) 
throws IOException, TransformException
     {
         Envelope envelope = new Envelope2D(null, gridX, gridY, nx - 1, ny - 1);


Reply via email to