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

alexismanin pushed a commit to branch fix/image-tile-matrix-get-tile
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/fix/image-tile-matrix-get-tile 
by this push:
     new ac78d7ec34 test(Storage): add a test that shows a bug in 
ImageTileMatrix when trying to get the resource of a 3D tile
ac78d7ec34 is described below

commit ac78d7ec34c141454c3c3aff8eb5bb8a6e4c0800
Author: Alexis Manin <[email protected]>
AuthorDate: Thu May 7 18:20:32 2026 +0200

    test(Storage): add a test that shows a bug in ImageTileMatrix when trying 
to get the resource of a 3D tile
---
 .../sis/storage/tiling/ImageTileMatrixTest.java    | 188 +++++++++++++++++++++
 1 file changed, 188 insertions(+)

diff --git 
a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/tiling/ImageTileMatrixTest.java
 
b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/tiling/ImageTileMatrixTest.java
new file mode 100644
index 0000000000..372713b087
--- /dev/null
+++ 
b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/tiling/ImageTileMatrixTest.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.tiling;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.util.List;
+import java.util.Optional;
+import org.apache.sis.storage.GridCoverageResource;
+import org.opengis.metadata.spatial.DimensionNameType;
+import org.opengis.util.GenericName;
+import org.apache.sis.coverage.SampleDimension;
+import org.apache.sis.coverage.grid.GridExtent;
+import org.apache.sis.coverage.grid.GridGeometry;
+import org.apache.sis.coverage.grid.PixelInCell;
+import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.util.iso.Names;
+
+// Test dependencies
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.*;
+import org.apache.sis.test.TestCase;
+import org.apache.sis.referencing.crs.HardCodedCRS;
+
+
+/**
+ * Minimal test case for image tile matrices
+ *
+ * @author  Alexis Manin (Geomatys)
+ */
+@SuppressWarnings("exports")
+public final class ImageTileMatrixTest extends TestCase {
+
+    private static final BufferedImage MODEL = new BufferedImage(4, 4, 
BufferedImage.TYPE_BYTE_GRAY);
+    private static final int TILE_WIDTH  = 4;
+    private static final int TILE_HEIGHT = 4;
+    private static final int NUM_COLS    = 3;
+    private static final int NUM_ROWS    = 3;
+    private static final int NUM_SLICES  = 2;
+
+    /**
+     * Test that a tile from a 3D dataset can return its associated resource.
+     * This is an anti-regression test because of a bug encountered while 
fetching tile resource.
+     *
+     * @throws DataStoreException if a data store error occurred.
+     */
+    @Test
+    public void testGetResourceFromTile3D() throws DataStoreException {
+        final var resource = new MockTiledResource();
+        final var tileMatrixSets = resource.getTileMatrixSets();
+        assertFalse(tileMatrixSets.isEmpty());
+        final TileMatrixSet tms = tileMatrixSets.iterator().next();
+        assertFalse(tms.getTileMatrices().isEmpty());
+        final TileMatrix matrix = 
tms.getTileMatrices().values().iterator().next();
+
+        final GridExtent tilingExtent = matrix.getTilingScheme().getExtent();
+        assertEquals(3, tilingExtent.getDimension());
+        final long[] indices = new long[] {
+            tilingExtent.getLow(0),
+            tilingExtent.getLow(1),
+            tilingExtent.getLow(2)
+        };
+
+        final Optional<Tile> optTile = matrix.getTile(indices);
+        assertTrue(optTile.isPresent());
+        final var tile = optTile.get();
+        assertEquals(TileStatus.EXISTS, tile.getStatus());
+        final var tResource = tile.getResource();
+        assertNotNull(tResource);
+        if (!(tResource instanceof GridCoverageResource tileGridResource)) {
+            throw new AssertionError("Tile resource is not a grid resource");
+        }
+        var tileImage = tileGridResource.read(null).render(null);
+        assertEquals(TILE_WIDTH, tileImage.getWidth());
+        assertEquals(TILE_HEIGHT, tileImage.getHeight());
+    }
+
+    /**
+     * A minimal {@link TiledGridCoverageResource} for testing.
+     */
+    private static final class MockTiledResource extends 
TiledGridCoverageResource {
+
+        private final GridGeometry gridGeometry;
+        private final List<SampleDimension> sampleDimensions;
+
+        MockTiledResource() {
+            super(null);
+            final var extent = new GridExtent(
+                    new DimensionNameType[] {
+                        DimensionNameType.COLUMN,
+                        DimensionNameType.ROW,
+                        DimensionNameType.VERTICAL
+                    },
+                    new long[3],
+                    new long[] {
+                        NUM_COLS * TILE_WIDTH  - 1,
+                        NUM_ROWS * TILE_HEIGHT - 1,
+                        NUM_SLICES - 1
+                    },
+                    true);
+
+            final int dimension = 3;
+            final MatrixSIS gridToCRS = Matrices.createIdentity(dimension + 1);
+            gridToCRS.setNumber(0, 0, 0.5);
+            gridToCRS.setNumber(1, 1, 0.5);
+            gridToCRS.setNumber(2, 2, 100);
+            gridGeometry = new GridGeometry(extent, PixelInCell.CELL_CORNER,
+                    MathTransforms.linear(gridToCRS), HardCodedCRS.WGS84_3D);
+
+            sampleDimensions = List.of(new 
SampleDimension.Builder().setName("data").build());
+        }
+
+        @Override
+        public GridGeometry getGridGeometry() {
+            return gridGeometry;
+        }
+
+        @Override
+        public List<SampleDimension> getSampleDimensions() {
+            return sampleDimensions;
+        }
+
+        @Override
+        protected int[] getTileSize() {
+            return new int[] {TILE_WIDTH, TILE_HEIGHT, 1};
+        }
+
+        @Override
+        protected ColorModel getColorModel(int[] bands) {
+            return MODEL.getColorModel();
+        }
+
+        @Override
+        protected SampleModel getSampleModel(int[] bands) {
+            return MODEL.getSampleModel();
+        }
+
+        @Override
+        protected TiledGridCoverage read(Subset subset) {
+            return new MockTiledCoverage(subset);
+        }
+    }
+
+    /**
+     * A minimal {@link TiledGridCoverage} that creates empty rasters on 
demand.
+     */
+    private static final class MockTiledCoverage extends TiledGridCoverage {
+
+        MockTiledCoverage(TiledGridCoverageResource.Subset subset) {
+            super(subset);
+        }
+
+        @Override
+        protected GenericName getIdentifier() {
+            return Names.createLocalName(null, null, "test");
+        }
+
+        @Override
+        protected Raster[] readTiles(TileIterator iterator) {
+            final Raster[] tiles = new Raster[iterator.tileCountInQuery];
+            do {
+                final WritableRaster raster = iterator.createRaster();
+                tiles[iterator.getTileIndexInResultArray()] = raster;
+            } while (iterator.next());
+            return tiles;
+        }
+    }
+}
\ No newline at end of file

Reply via email to