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

asf-gitbox-commits 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 3c5edfa91e Make possible to use a pyramided TIFF image even if there 
is no "grid to CRS" transform.
3c5edfa91e is described below

commit 3c5edfa91e8a1868c56ffd5046b38dae346bbee5
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Tue Jul 7 16:25:15 2026 +0200

    Make possible to use a pyramided TIFF image even if there is no "grid to 
CRS" transform.
---
 .../apache/sis/coverage/grid/GridDerivation.java   | 27 ++++++++++++++++++---
 .../org/apache/sis/coverage/grid/GridGeometry.java | 10 --------
 .../sis/coverage/grid/GridDerivationTest.java      | 21 ++++++++++++----
 .../sis/storage/geotiff/ImageFileDirectory.java    | 28 +++++++++++++++++++++-
 4 files changed, 68 insertions(+), 18 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridDerivation.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridDerivation.java
index d330971eff..eb36c478f8 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridDerivation.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridDerivation.java
@@ -741,9 +741,30 @@ public class GridDerivation {
      */
     public GridDerivation subgrid(Envelope areaOfInterest, double... 
resolution) {
         ensureSubgridNotSet();
-        final boolean isEnvelopeOnly = base.isEnvelopeOnly() && (resolution == 
null || resolution.length == 0);
-        MathTransform cornerToCRS = isEnvelopeOnly ? 
MathTransforms.identity(base.envelope.getDimension())
-                                                   : 
base.requireGridToCRS(false);         // Normal case.
+        MathTransform cornerToCRS;
+        final boolean isEnvelopeOnly;
+        /*
+         * Check for the cases where the arguments or grid geometry 
information are incomplete.
+         * It includes the case where the base grid geometry has no "grid to 
CRS" transform but
+         * nevertheless has a resolution, which happens sometime in the 
context of a pyramid.
+         */
+        if (resolution == null || resolution.length == 0) {
+            isEnvelopeOnly = base.gridToCRS == null && base.extent == null && 
base.envelope != null;
+            if (isEnvelopeOnly) {
+                cornerToCRS = 
MathTransforms.identity(base.envelope.getDimension());
+            } else {
+                cornerToCRS = base.requireGridToCRS(false);
+            }
+        } else if (areaOfInterest == null && base.gridToCRS == null && 
base.resolution != null) {
+            final long[] subsampling = new long[base.resolution.length];
+            for (int i = subsampling.length; --i >= 0;) {
+                subsampling[i] = roundSubsampling(resolution[i] / 
base.resolution[i], i);
+            }
+            return subsample(subsampling);
+        } else {
+            isEnvelopeOnly = false;
+            cornerToCRS = base.requireGridToCRS(false);
+        }
         subGridSetter = "subgrid";
         try {
             /*
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
index 3edd2a913b..81eaa83f18 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridGeometry.java
@@ -1604,16 +1604,6 @@ public class GridGeometry implements LenientComparable, 
Serializable {
             && ((bitmask & TEMPORAL_EXTENT)   == 0 || (timeRange().length != 
0));
     }
 
-    /**
-     * Returns {@code true} if this grid geometry contains only an envelope 
with no extent or transform.
-     * Note: if {@link #gridToCRS} is {@code null}, then {@link #cornerToCRS} 
shall also be {@code null}.
-     * The {@link #resolution} array is usually also null, but may be non-null 
if this grid geometry was
-     * {@linkplain #GridGeometry(GridGeometry, GridExtent, MathTransform) 
derived from another grid}.
-     */
-    final boolean isEnvelopeOnly() {
-        return gridToCRS == null && extent == null && envelope != null;
-    }
-
     /**
      * Returns an object that can be used for creating a new grid geometry 
derived from this grid geometry.
      * {@code GridDerivation} does not change the state of this {@code 
GridGeometry} but instead creates
diff --git 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridDerivationTest.java
 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridDerivationTest.java
index 3e3405a4ed..12f7dc725f 100644
--- 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridDerivationTest.java
+++ 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridDerivationTest.java
@@ -628,12 +628,16 @@ public final class GridDerivationTest extends TestCase {
         assertArrayEquals(new double[] {128, 128}, base.getResolution(false));
         assertSame(base, base.derive().subgrid(aoi).build());
 
-        aoi = new GridGeometry(null, PixelInCell.CELL_CORNER, 
MathTransforms.scale(256, 256), null);
+        final double[] resolution = {256, 256};
+        aoi = new GridGeometry(null, PixelInCell.CELL_CORNER, 
MathTransforms.scale(resolution), null);
         GridGeometry derived = base.derive().subgrid(aoi).build();
-        assertArrayEquals(new double[] {256, 256}, 
derived.getResolution(false));
+        assertArrayEquals(resolution, derived.getResolution(false));
         assertExtentEquals(new long[2], new long[] {1023, 398}, 
derived.getExtent());
         assertNull(derived.gridToCRS);
         assertNull(derived.envelope);
+
+        // Alternative way to get the same result.
+        assertEquals(derived, base.derive().subgrid(null, resolution).build());
     }
 
     /**
@@ -1035,7 +1039,7 @@ public final class GridDerivationTest extends TestCase {
         GridGeometry grid1    = new GridGeometry(domain);
         GridGeometry grid2    = new GridGeometry(request);
         GridGeometry subgrid  = grid1.derive().subgrid(grid2).build();
-        assertTrue(subgrid.isEnvelopeOnly());
+        assertEnvelopeOnly(subgrid);
         assertEnvelopeEquals(expected, subgrid.getEnvelope());
         /*
          * Test same envelope but with different axis order. The request uses 
a different CRS,
@@ -1046,10 +1050,19 @@ public final class GridDerivationTest extends TestCase {
         grid2   = new GridGeometry(request);
         subgrid = grid1.derive().subgrid(grid2).build();
         assertSame(HardCodedCRS.WGS84, subgrid.getCoordinateReferenceSystem());
-        assertTrue(subgrid.isEnvelopeOnly());
+        assertEnvelopeOnly(subgrid);
         assertEnvelopeEquals(expected, subgrid.getEnvelope());
     }
 
+    /**
+     * Asserts that the given grid geometry contains only an envelope, without 
extent.
+     */
+    private static void assertEnvelopeOnly(final GridGeometry subgrid) {
+        assertNull(subgrid.gridToCRS);
+        assertNull(subgrid.extent);
+        assertNotNull(subgrid.envelope);
+    }
+
     /**
      * Tests {@link GridDerivation#margin(int...)} when no other operation is 
requested.
      */
diff --git 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
index c5122cc4e5..a5647855a6 100644
--- 
a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
+++ 
b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/ImageFileDirectory.java
@@ -1499,6 +1499,9 @@ final class ImageFileDirectory extends DataCube {
                     domain = reader.store.customizer.customize(source, domain);
                 }
                 gridGeometry = domain;
+                if (overviews != null) {
+                    ensureResolutionExists();
+                }
             }
             return domain;
         }
@@ -2030,9 +2033,32 @@ final class ImageFileDirectory extends DataCube {
      * Sets a list of overviews from coarsest resolution (the overview) to 
finest resolution.
      * The full-resolution image shall be {@code this} and shall not be 
included in the given list.
      */
-    final void setOverviews(final List<ImageFileDirectory> images) {
+    final void setOverviews(final List<ImageFileDirectory> images) throws 
DataStoreException {
         if (!images.isEmpty()) {
             overviews = new Overviews(images);
+            if (gridGeometry != null) {
+                ensureResolutionExists();
+            }
+        }
+    }
+
+    /**
+     * Ensures that the grid geometry declares a resolution.
+     * This method should be invoked only when {@link #gridGeometry} 
<strong>and</strong>
+     * {@link #overviews} are non-null, i.e. when we determined that a pyramid 
exists.
+     * The pyramid system of Apache <abbr>SIS</abbr> needs a resolution in all 
levels.
+     * Therefore, if the base level has no resolution, we need to add an 
arbitrary one.
+     * A resolution is missing when there is no "grid to <abbr>CRS</abbr>" 
transform.
+     * Arbitrary resolution values are okay when there is no <abbr>CRS</abbr>.
+     * The arbitrary value is 1, which means that resolutions are in units of 
pixels
+     * of the base level.
+     */
+    private void ensureResolutionExists() throws DataStoreException {
+        if (!gridGeometry.isDefined(GridGeometry.RESOLUTION) && 
!gridGeometry.isDefined(GridGeometry.CRS)) try {
+            gridGeometry = new GridGeometry(gridGeometry, 
gridGeometry.getExtent(),
+                            
MathTransforms.identity(gridGeometry.getDimension()));
+        } catch (TransformException e) {
+            throw new DataStoreReferencingException(e);     // Should never 
happen.
         }
     }
 

Reply via email to