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

commit 76386d6d1cae39d80f7b0794c33c61ba109b3d8f
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Aug 1 15:41:51 2026 +0200

    Modify `RenderingDataTest` for using the image mock.
---
 .../test/org/apache/sis/image/TiledImageMock.java  |  71 +++++++++++++-
 .../image/internal/shared/ReshapedImageTest.java   |   5 +-
 .../apache/sis/map/coverage/RenderingDataTest.java | 103 +++++++++++----------
 3 files changed, 124 insertions(+), 55 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/TiledImageMock.java
 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/TiledImageMock.java
index 70989ebf3b..36fb739b6f 100644
--- 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/TiledImageMock.java
+++ 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/TiledImageMock.java
@@ -16,10 +16,13 @@
  */
 package org.apache.sis.image;
 
+import java.util.Map;
+import java.util.HashMap;
 import java.util.Arrays;
 import java.util.Random;
 import java.util.stream.Collectors;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.awt.Image;
 import java.awt.Point;
 import java.awt.Transparency;
 import java.awt.color.ColorSpace;
@@ -47,8 +50,7 @@ import static org.junit.jupiter.api.Assertions.*;
 
 /**
  * A rendered image which can contain an arbitrary number of tiles. Tiles are 
stored in memory.
- * We use this class for testing purpose only because tiled images in 
production use need a more
- * sophisticated implementation capable to store some tiles on disk (for 
memory consumption reasons).
+ * We use this class for testing purpose only.
  *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
@@ -142,6 +144,29 @@ public final class TiledImageMock extends PlanarImage 
implements WritableRendere
      */
     private ColorModel colorModel;
 
