This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit ca6eba4f648ec92a0f0513deb19e4141cf1706e9
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Feb 12 12:46:57 2026 +0100

    Move `TiledGridResource` and `TiledGridCoverage` to public API.
---
 .../org/apache/sis/coverage/grid/GridCoverage.java |  10 +-
 .../sis/storage/geotiff/CompressedSubset.java      |   2 +-
 .../org/apache/sis/storage/geotiff/DataCube.java   |   2 +-
 .../org/apache/sis/storage/geotiff/DataSubset.java |   4 +-
 .../{base => tiling}/TiledDeferredImage.java       |   9 +-
 .../{base => tiling}/TiledGridCoverage.java        | 123 +++++++++++----------
 .../{base => tiling}/TiledGridResource.java        |  31 ++++--
 .../apache/sis/storage/tiling/package-info.java    |  10 +-
 .../apache/sis/storage/geoheif/ImageResource.java  |   4 +-
 .../org/apache/sis/storage/gdal/TiledCoverage.java |   4 +-
 .../org/apache/sis/storage/gdal/TiledResource.java |   2 +-
 11 files changed, 114 insertions(+), 87 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage.java
index e036c2de7f..5f0489bd42 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage.java
@@ -58,15 +58,19 @@ import org.opengis.coverage.CannotEvaluateException;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.6
+ * @version 1.7
  * @since   1.0
  */
 public abstract class GridCoverage extends BandedCoverage {
     /**
      * A constant for making easier to identify codes working on two 
dimensional data.
-     * This is the minimal number of dimension required for {@link 
GridCoverage2D}.
+     * This constant can be used for making easier to identify codes where a 
two-dimensional slice is assumed.
+     *
+     * @see #render(GridExtent)
+     *
+     * @since 1.7
      */
-    static final int BIDIMENSIONAL = 2;
+    protected static final int BIDIMENSIONAL = 2;
 
     /**
      * The processor to use in calls to {@link #convert(RenderedImage, 
DataType, MathTransform1D[], ImageProcessor)}.
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/CompressedSubset.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/CompressedSubset.java
index b8efc5f907..72c93d2e25 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/CompressedSubset.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/CompressedSubset.java
@@ -23,7 +23,7 @@ import java.awt.Point;
 import java.awt.image.Raster;
 import static java.lang.Math.toIntExact;
 import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.base.TiledGridResource;
+import org.apache.sis.storage.tiling.TiledGridResource;
 import org.apache.sis.storage.geotiff.inflater.Inflater;
 import org.apache.sis.image.DataType;
 import org.apache.sis.image.internal.shared.RasterFactory;
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java
index 0b8ea082e4..c5ec2f001e 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java
@@ -32,7 +32,7 @@ import org.apache.sis.storage.geotiff.base.Tags;
 import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.storage.geotiff.base.Predictor;
 import org.apache.sis.storage.geotiff.base.Compression;
-import org.apache.sis.storage.base.TiledGridResource;
+import org.apache.sis.storage.tiling.TiledGridResource;
 import org.apache.sis.storage.base.StoreResource;
 import org.apache.sis.math.Vector;
 
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataSubset.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataSubset.java
index bd70e5380c..943f67d9dd 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataSubset.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataSubset.java
@@ -43,8 +43,8 @@ import org.apache.sis.image.internal.shared.ImageUtilities;
 import org.apache.sis.image.internal.shared.RasterFactory;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreContentException;
-import org.apache.sis.storage.base.TiledGridCoverage;
-import org.apache.sis.storage.base.TiledGridResource;
+import org.apache.sis.storage.tiling.TiledGridCoverage;
+import org.apache.sis.storage.tiling.TiledGridResource;
 import org.apache.sis.storage.geotiff.base.Resources;
 import org.apache.sis.storage.geotiff.reader.ReversedBitsChannel;
 import org.apache.sis.io.stream.Region;
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledDeferredImage.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledDeferredImage.java
similarity index 92%
rename from 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledDeferredImage.java
rename to 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledDeferredImage.java
index d5f803d077..50812101ee 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledDeferredImage.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledDeferredImage.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.storage.base;
+package org.apache.sis.storage.tiling;
 
 import java.util.Map;
 import java.awt.Rectangle;
@@ -53,9 +53,12 @@ final class TiledDeferredImage extends BatchComputedImage {
      * @param imageSize   full image size, after subsampling.
      * @param tileLower   indices of first tile to read, inclusive.
      * @param properties  image properties, or {@code null} if none.
+     * @param iterator    iterator over the coordinates of the tiles.
      */
-    TiledDeferredImage(final int[] imageSize, final int[] tileLower,
-                       final Map<String,Object> properties, final 
TiledGridCoverage.TileIterator iterator)
+    TiledDeferredImage(final int[] imageSize,
+                       final int[] tileLower,
+                       final Map<String,Object> properties,
+                       final TiledGridCoverage.TileIterator iterator)
     {
         super(iterator.getCoverage().model, properties);
         this.width    = imageSize[TiledGridCoverage.X_DIMENSION];
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridCoverage.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridCoverage.java
similarity index 93%
rename from 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridCoverage.java
rename to 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridCoverage.java
index b921826c94..06498ac4d7 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridCoverage.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridCoverage.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.storage.base;
+package org.apache.sis.storage.tiling;
 
 import java.util.Map;
 import java.util.Locale;
@@ -25,6 +25,7 @@ import java.awt.image.DataBuffer;
 import java.awt.image.ColorModel;
 import java.awt.image.SampleModel;
 import java.awt.image.MultiPixelPackedSampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
 import java.awt.image.RenderedImage;
 import java.awt.image.Raster;
 import java.awt.image.WritableRaster;
@@ -41,7 +42,6 @@ import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.DisjointExtentException;
 import org.apache.sis.image.internal.shared.DeferredProperty;
 import org.apache.sis.image.internal.shared.TiledImage;
-import org.apache.sis.storage.tiling.TileMatrixSet;
 import org.apache.sis.storage.internal.Resources;
 import org.apache.sis.util.collection.WeakValueHashMap;
 import org.apache.sis.util.resources.Errors;
@@ -56,18 +56,20 @@ import org.opengis.coordinate.MismatchedDimensionException;
 
 
 /**
- * Base class of grid coverage read from a resource where data are stored in 
tiles.
+ * Base class of grid coverages that are read from resources with data stored 
in tiles.
  * This grid coverage may represent only a subset of the coverage resource.
- * Tiles are read from the storage only when first needed.
+ * Tiles are read from the storage when first needed, then cached using weak 
references.
+ * The reading of tiles is done by the {@link #readTiles(TileIterator)} method,
+ * which must be defined by subclasses.
  *
  * <h2>Cell coordinates</h2>
  * When there is no subsampling, this coverage uses the same cell coordinates 
as the originating resource.
  * When there is a subsampling, cell coordinates in this coverage are divided 
by the subsampling factors.
- * Conversions are done by {@link #coverageToResourceCoordinate(long, int)}.
+ * Conversions can be done by {@link #coverageToResourceCoordinate(long, int)}.
  *
  * <p><b>Design note:</b> {@code TiledGridCoverage} uses the same cell 
coordinates as the originating
  * {@link TiledGridResource} (when no subsampling) because those two classes 
use {@code long} integers.
- * There is no integer overflow to avoid.</p>
+ * There is no integer overflow to avoid, contrarily to tile indices described 
below.</p>
  *
  * <h2>Tile matrix coordinate (<abbr>TMC</abbr>)</h2>
  * In each {@code TiledGridCoverage}, indices of tiles starts at (0, 0, …).
@@ -75,14 +77,10 @@ import org.opengis.coordinate.MismatchedDimensionException;
  * Each {@code TiledGridCoverage} instance uses its own, independent, Tile 
Matrix Coordinates (<abbr>TMC</abbr>).
  *
  * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.7
+ * @since   1.7
  */
 public abstract class TiledGridCoverage extends GridCoverage {
-    /**
-     * Number of dimensions in a rendered image.
-     * Used for identifying codes where a two-dimensional slice is assumed.
-     */
-    protected static final int BIDIMENSIONAL = 2;
-
     /**
      * The dimensions of <var>x</var> and <var>y</var> axes.
      * Static constants for now, may become configurable fields in the future.
@@ -101,7 +99,7 @@ public abstract class TiledGridCoverage extends GridCoverage 
{
      * The read extent is not cropped when reading a tiled image on the 
assumption that
      * tiles are reasonable small, because reading tiles fully makes easier to 
cache them.</p>
      */
-    protected final GridExtent readExtent;
+    private final GridExtent readExtent;
 
     /**
      * Whether to enforce {@link #virtualTileSize} even if the intersection 
with {@link #readExtent} is smaller.
@@ -201,13 +199,13 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
     /**
      * Indices of {@link TiledGridResource} bands which have been retained for
      * inclusion in this {@code TiledGridCoverage}, in strictly increasing 
order.
-     * An "included" band is stored in memory but not necessarily visible to 
the user,
-     * because the {@link SampleModel} can be configured for ignoring some 
bands.
+     * An included band is stored in memory but not necessarily visible to 
users,
+     * depending on how the {@link SampleModel} uses each band.
      * This array is {@code null} if all bands shall be included.
      *
-     * <p>If the user specified bands out of order, the change of band order 
is taken in account
-     * by the sample {@link #model}. This {@code includedBands} array does not 
apply any change
-     * of order for making sequential readings easier.</p>
+     * <p>If the user specified bands out of order, the band reordering is 
applied by the sample {@link #model}.
+     * Changes of band order are not encoded in this {@code includedBands} 
array
+     * (i.e., values are always in strictly increasing order) for making 
sequential reads easier.</p>
      */
     protected final int[] includedBands;
 
@@ -223,9 +221,10 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
     private final WeakValueHashMap<TiledGridResource.CacheKey, Raster> rasters;
 
     /**
-     * The sample model for all rasters. The width and height of this sample 
model are the two first elements
-     * of {@link #virtualTileSize} divided by subsampling and clipped to the 
domain.
-     * If user requested to read only a subset of the bands, then this sample 
model is already the subset.
+     * The sample model for all rasters. The width and height of this sample 
model are computed
+     * from the size of tiles in the resource divided by subsampling and 
clipped to the domain.
+     * The components may be a subset of the bands in the resource if the user 
requested to read
+     * only a subset of those bands.
      *
      * @see TiledGridResource#getSampleModel(int[])
      */
@@ -372,36 +371,38 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
     }
 
     /**
-     * Converts a cell coordinate from this coverage to the {@code 
TiledGridResource} coordinate space.
-     * This method removes the subsampling effect, i.e. returns the coordinate 
that we would have if this
-     * coverage was at full resolution. When there is no subsampling, {@code 
TiledGridCoverage} uses the
-     * same coordinates as the originating {@link TiledGridResource}.
+     * Converts a cell coordinate of this coverage to the {@code 
TiledGridResource} coordinate space.
+     * This method removes the subsampling effect,
+     * i.e. returns the coordinate that we would have if this coverage was at 
full resolution.
+     * The result is the given {@code coordinate} value unchanged when there 
is no subsampling.
      *
      * @param  coordinate  coordinate in this {@code TiledGridCoverage} domain.
      * @param  dimension   the dimension of the coordinate to convert.
-     * @return coordinate in this {@code TiledGridResource} with no 
subsampling applied.
-     * @throws ArithmeticException if the coordinate cannot be represented as 
a long integer.
+     * @return coordinate in the {@code TiledGridResource} domain with no 
subsampling applied.
+     * @throws ArithmeticException if the coordinate cannot be represented as 
a 64 bits integer.
      */
     protected final long coverageToResourceCoordinate(final long coordinate, 
final int dimension) {
         return addExact(multiplyExact(coordinate, subsampling[dimension]), 
subsamplingOffsets[dimension]);
     }
 
     /**
-     * Converts a cell coordinate from {@link TiledGridResource} space to 
{@code TiledGridCoverage} coordinate.
+     * Converts a cell coordinate from the {@code TiledGridResource} to this 
coverage coordinate space.
      * This method is the converse of {@link 
#coverageToResourceCoordinate(long, int)}.
-     * Note that there is a possible accuracy lost.
+     * The result is the given {@code coordinate} value unchanged when there 
is no subsampling.
+     * If there is a subsampling, the returned value is rounded toward 
negative infinity.
      *
      * @param  coordinate  coordinate in the {@code TiledGridResource} domain.
      * @param  dimension   the dimension of the coordinate to convert.
      * @return coordinates in this subsampled {@code TiledGridCoverage} domain.
-     * @throws ArithmeticException if the coordinate cannot be represented as 
a long integer.
+     * @throws ArithmeticException if the coordinate cannot be represented as 
a 64 bits integer.
      */
-    private long resourceToCoverageCoordinate(final long coordinate, final int 
dimension) {
+    protected final long resourceToCoverageCoordinate(final long coordinate, 
final int dimension) {
         return floorDiv(subtractExact(coordinate, 
subsamplingOffsets[dimension]), subsampling[dimension]);
     }
 
     /**
-     * Converts a tile index from the <abbr>TMC</abbr> of this coverage to a 
cell coordinate in the originating resource.
+     * Converts a tile index from the <abbr>TMC</abbr> of this coverage to the
+     * coordinate of the upper-left cell of the tile in the originating 
resource.
      * Note that the computation (like all methods in this class) uses the 
<em>virtual</em> tile size.
      * This is usually the same as the real tile size, but not always.
      *
@@ -409,7 +410,7 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
      * @param  dimension  the dimension of the coordinate to convert.
      * @return cell coordinate of the tile lower coordinate in the originating 
resource.
      */
-    final long coverageTileToResourceCell(final long tileIndex, final int 
dimension) {
+    private long coverageTileToResourceCell(final long tileIndex, final int 
dimension) {
         return multiplyExact(addExact(tileIndex, tmcOfFirstTile[dimension]), 
virtualTileSize[dimension]);
     }
 
@@ -434,13 +435,11 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
      * This value is a power of 2 according {@code 
MultiPixelPackedSampleModel} specification.
      *
      * <h4>Design note</h4>
-     * This is "pixels per element", not "samples per element". It makes a 
difference in the
-     * {@link java.awt.image.SinglePixelPackedSampleModel} case, for which 
this method returns 1
-     * (by contrast a "samples per element" would give a value greater than 1).
-     * But this value can nevertheless be understood as a "samples per 
element" value
-     * where only one band is considered at a time.
+     * This is value is the number of <em>pixels per element</em>, not 
<em>samples per element</em>.
+     * This distinction is important in the case of {@link 
SinglePixelPackedSampleModel}, for which
+     * this method returns 1 (contrarily to the number of samples per element 
which would be greater than 1).
      *
-     * @return number of pixels in a single bank element. Usually 1.
+     * @return number of pixels in a single bank element. This is often 1.
      *
      * @see SampleModel#getSampleSize(int)
      * @see MultiPixelPackedSampleModel#getPixelBitStride()
@@ -493,6 +492,8 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
 
     /**
      * Returns a two-dimensional slice of grid data as a rendered image.
+     * The default implementation creates a {@link TileIterator} over the 
region specified in argument,
+     * then {@linkplain #readTiles(TileIterator) reads the tiles} and stores 
the result in a rendered image.
      *
      * @param  sliceExtent  a subspace of this grid coverage, or {@code null} 
for the whole image.
      * @return the grid slice as a rendered image. Image location is relative 
to {@code sliceExtent}.
@@ -686,6 +687,9 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
 
         /**
          * Returns the cached tile for current <abbr>AOI</abbr> position.
+         * This method returns the value given in a call to the {@link 
#cache(Raster)}
+         * during a previous iteration when the iterator was at the same 
position,
+         * if that raster has not yet been garbage collected.
          *
          * @return cached tile at current <abbr>AOI</abbr> position, or {@code 
null} if none.
          *
@@ -734,13 +738,13 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
 
         /**
          * Stores the given raster in the cache for the current 
<abbr>AOI</abbr> position.
-         * If another raster existed previously in the cache, the old raster 
will be reused if
-         * it has the same size and model, or discarded otherwise. The latter 
case may happen if
-         * {@link #getCachedTile()} determined that a cached raster exists but 
cannot be reused.
+         * If a raster is already in the cache and has the same size and equal 
sample model,
+         * then the given raster is ignored and the existing raster is returned
+         * on the assumption that it has the same content.
          *
          * @param  tile  the raster to cache.
          * @return the cached raster. Should be the given {@code raster} 
instance,
-         *         but this method check for concurrent caching as a paranoiac 
check.
+         *         unless this method is invoked during two concurrent reads 
of the same tile.
          *
          * @see #getCachedTile()
          */
@@ -751,7 +755,7 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
         /**
          * Creates an initially empty raster for the tile at the current 
<abbr>AOI</abbr> position.
          * The sample model is {@link #model} and the minimum <var>x</var> and 
<var>y</var> position
-         * are set the the pixel coordinates in the two first dimensions of 
the <abbr>AOI</abbr>.
+         * are set to the pixel coordinates in two dimensions of the 
<abbr>AOI</abbr>.
          *
          * <p>The raster is <em>not</em> filled with {@link #fillValues}.
          * Filling, if needed, should be done by the caller.</p>
@@ -767,7 +771,7 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
         /**
          * Returns the given raster relocated at the current <abbr>AOI</abbr> 
position.
          * This method does not need to be invoked for tiles created by {@link 
#createRaster()},
-         * but may need to be invoked for tiles created in a different way.
+         * but may need to be invoked for tiles created by a method external 
to this class.
          * If the given raster is already at the current <abbr>AOI</abbr> 
position,
          * then this method returns that raster directly.
          *
@@ -787,9 +791,14 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
 
         /**
          * Returns the location (relative to the cropped tile) of the 
upper-left corner of the uncropped tile.
-         * This value should be present only when reading an image made of a 
single potentially huge tile,
-         * and the {@link #readExtent} has been cropped for avoiding to read 
that huge tile in whole.
-         * This value should always be empty for tiled images, because this 
class usually reads tiles
+         * This value is present under the following conditions:
+         *
+         * <ul>
+         *   <li>Reading an image made of a single potentially huge tile, 
and</li>
+         *   <li>the huge tile is cropped for avoiding to read that tile in 
whole.</li>
+         * </ul>
+         *
+         * This value is empty for tiled images, because this class usually 
reads tiles
          * fully (without cropping) on the assumption that they are reasonably 
small.
          *
          * <p>This value can be <em>added</em> to the coordinates of a point
@@ -881,8 +890,10 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
          * @param  subsampled   whether to return coordinates with subsampling 
applied.
          * @return {@code true} on success, or {@code false} if the tile is 
empty.
          */
-        public boolean getRegionInsideTile(final long[] lower, final long[] 
upper,
-                final long[] subsampling, final boolean subsampled)
+        public boolean getRegionInsideTile(final long[] lower,
+                                           final long[] upper,
+                                           final long[] subsampling,
+                                           final boolean subsampled)
         {
             int dimension = Math.min(lower.length, upper.length);
             final TiledGridCoverage coverage = getCoverage();
@@ -1032,7 +1043,7 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
          * @param  endTile    indices (relative to enclosing {@code 
TiledGridCoverage}) after the bottom-right tile to read.
          * @return a new {@code TileIterator} instance for the specified 
sub-region.
          */
-        public TileIterator subset(final int[] firstTile, final int[] endTile) 
{
+        final TileIterator subset(final int[] firstTile, final int[] endTile) {
             final int[] offset = offsetAOI.clone();
             final int[] lower  = tileLower.clone();
             for (int i = Math.min(firstTile.length, lower.length); --i >= 0;) {
@@ -1068,8 +1079,8 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
          *
          * <p>The returned region is based on the user's request in her/his 
call to {@link #render(GridExtent)},
          * but is not necessarily identical. The render method may have 
expanded or clipped the user's request.
-         * The returned extent may be larger than the actual resource extent 
because {@link #readExtent} size
-         * is rounded to an integer number of chunks.</p>
+         * The returned extent may be larger than the actual resource extent 
because it may be rounded to an
+         * integer number of chunks.</p>
          *
          * @return extent of all tiles to be traversed by this iterator, in 
units of the originating resource.
          */
@@ -1078,6 +1089,7 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
             final long[] lower = new long[dimension];
             final long[] upper = new long[dimension];
             for (int i=0; i<dimension; i++) {
+                // Note: `readExtent` is rounded to an integer number of 
chunks.
                 lower[i] = Math.max(coverageTileToResourceCell(tileLower[i], 
i),   readExtent.getLow(i));
                 upper[i] = Math.min(coverageTileToResourceCell(tileUpper[i], 
i)-1, readExtent.getHigh(i));
             }
@@ -1094,7 +1106,7 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
          * @param  ceil        {@code true} for rounding up, or {@code false} 
for rounding down.
          * @return cell coordinate in the {@link TiledGridResource} coordinate 
system.
          */
-        public long resourceToImage(long coordinate, final int dimension, 
final boolean ceil) {
+        private long resourceToImage(long coordinate, final int dimension, 
final boolean ceil) {
             coordinate = subtractExact(coordinate, 
coverageTileToResourceCell(tileLower[dimension], dimension));
             long s = getSubsampling(dimension);
             coordinate = ceil ? ceilDiv(coordinate, s) : floorDiv(coordinate, 
s);
@@ -1111,7 +1123,7 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
          * @param  dimension   the dimension of the coordinate to convert.
          * @return cell coordinate in the {@link TiledGridResource} coordinate 
system.
          */
-        public long imageToResource(long coordinate, final int dimension) {
+        private long imageToResource(long coordinate, final int dimension) {
             coordinate = subtractExact(coordinate, offsetAOI[dimension]);      
 // (0,0) at image origin instead of AOI.
             coordinate = multiplyExact(coordinate, getSubsampling(dimension)); 
 // Full resolution, like in the resource.
             coordinate = addExact(coordinate, 
coverageTileToResourceCell(tileLower[dimension], dimension));
@@ -1359,7 +1371,6 @@ public abstract class TiledGridCoverage extends 
GridCoverage {
      *         subtypes for Java2D errors.
      *
      * @see TileIterator#createRaster()
-     * @see TileIterator#getTileOrigin(int)
      * @see TileIterator#getTileIndexInResultArray()
      */
     protected abstract Raster[] readTiles(TileIterator iterator) throws 
Exception;
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridResource.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridResource.java
similarity index 97%
rename from 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridResource.java
rename to 
endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridResource.java
index d2442b62cc..12f595eb6c 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridResource.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/TiledGridResource.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.storage.base;
+package org.apache.sis.storage.tiling;
 
 import java.util.List;
 import java.util.Arrays;
@@ -49,15 +49,15 @@ import org.apache.sis.measure.NumberRange;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.internal.shared.Numerics;
 import org.apache.sis.util.collection.WeakValueHashMap;
-import static org.apache.sis.storage.base.TiledGridCoverage.X_DIMENSION;
-import static org.apache.sis.storage.base.TiledGridCoverage.Y_DIMENSION;
+import static org.apache.sis.storage.tiling.TiledGridCoverage.X_DIMENSION;
+import static org.apache.sis.storage.tiling.TiledGridCoverage.Y_DIMENSION;
 
 // Specific to the geoapi-3.1 and geoapi-4.0 branches:
 import org.opengis.coverage.CannotEvaluateException;
 
 
 /**
- * Base class of grid coverage resource storing data in tiles.
+ * Base class of grid coverage resources that store data in tiles.
  * The word "tile" is used for simplicity but can be understood
  * as "chunk" in a <var>n</var>-dimensional generalization.
  * Subclasses need to implement the following methods:
@@ -85,8 +85,16 @@ import org.opengis.coverage.CannotEvaluateException;
  *     }
  *
  * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.7
+ * @since   1.7
  */
 public abstract class TiledGridResource extends AbstractGridCoverageResource {
+    /**
+     * Number of dimensions in a rendered image.
+     * Used for identifying codes where a two-dimensional slice is assumed.
+     */
+    private static final int BIDIMENSIONAL = 2;
+
     /**
      * A key in the {@link #rasters} cache of tiles.
      * Each key shall be unique within its enclosing {@link TiledGridResource} 
instance.
@@ -160,7 +168,7 @@ public abstract class TiledGridResource extends 
AbstractGridCoverageResource {
     /**
      * Returns the size of tiles in this resource.
      * The length of the returned array is the number of dimensions,
-     * which must be {@value TiledGridCoverage#BIDIMENSIONAL} or more.
+     * which must be {@value #BIDIMENSIONAL} or more.
      *
      * @return the size of tiles (in pixels) in this resource.
      * @throws DataStoreException if an error occurred while fetching the tile 
size.
@@ -689,13 +697,14 @@ check:  if (dataType.isInteger()) {
     /**
      * If the loading strategy is to load all tiles at {@code read(…)} time, 
replaces the given coverage
      * by a coverage will all data in memory. This method should be invoked by 
subclasses at the end of
-     * their {@link #read(GridGeometry, int...)} method implementation.
+     * their {@link #read(GridGeometry, int...)} method implementation if the 
tile loading strategy is not
+     * {@link RasterLoadingStrategy#AT_GET_TILE_TIME}.
      *
      * @param  coverage  the {@link TiledGridCoverage} to potentially replace 
by a coverage with preloaded data.
      * @return a coverage with preloaded data, or the given coverage if 
preloading is not enabled.
      * @throws DataStoreException if an error occurred while preloading data.
      */
-    protected final GridCoverage preload(final GridCoverage coverage) throws 
DataStoreException {
+    protected GridCoverage preload(final GridCoverage coverage) throws 
DataStoreException {
         assert Thread.holdsLock(getSynchronizationLock());
         // Note: `loadingStrategy` may still be null if unitialized.
         if (loadingStrategy == null || loadingStrategy == 
RasterLoadingStrategy.AT_READ_TIME) {
@@ -704,7 +713,7 @@ check:  if (dataType.isInteger()) {
              * We apply it anyway in case the coverage geometry is not what 
was announced.
              * This condition is also necessary if `loadingStrategy` has not 
been initialized.
              */
-            if (coverage.getGridGeometry().getDimension() == 
TiledGridCoverage.BIDIMENSIONAL) try {
+            if (coverage.getGridGeometry().getDimension() == BIDIMENSIONAL) 
try {
                 final RenderedImage image = coverage.render(null);
                 return new GridCoverage2D(coverage.getGridGeometry(), 
coverage.getSampleDimensions(), image);
             } catch (RuntimeException e) {
@@ -737,7 +746,7 @@ check:  if (dataType.isInteger()) {
      * Non-immediate loading allows users to specify two-dimensional slices.
      */
     private boolean supportImmediateLoading() throws DataStoreException {
-        return getTileSize().length == TiledGridCoverage.BIDIMENSIONAL;
+        return getTileSize().length == BIDIMENSIONAL;
     }
 
     /**
@@ -747,7 +756,7 @@ check:  if (dataType.isInteger()) {
      * @throws DataStoreException if an error occurred while fetching data 
store configuration.
      */
     @Override
-    public final RasterLoadingStrategy getLoadingStrategy() throws 
DataStoreException {
+    public RasterLoadingStrategy getLoadingStrategy() throws 
DataStoreException {
         synchronized (getSynchronizationLock()) {
             if (loadingStrategy == null) {
                 setLoadingStrategy(supportImmediateLoading());
@@ -765,7 +774,7 @@ check:  if (dataType.isInteger()) {
      * @throws DataStoreException if an error occurred while setting data 
store configuration.
      */
     @Override
-    public final boolean setLoadingStrategy(final RasterLoadingStrategy 
strategy) throws DataStoreException {
+    public boolean setLoadingStrategy(final RasterLoadingStrategy strategy) 
throws DataStoreException {
         synchronized (getSynchronizationLock()) {
             if (strategy == RasterLoadingStrategy.AT_GET_TILE_TIME) {
                 loadingStrategy = strategy;
diff --git 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/package-info.java
 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/package-info.java
index 8d286d322f..d9015c8187 100644
--- 
a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/package-info.java
+++ 
b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/tiling/package-info.java
@@ -19,7 +19,7 @@
 /**
  * Base types for retrieving and saving tiles in resources.
  * A {@link TiledResource} if a resource capable to describe its tiling 
schemes as {@link TileMatrixSet} instances.
- * A {@link TileMatrixSet} is a collection of {@link TileMatrix} instances in 
the same CRS but at different scale levels.
+ * A {@link TileMatrixSet} is a collection of {@link TileMatrix} instances in 
the same <abbr>CRS</abbr> but at different scale levels.
  * A {@link TileMatrix} is a collection of {@link Tile} instances with the 
same size and properties placed on a regular grid with no overlapping.
  * The "tile" word is used because of its wide usage with two-dimensional 
data, but actually this package has no restriction
  * on the number of dimensions and can work with multi-dimensional "tiles" as 
well.
@@ -27,7 +27,7 @@
  * <h2>References</h2>
  * <ul>
  *   <li><a href="https://www.ogc.org/standards/tms";>OGC Two Dimensional Tile 
Matrix Set</a> — the core standard used in this package.</li>
- *   <li><a href="https://www.ogc.org/standards/wmts";>OGC Web Map Tile Service 
(WMTS)</a> — a common use of above standard.</li>
+ *   <li><a href="https://www.ogc.org/standards/wmts";>OGC Web Map Tile Service 
(<abbr>WMTS</abbr>)</a> — a common use of above standard.</li>
  *   <li><a 
href="https://docs.opengeospatial.org/is/17-066r1/17-066r1.html";>OGC 
Geopackage: Extension for Tiled Gridded Coverage Data</a> — another common 
use.</li>
  *   <li><a href="https://docs.ogc.org/per/18-074.html";>OGC Geopackage: 
Extension for vector tiles</a> — experimental work for tiled geometries.</li>
  * </ul>
@@ -40,12 +40,12 @@
  * <a href="https://docs.mapbox.com/mapbox-tiling-service/guides/";>MapBox 
Tiling service</a>.
  *
  *
- * <h2>Relationship with OGC specifications</h2>
+ * <h2>Relationship with <abbr>OGC</abbr> specifications</h2>
  * The {@code TileMatrix} and {@code TileMatrixSet} class names are reused as 
defined by OGC.
  * The "2D" suffix in class names is omitted because this package is fully 
multi-dimensional.
  * The concept of "tiling scheme" is encapsulated in a {@link 
org.apache.sis.coverage.grid.GridGeometry}.
  *
- * <h3>Departures with OGC specifications</h3>
+ * <h3>Departures with <abbr>OGC</abbr> specifications</h3>
  * The OGC {@code TileMatrixLimits} class is replaced by {@link 
org.apache.sis.coverage.grid.GridExtent}.
  * The OGC restriction against negative numbers is removed (Apache SIS accepts 
negative tile indices).
  * The <var>tile span</var> and <var>tile matrix min/max</var> coefficients 
are replaced by a more generic
@@ -68,7 +68,7 @@
  * @author  Johann Sorel (Geomatys)
  * @author  Alexis Manin (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.2
+ * @version 1.7
  * @since   1.2
  */
 package org.apache.sis.storage.tiling;
diff --git 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageResource.java
 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageResource.java
index 32439c4d07..8864b943c1 100644
--- 
a/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageResource.java
+++ 
b/incubator/src/org.apache.sis.storage.geoheif/main/org/apache/sis/storage/geoheif/ImageResource.java
@@ -41,8 +41,8 @@ import org.apache.sis.metadata.iso.DefaultMetadata;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.base.StoreResource;
-import org.apache.sis.storage.base.TiledGridCoverage;
-import org.apache.sis.storage.base.TiledGridResource;
+import org.apache.sis.storage.tiling.TiledGridCoverage;
+import org.apache.sis.storage.tiling.TiledGridResource;
 import org.apache.sis.storage.isobmff.ByteRanges;
 import org.apache.sis.io.stream.ChannelDataInput;
 
diff --git 
a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledCoverage.java
 
b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledCoverage.java
index fa311b9365..59c990133b 100644
--- 
a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledCoverage.java
+++ 
b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledCoverage.java
@@ -25,8 +25,8 @@ import java.lang.foreign.MemorySegment;
 import org.opengis.util.GenericName;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.storage.DataStoreException;
-import org.apache.sis.storage.base.TiledGridCoverage;
-import org.apache.sis.storage.base.TiledGridResource;
+import org.apache.sis.storage.tiling.TiledGridCoverage;
+import org.apache.sis.storage.tiling.TiledGridResource;
 
 // Test dependencies
 import org.apache.sis.image.internal.shared.AssertionMessages;
diff --git 
a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java
 
b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java
index b243fe1a55..2fd8453c29 100644
--- 
a/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java
+++ 
b/optional/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java
@@ -49,7 +49,7 @@ import org.apache.sis.image.internal.shared.ColorModelFactory;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.DataStoreReferencingException;
 import org.apache.sis.storage.base.MetadataBuilder;
-import org.apache.sis.storage.base.TiledGridResource;
+import org.apache.sis.storage.tiling.TiledGridResource;
 import org.apache.sis.system.Configuration;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.resources.Vocabulary;


Reply via email to