+    /**
+     * Image properties as a writable map.
+     */
+    private final Map<String, Object> properties;
+
+    /**
+     * Creates a new tiled image starting a (0,0) and storing data as unsigned 
short (16 bits) integers.
+     * This is a convenience constructor for cases simpler than the 
full-featured constructor.
+     *
+     * @param width        number of pixels along X axis in the whole rendered 
image.
+     * @param height       number of pixels along Y axis in the whole rendered 
image.
+     * @param tileWidth    number of pixels along X axis in a single tile of 
the image.
+     * @param tileHeight   number of pixels along Y axis in a single tile of 
the image.
+     * @param numBands     number of bands in the sample model to create.
+     * @param banded       whether to use {@link BandedSampleModel} instead of 
{@link PixelInterleavedSampleModel}.
+     */
+    public TiledImageMock(final int width,     final int height,
+                          final int tileWidth, final int tileHeight,
+                          final int numBands,  final boolean banded)
+    {
+        this(DataBuffer.TYPE_SHORT, numBands, 0, 0, width, height, tileWidth, 
tileHeight, 0, 0, banded);
+    }
+
     /**
      * Creates a new tiled image. Testers should invoke {@link #validate()} 
after construction.
      *
@@ -178,6 +203,7 @@ public final class TiledImageMock extends PlanarImage 
implements WritableRendere
         this.sampleModel = banded ? new BandedSampleModel(dataType, tileWidth, 
tileHeight, numBands) :
                           new PixelInterleavedSampleModel(dataType, tileWidth, 
tileHeight, numBands,
                                  StrictMath.multiplyExact(numBands, 
tileWidth), ArraysExt.range(0, numBands));
+        this.properties  = new HashMap<>();
     }
 
     /**
@@ -210,8 +236,45 @@ public final class TiledImageMock extends PlanarImage 
implements WritableRendere
         return colorModel;
     }
 
-    /** Returns a sample model for data type given to the constructor. */
-    @Override public SampleModel getSampleModel() {return sampleModel;}
+    /**
+     * Returns a sample model for data type given to the constructor.
+     */
+    @Override
+    public SampleModel getSampleModel() {
+        return sampleModel;
+    }
+
+    /**
+     * Returns the name of all properties, or {@code null} if none.
+     *
+     * @return the name of all properties, or {@code null} if none.
+     */
+    @Override
+    public synchronized String[] getPropertyNames() {
+        return properties.isEmpty() ? null : 
properties.keySet().toArray(String[]::new);
+    }
+
+    /**
+     * Returns the value associated to the given property name.
+     *
+     * @param  name  name of the property to fetch.
+     * @return the associated value, or {@link Image#UndefinedProperty} if 
none.
+     */
+    @Override
+    public synchronized Object getProperty(final String name) {
+        return properties.getOrDefault(name, Image.UndefinedProperty);
+    }
+
+    /**
+     * Adds a value associated to the given property name.
+     * Each property name can be associated to a value only once.
+     *
+     * @param  name   name of the property to set.
+     * @param  value  value of the property.
+     */
+    public synchronized void addProperty(final String name, final Object 
value) {
+        assertNull(properties.putIfAbsent(name, value), name);
+    }
 
     /*
      * Information specified to the constructor.
diff --git 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/internal/shared/ReshapedImageTest.java
 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/internal/shared/ReshapedImageTest.java
index 7230007200..1c6201cc16 100644
--- 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/internal/shared/ReshapedImageTest.java
+++ 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/image/internal/shared/ReshapedImageTest.java
@@ -203,11 +203,12 @@ public final class ReshapedImageTest extends TestCase {
     }
 
     /**
-     * Verify a reshaped image created to expose a single tile from a source 
tiled image only serves the requested tile.
+     * Verifies a reshaped image created to expose a single tile
+     * from a source tiled image which only serves the requested tile.
      */
     @Test
     public void testExposeSingleTileFromTiledImage() {
-        var source  = new TiledImageMock(DataBuffer.TYPE_USHORT, 1, 0, 0, 4, 
4, 2, 2, 0, 0, false);
+        var source  = new TiledImageMock(4, 4, 2, 2, 1, false);
         source.validate();
         source.initializeAllTiles(0);
         RenderedImage lastTile = ReshapedImage.singleTile(source, 1, 1);
diff --git 
a/endorsed/src/org.apache.sis.portrayal/test/org/apache/sis/map/coverage/RenderingDataTest.java
 
b/endorsed/src/org.apache.sis.portrayal/test/org/apache/sis/map/coverage/RenderingDataTest.java
index 7cf6ac1de4..7249c74974 100644
--- 
a/endorsed/src/org.apache.sis.portrayal/test/org/apache/sis/map/coverage/RenderingDataTest.java
+++ 
b/endorsed/src/org.apache.sis.portrayal/test/org/apache/sis/map/coverage/RenderingDataTest.java
@@ -16,15 +16,6 @@
  */
 package org.apache.sis.map.coverage;
 
-import java.util.Map;
-import java.util.Arrays;
-import java.awt.Point;
-import java.awt.color.ColorSpace;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.MultiPixelPackedSampleModel;
-import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
@@ -42,7 +33,7 @@ import org.apache.sis.geometry.GeneralDirectPosition;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.image.ErrorHandler;
 import org.apache.sis.image.PlanarImage;
-import org.apache.sis.image.internal.shared.TiledImage;
+import org.apache.sis.image.TiledImageMock;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
@@ -62,25 +53,41 @@ import org.apache.sis.test.TestCase;
  */
 public final class RenderingDataTest extends TestCase {
     /**
-     * Width and height (in pixels) of the rendered image produced in output.
+     * Number of tiles horizontally and vertically.
+     * The number of horizontal tiles is such as a Region Of Interest 
(<abbr>ROI</abbr>) in the middle
+     * and covering half the image width will intersect all 3 tiles, thus 
preventing tile subsetting.
+     * The number of vertical tiles makes such tile subsetting possible on the 
<var>y</var> axis.
+     */
+    private static final int NUM_X_TILES = 3, NUM_Y_TILES = 4;
+
+    /**
+     * Tile size (width and height) in pixels.
      */
-    private static final int RENDERED_SIZE = 8;
+    private static final int TILE_WIDTH = 8, TILE_HEIGHT = 5;
 
     /**
-     * Width and height (in pixels) of the resource used as input.
+     * Image size (width and height) in pixels.
      */
-    private static final int DATA_SIZE = 128;
+    private static final int IMAGE_WIDTH  = NUM_X_TILES * TILE_WIDTH,
+                             IMAGE_HEIGHT = NUM_Y_TILES * TILE_HEIGHT;
 
     /**
-     * Tile height in pixels. There is no tile width as this test does not 
tile the image horizontally.
-     * It is sufficient to focus the test on the tiling in only one axis, 
which is <abbr>y</abbr>.
+     * Width and height (in pixels) of the rendered image produced in output.
      */
-    private static final int TILE_HEIGHT = 16;
+    private static final int RENDERED_WIDTH = 9, RENDERED_HEIGHT = 8;
 
     /**
      * Number of meters per pixel at full resolution.
+     * The <var>y</var> resolution is negative for flipping axis direction.
+     */
+    private static final double X_RESOLUTION = 10, Y_RESOLUTION = -8;
+
+    /**
+     * Envelope extent (width and height) in metres.
+     * The height is intentionally negative.
      */
-    private static final double RESOLUTION = 10;
+    private static final double ENVELOPE_WIDTH  = X_RESOLUTION * IMAGE_WIDTH,
+                                ENVELOPE_HEIGHT = Y_RESOLUTION * IMAGE_HEIGHT;
 
     /**
      * The western-most coordinate of the limit of the resource extent.
@@ -122,22 +129,15 @@ public final class RenderingDataTest extends TestCase {
 
     /**
      * Creates a two-dimensional coverage wrapping a tiled image with an 
<var>UTM</var> projection.
-     * The pixel values do not matter and are all zeros. What matter for this 
test is the tiling.
-     * Therefore, for saving memory and <abbr>CPU</abbr>, all tiles share the 
same data buffer.
      */
     private static GridCoverage createTiledCoverage() {
-        final var gridToCRS  = new AffineTransform2D(RESOLUTION, 0, 0, 
-RESOLUTION, WEST_BOUND, NORTH_BOUND);
+        final var gridToCRS  = new AffineTransform2D(X_RESOLUTION, 0, 0, 
Y_RESOLUTION, WEST_BOUND, NORTH_BOUND);
         final var crs        = CommonCRS.WGS84.universal(45, 3);   // UTM zone 
31N.
-        final var gg         = new GridGeometry(new GridExtent(DATA_SIZE, 
DATA_SIZE), PixelInCell.CELL_CORNER, gridToCRS, crs);
-        final var properties = Map.of(TiledImage.GRID_GEOMETRY_KEY, gg);
-
-        final var colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
-        final var colors     = new ComponentColorModel(colorSpace, false, 
true, ComponentColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
-        final var layout     = new 
MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, DATA_SIZE, TILE_HEIGHT, 1);
-        final var buffer     = new DataBufferByte(DATA_SIZE * TILE_HEIGHT / 
Byte.SIZE, 1);
-        final var tiles      = new Raster[DATA_SIZE / TILE_HEIGHT];
-        Arrays.setAll(tiles, (i) -> Raster.createRaster(layout, buffer, new 
Point(0, i * TILE_HEIGHT)));
-        final var image      = new TiledImage(properties, colors, DATA_SIZE, 
DATA_SIZE, 0, 0, tiles);
+        final var gg         = new GridGeometry(new GridExtent(IMAGE_WIDTH, 
IMAGE_HEIGHT), PixelInCell.CELL_CORNER, gridToCRS, crs);
+        final var image      = new TiledImageMock(IMAGE_WIDTH, IMAGE_HEIGHT, 
TILE_WIDTH, TILE_HEIGHT, 1, true);
+        image.addProperty(TiledImageMock.GRID_GEOMETRY_KEY, gg);
+        image.validate();
+        image.initializeAllTiles(0);
         return new GridCoverage2D(gg, null, image);
     }
 
@@ -194,11 +194,12 @@ public final class RenderingDataTest extends TestCase {
             assertArrayEquals(new int[] {0, 1}, r.getXYDimensions());
         }
         domain = domain.selectDimensions(0, 1);
-        final double scale = ((double) RENDERED_SIZE) / (DATA_SIZE * 
RESOLUTION);
-        final var objectiveToDisplay = new AffineTransform2D(scale, 0, 0, 
-scale, WEST_BOUND * -scale, NORTH_BOUND * scale);
+        final double scaleX = RENDERED_WIDTH  / ENVELOPE_WIDTH;
+        final double scaleY = RENDERED_HEIGHT / ENVELOPE_HEIGHT;    // 
Negative.
+        final var objectiveToDisplay = new AffineTransform2D(scaleX, 0, 0, 
scaleY, WEST_BOUND * -scaleX, NORTH_BOUND * -scaleY);
         final CoordinateReferenceSystem objectiveCRS = 
domain.getCoordinateReferenceSystem();
-        final var poi = new DirectPosition2D(objectiveCRS, WEST_BOUND + 
DATA_SIZE * RESOLUTION / 2,
-                                                          NORTH_BOUND - 
DATA_SIZE * RESOLUTION / 2);
+        final var poi = new DirectPosition2D(objectiveCRS, WEST_BOUND + 
ENVELOPE_WIDTH  / 2,
+                                                          NORTH_BOUND + 
ENVELOPE_HEIGHT / 2);
         /*
          * Render the request which has been prepared above.
          * Get the result, but also the source of the result.
@@ -215,16 +216,20 @@ public final class RenderingDataTest extends TestCase {
          * The source should have the same size as the original data,
          * but translated for having the request at coordinates (0,0).
          */
-        assertEquals(-DATA_SIZE / 4,   source.getMinX());   // Difference 
relative to requested area.
-        assertEquals( DATA_SIZE,       source.getWidth());
-        assertEquals( 0,               source.getMinY());
-        assertEquals( DATA_SIZE / 2,   source.getHeight());
-        assertEquals(0,                 shown.getMinX());
-        assertEquals(RENDERED_SIZE,     shown.getWidth());
-        assertEquals(RENDERED_SIZE,     shown.getTileWidth());
-        assertEquals(RENDERED_SIZE / 4, shown.getMinY());
-        assertEquals(RENDERED_SIZE / 2, shown.getHeight());
-        assertEquals(RENDERED_SIZE / 2, shown.getTileHeight());
+        assertEquals(TILE_WIDTH,         source.getTileWidth());
+        assertEquals(TILE_HEIGHT,        source.getTileHeight());
+        assertEquals(NUM_X_TILES,        source.getNumXTiles());    // 
Couldn't retain only a subset of the tiles.
+        assertEquals(NUM_Y_TILES  / 2,   source.getNumYTiles());    // Could 
retain a subset of the tiles.
+        assertEquals(IMAGE_WIDTH,        source.getWidth());        // Full 
width because tile subsetting couldn't be applied.
+        assertEquals(IMAGE_HEIGHT / 2,   source.getHeight());
+        assertEquals(IMAGE_WIDTH  / -4,  source.getMinX());         // 
Difference relative to requested area.
+        assertEquals(0,                  source.getMinY());         // No 
difference because tile subsetting was applied.
+        assertEquals(0,                   shown.getMinX());
+        assertEquals(RENDERED_HEIGHT / 4, shown.getMinY());
+        assertEquals(RENDERED_WIDTH,      shown.getWidth());
+        assertEquals(RENDERED_WIDTH,      shown.getTileWidth());
+        assertEquals(RENDERED_HEIGHT / 2, shown.getHeight());
+        assertEquals(RENDERED_HEIGHT / 2, shown.getTileHeight());
         /*
          * Verify georeferencing.
          */
@@ -236,8 +241,8 @@ public final class RenderingDataTest extends TestCase {
      */
     private static void verifyLocationOfCenter(final GridGeometry domain) 
throws TransformException {
         final Envelope envelope = domain.getEnvelope();
-        assertEquals( WEST_BOUND + RESOLUTION * (DATA_SIZE / 2), 
envelope.getMedian(0));
-        assertEquals(NORTH_BOUND - RESOLUTION * (DATA_SIZE / 2), 
envelope.getMedian(1));
+        assertEquals( WEST_BOUND + ENVELOPE_WIDTH  / 2, envelope.getMedian(0));
+        assertEquals(NORTH_BOUND + ENVELOPE_HEIGHT / 2, envelope.getMedian(1));
 
         final GridExtent extent = domain.getExtent();
         final var center = new GeneralDirectPosition(extent.getDimension());
@@ -245,7 +250,7 @@ public final class RenderingDataTest extends TestCase {
             center.setCoordinate(i, extent.getMedian(i));
         }
         assertSame(center, 
(domain.getGridToCRS(PixelInCell.CELL_CORNER).transform(center, center)));
-        assertEquals( WEST_BOUND + RESOLUTION * (DATA_SIZE / 2), 
center.getCoordinate(0));
-        assertEquals(NORTH_BOUND - RESOLUTION * (DATA_SIZE / 2), 
center.getCoordinate(1));
+        assertEquals( WEST_BOUND + ENVELOPE_WIDTH  / 2, 
center.getCoordinate(0));
+        assertEquals(NORTH_BOUND + ENVELOPE_HEIGHT / 2, 
center.getCoordinate(1));
     }
 }

Reply via email to