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 bb9c139b68ecaa1cabac920166fb039b494e11ae
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Fri Aug 8 14:49:27 2025 +0200

    Add a `PlanarImage.XY_DIMENSIONS_KEY` property.
    It contains the dimensions selected by `GridCoverage.render(GridExtent)`.
---
 .../apache/sis/coverage/grid/GridCoverage2D.java   |  2 +-
 .../apache/sis/coverage/grid/ImageRenderer.java    | 50 ++++++++++++++++------
 .../main/org/apache/sis/image/BandSelectImage.java | 22 +++++-----
 .../main/org/apache/sis/image/ImageOverlay.java    |  2 +
 .../main/org/apache/sis/image/PlanarImage.java     | 25 ++++++++++-
 .../sis/image/PositionalConsistencyImage.java      |  6 ++-
 .../org/apache/sis/image/SourceAlignedImage.java   |  7 ++-
 .../coverage/grid/ConvertedGridCoverageTest.java   |  9 ++--
 .../sis/coverage/grid/GridCoverage2DTest.java      |  4 +-
 .../org/apache/sis/map/coverage/RenderingData.java | 22 ++++++----
 .../main/org/apache/sis/portrayal/Canvas.java      |  2 +-
 11 files changed, 105 insertions(+), 46 deletions(-)

diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage2D.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage2D.java
index e3bd525acd..86dd521f02 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage2D.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridCoverage2D.java
@@ -191,7 +191,7 @@ public class GridCoverage2D extends GridCoverage {
         final GridExtent extent = gridGeometry.getExtent();
         final int[] imageAxes;
         if (source instanceof GridCoverage2D) {
-            final GridCoverage2D gs = (GridCoverage2D) source;
+            final var gs = (GridCoverage2D) source;
             xDimension     = gs.xDimension;
             yDimension     = gs.yDimension;
             gridToImageX   = gs.gridToImageX;
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/ImageRenderer.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/ImageRenderer.java
index 6a9d10d465..21b99a6306 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/ImageRenderer.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/ImageRenderer.java
@@ -57,6 +57,7 @@ import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.math.Vector;
+import static org.apache.sis.image.PlanarImage.XY_DIMENSIONS_KEY;
 import static org.apache.sis.image.PlanarImage.GRID_GEOMETRY_KEY;
 import static org.apache.sis.image.PlanarImage.SAMPLE_DIMENSIONS_KEY;
 
@@ -416,6 +417,8 @@ public class ImageRenderer {
      *
      * @return indices of <var>x</var> and <var>y</var> coordinate values in a 
grid coordinate tuple.
      *
+     * @see org.apache.sis.image.PlanarImage#XY_DIMENSIONS_KEY
+     *
      * @since 1.3
      */
     public final int[] getXYDimensions() {
@@ -469,6 +472,7 @@ public class ImageRenderer {
      * The properties recognized by current implementation are:
      *
      * <ul>
+     *   <li>{@value org.apache.sis.image.PlanarImage#XY_DIMENSIONS_KEY}.</li>
      *   <li>{@value org.apache.sis.image.PlanarImage#GRID_GEOMETRY_KEY}.</li>
      *   <li>{@value 
org.apache.sis.image.PlanarImage#SAMPLE_DIMENSIONS_KEY}.</li>
      *   <li>Any property added by calls to {@link #addProperty(String, 
Object)}.</li>
@@ -481,6 +485,7 @@ public class ImageRenderer {
      */
     public Object getProperty(final String key) {
         switch (key) {
+            case XY_DIMENSIONS_KEY:     return getXYDimensions();
             case GRID_GEOMETRY_KEY:     return 
getImageGeometry(GridCoverage2D.BIDIMENSIONAL);
             case SAMPLE_DIMENSIONS_KEY: return bands.clone();
         }
@@ -501,12 +506,17 @@ public class ImageRenderer {
     public void addProperty(final String key, final Object value) {
         ArgumentChecks.ensureNonNull("key",   key);
         ArgumentChecks.ensureNonNull("value", value);
-        if (!(GRID_GEOMETRY_KEY.equals(key) || 
SAMPLE_DIMENSIONS_KEY.equals(key))) {
-            if (properties == null) {
-                properties = new Hashtable<>();
-            }
-            if (properties.putIfAbsent(key, value) == null) {
-                return;
+        switch (key) {
+            case XY_DIMENSIONS_KEY:
+            case GRID_GEOMETRY_KEY:
+            case SAMPLE_DIMENSIONS_KEY: break;
+            default: {
+                if (properties == null) {
+                    properties = new Hashtable<>();
+                }
+                if (properties.putIfAbsent(key, value) == null) {
+                    return;
+                }
             }
         }
         throw new 
IllegalArgumentException(Errors.format(Errors.Keys.ElementAlreadyPresent_1, 
key));
@@ -596,7 +606,7 @@ public class ImageRenderer {
      */
     public void setData(final Vector... data) {
         ensureExpectedBandCount(data.length, true);
-        final Buffer[] buffers = new Buffer[data.length];
+        final var buffers = new Buffer[data.length];
         DataType dataType = null;
         for (int i=0; i<data.length; i++) {
             final Vector v = data[i];
@@ -733,6 +743,8 @@ public class ImageRenderer {
      * The image upper-left corner is located at the position given by {@link 
#getBounds()}.
      * The two-dimensional {@linkplain #getImageGeometry(int) image geometry} 
is stored as
      * a property associated to the {@value 
org.apache.sis.image.PlanarImage#GRID_GEOMETRY_KEY} key.
+     * The dimensions of the source grid that are represented in the image are 
associated to the
+     * {@value org.apache.sis.image.PlanarImage#XY_DIMENSIONS_KEY} key.
      * The sample dimensions are stored as a property associated to the
      * {@value org.apache.sis.image.PlanarImage#SAMPLE_DIMENSIONS_KEY} key.
      *
@@ -769,11 +781,12 @@ public class ImageRenderer {
         }
         final WritableRaster wr = (raster instanceof WritableRaster) ? 
(WritableRaster) raster : null;
         if (wr != null && cm != null && (imageX | imageY) == 0) {
-            return new Untiled(cm, wr, properties, imageGeometry, supplier, 
bands);
+            return new Untiled(cm, wr, properties, gridDimensions, 
imageGeometry, supplier, bands);
         }
         if (properties == null) {
             properties = new Hashtable<>();
         }
+        properties.putIfAbsent(XY_DIMENSIONS_KEY, gridDimensions);
         properties.putIfAbsent(GRID_GEOMETRY_KEY, (supplier != null) ? new 
DeferredProperty(supplier) : imageGeometry);
         properties.putIfAbsent(SAMPLE_DIMENSIONS_KEY, bands);
         if (wr != null) {
@@ -791,6 +804,11 @@ public class ImageRenderer {
      * in the form {@code if (image instanceof BufferedImage)}.
      */
     private static final class Untiled extends ObservableImage {
+        /**
+         * The value associated to the {@value 
org.apache.sis.image.PlanarImage#XY_DIMENSIONS_KEY} key.
+         */
+        private final int[] gridDimensions;
+
         /**
          * The value associated to the {@value 
org.apache.sis.image.PlanarImage#GRID_GEOMETRY_KEY} key,
          * or {@code null} if not yet computed.
@@ -813,12 +831,13 @@ public class ImageRenderer {
          */
         @SuppressWarnings("UseOfObsoleteCollectionType")
         Untiled(final ColorModel colors, final WritableRaster raster, final 
Hashtable<?,?> properties,
-                final GridGeometry geometry, final SliceGeometry supplier, 
final SampleDimension[] bands)
+                final int[] gridDimensions, final GridGeometry geometry, final 
SliceGeometry supplier, final SampleDimension[] bands)
         {
             super(colors, raster, false, properties);
-            this.geometry = geometry;
-            this.supplier = supplier;
-            this.bands    = bands;
+            this.gridDimensions = gridDimensions;
+            this.geometry       = geometry;
+            this.supplier       = supplier;
+            this.bands          = bands;
         }
 
         /**
@@ -826,8 +845,10 @@ public class ImageRenderer {
          */
         @Override
         public String[] getPropertyNames() {
-            return ArraysExt.concatenate(super.getPropertyNames(),
-                    new String[] {GRID_GEOMETRY_KEY, SAMPLE_DIMENSIONS_KEY});
+            return ArraysExt.concatenate(super.getPropertyNames(), new 
String[] {
+                    XY_DIMENSIONS_KEY,
+                    GRID_GEOMETRY_KEY,
+                    SAMPLE_DIMENSIONS_KEY});
         }
 
         /**
@@ -842,6 +863,7 @@ public class ImageRenderer {
             switch (key) {
                 default: return super.getProperty(key);
                 case SAMPLE_DIMENSIONS_KEY: return bands.clone();
+                case XY_DIMENSIONS_KEY: return gridDimensions.clone();
                 case GRID_GEOMETRY_KEY: {
                     synchronized (this) {
                         if (geometry == null) {
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandSelectImage.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandSelectImage.java
index e1bcd92e8f..a3357beb0e 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandSelectImage.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/BandSelectImage.java
@@ -46,22 +46,24 @@ import org.apache.sis.image.privy.ObservableImage;
  * @author  Martin Desruisseaux (Geomatys)
  */
 class BandSelectImage extends SourceAlignedImage {
-    /**
-     * Properties to inherit from the source images, after bands reduction if 
applicable.
-     *
-     * @see #getProperty(String)
-     */
-    private static final Set<String> INHERITED_PROPERTIES = Set.of(
-            GRID_GEOMETRY_KEY, POSITIONAL_ACCURACY_KEY,                        
 // Properties to forward as-is.
-            SAMPLE_DIMENSIONS_KEY, SAMPLE_RESOLUTIONS_KEY, STATISTICS_KEY);    
 // Properties to forward after band reduction.
-
     /**
      * Inherited properties that require band reduction.
      * Shall be a subset of {@link #INHERITED_PROPERTIES}.
      * All values must be arrays.
      */
     static final Set<String> REDUCED_PROPERTIES = Set.of(
-            SAMPLE_DIMENSIONS_KEY, SAMPLE_RESOLUTIONS_KEY, STATISTICS_KEY);
+            SAMPLE_DIMENSIONS_KEY,
+            SAMPLE_RESOLUTIONS_KEY,
+            STATISTICS_KEY);
+
+    /**
+     * Properties to inherit from the source images, after bands reduction if 
applicable.
+     *
+     * @see #getProperty(String)
+     */
+    private static final Set<String> INHERITED_PROPERTIES = Set.of(
+            
ArraysExt.concatenate(POSITIONAL_PROPERTIES.toArray(String[]::new),     // 
Properties to forward as-is.
+                                     
REDUCED_PROPERTIES.toArray(String[]::new)));   // Properties to forward after 
band reduction.
 
     /**
      * The selected bands.
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageOverlay.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageOverlay.java
index a81e34a308..a52e06d866 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageOverlay.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/ImageOverlay.java
@@ -237,6 +237,7 @@ final class ImageOverlay extends MultiSourceImage {
                      * we count their occurrences.
                      */
                     switch (name) {
+                        case XY_DIMENSIONS_KEY:
                         case GRID_GEOMETRY_KEY:
                         case SAMPLE_DIMENSIONS_KEY:
                         case POSITIONAL_ACCURACY_KEY: count.put(name, n); 
break;
@@ -267,6 +268,7 @@ final class ImageOverlay extends MultiSourceImage {
     @Override
     public Object getProperty(final String key) {
         switch (key) {
+            case XY_DIMENSIONS_KEY:
             case GRID_GEOMETRY_KEY:       // Fall through
             case SAMPLE_DIMENSIONS_KEY:   return getConstantProperty(key);
             case POSITIONAL_ACCURACY_KEY: return getCombinedProperty(key, 
Quantity[].class,   (q) -> q.clone(),            ImageOverlay::combine, false);
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/PlanarImage.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/PlanarImage.java
index 19c776b1cd..9715ac8945 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/PlanarImage.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/PlanarImage.java
@@ -111,6 +111,23 @@ import org.apache.sis.pending.jdk.JDK18;
  * @since   1.1
  */
 public abstract class PlanarImage implements RenderedImage {
+    /**
+     * Key for a property identifying the grid dimensions that are represented 
as a two-dimensional image.
+     * For an image which is the result of {@linkplain 
org.apache.sis.coverage.grid.GridCoverage#render
+     * rendering a two-dimensional slice} of a multi-dimensional grid 
coverage, this property maps the
+     * <var>x</var> and <var>y</var> axes of this image to the dimensions of 
the grid of the source coverage.
+     *
+     * <p>The property value is an {@code int[]} array of length 2.
+     * The value at array index 0 identifies the source grid dimension of the 
<var>x</var> image axis, which is usually 0.
+     * The value at array index 1 identifies the source grid dimension of the 
<var>y</var> image axis, which is usually 1.</p>
+     *
+     * @see org.apache.sis.coverage.grid.ImageRenderer#getXYDimensions()
+     * @see org.apache.sis.coverage.grid.GridExtent#getSubspaceDimensions(int)
+     *
+     * @since 1.5
+     */
+    public static final String XY_DIMENSIONS_KEY = 
"org.apache.sis.XYDimensions";
+
     /**
      * Key for a property defining a conversion from pixel coordinates to 
"real world" coordinates.
      * Other information include an envelope in "real world" coordinates and 
an estimation of pixel resolution.
@@ -129,8 +146,9 @@ public abstract class PlanarImage implements RenderedImage {
     public static final String GRID_GEOMETRY_KEY = 
"org.apache.sis.GridGeometry";
 
     /**
-     * Estimation of positional accuracy, typically in metres or pixel units. 
Pixel positions may have limited accuracy
-     * in they are computed by {@linkplain 
org.opengis.referencing.operation.Transformation coordinate transformations}.
+     * Key for a property giving an estimation of positional accuracy, 
typically in metres or pixel units.
+     * Pixel positions may have limited accuracy when they are computed by
+     * {@linkplain org.opengis.referencing.operation.Transformation coordinate 
transformations}.
      * The position may also be inaccurate because of approximation applied 
for faster rendering.
      *
      * <p>Values should be instances of <code>{@link 
javax.measure.Quantity[]}</code>. The array length
@@ -249,6 +267,9 @@ public abstract class PlanarImage implements RenderedImage {
      *     <th>Keys</th>
      *     <th>Values</th>
      *   </tr><tr>
+     *     <td>{@value #XY_DIMENSIONS_KEY}</td>
+     *     <td>Indexes of the dimensions of the source grid which are 
represented as a rendered image.</td>
+     *   </tr><tr>
      *     <td>{@value #GRID_GEOMETRY_KEY}</td>
      *     <td>Conversion from pixel coordinates to "real world" 
coordinates.</td>
      *   </tr><tr>
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/PositionalConsistencyImage.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/PositionalConsistencyImage.java
index 34fef74203..dae65538bc 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/PositionalConsistencyImage.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/PositionalConsistencyImage.java
@@ -39,7 +39,10 @@ final class PositionalConsistencyImage extends 
SourceAlignedImage {
      * @see #getPropertyNames()
      */
     private static final Set<String> INHERITED_PROPERTIES = Set.of(
-            GRID_GEOMETRY_KEY, POSITIONAL_ACCURACY_KEY, MASK_KEY);
+            XY_DIMENSIONS_KEY,
+            GRID_GEOMETRY_KEY,
+            POSITIONAL_ACCURACY_KEY,
+            MASK_KEY);
 
     /**
      * Properties added by this image, no matter if present in source image or 
not. Must be consistent with
@@ -83,6 +86,7 @@ final class PositionalConsistencyImage extends 
SourceAlignedImage {
             }
             case POSITIONAL_ACCURACY_KEY:
             case GRID_GEOMETRY_KEY:
+            case XY_DIMENSIONS_KEY:
             case MASK_KEY: {
                 return getSource().getProperty(key);
             }
diff --git 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/SourceAlignedImage.java
 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/SourceAlignedImage.java
index 302a8edfb4..4c8388951d 100644
--- 
a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/SourceAlignedImage.java
+++ 
b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/image/SourceAlignedImage.java
@@ -55,8 +55,11 @@ abstract class SourceAlignedImage extends ComputedImage {
      * May be used as the {@code inherit} argument in {@link 
#filterPropertyNames(String[], Set, String[])}.
      * Inheriting those properties make sense for operations that do not 
change pixel coordinates.
      */
-    static final Set<String> POSITIONAL_PROPERTIES = Set.of(GRID_GEOMETRY_KEY,
-            POSITIONAL_ACCURACY_KEY, 
ResampledImage.POSITIONAL_CONSISTENCY_KEY);
+    static final Set<String> POSITIONAL_PROPERTIES = Set.of(
+            XY_DIMENSIONS_KEY,
+            GRID_GEOMETRY_KEY,
+            POSITIONAL_ACCURACY_KEY,
+            ResampledImage.POSITIONAL_CONSISTENCY_KEY);
 
     /**
      * The color model for this image. May be {@code null}.
diff --git 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/ConvertedGridCoverageTest.java
 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/ConvertedGridCoverageTest.java
index 6c696e8f90..d743e98f4d 100644
--- 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/ConvertedGridCoverageTest.java
+++ 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/ConvertedGridCoverageTest.java
@@ -23,10 +23,10 @@ import org.opengis.referencing.operation.MathTransform1D;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.privy.AffineTransform2D;
 import org.apache.sis.coverage.SampleDimension;
+import org.apache.sis.image.PlanarImage;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.measure.NumberRange;
 import org.apache.sis.measure.Units;
-import static org.apache.sis.image.PlanarImage.SAMPLE_DIMENSIONS_KEY;
 
 // Test dependencies
 import org.junit.jupiter.api.Test;
@@ -82,9 +82,10 @@ public final class ConvertedGridCoverageTest extends 
TestCase {
      */
     private static RenderedImage render(final GridCoverage coverage) {
         final RenderedImage image = coverage.render(null);
-        final Object bands = image.getProperty(SAMPLE_DIMENSIONS_KEY);
-        final var sd = assertInstanceOf(SampleDimension[].class, bands);
-        
assertArrayEquals(coverage.getSampleDimensions().toArray(SampleDimension[]::new),
 sd);
+        
assertArrayEquals(coverage.getSampleDimensions().toArray(SampleDimension[]::new),
+                          assertInstanceOf(SampleDimension[].class, 
image.getProperty(PlanarImage.SAMPLE_DIMENSIONS_KEY)));
+        assertArrayEquals(new int[] {0, 1},
+                          assertInstanceOf(int[].class, 
image.getProperty(PlanarImage.XY_DIMENSIONS_KEY)));
         return image;
     }
 
diff --git 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridCoverage2DTest.java
 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridCoverage2DTest.java
index 4721081340..e975d5361a 100644
--- 
a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridCoverage2DTest.java
+++ 
b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridCoverage2DTest.java
@@ -262,8 +262,8 @@ public class GridCoverage2DTest extends TestCase {
          */
         final var singleRow = new GridExtent(GRID_SIZE, 1).translate(0, 1);
         result = coverage.render(singleRow);
-            assertInstanceOf(BufferedImage.class, result);
-            assertPixelsEqual(coverage.render(null), new Rectangle(0, 1, 
GRID_SIZE, 1), result, null);
+        assertInstanceOf(BufferedImage.class, result);
+        assertPixelsEqual(coverage.render(null), new Rectangle(0, 1, 
GRID_SIZE, 1), result, null);
         /*
          * Column extraction:
          *   - Expected size (1,2) is verified by `assertPixelsEqual(…)`.
diff --git 
a/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/coverage/RenderingData.java
 
b/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/coverage/RenderingData.java
index d2663e45f2..30363b34d3 100644
--- 
a/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/coverage/RenderingData.java
+++ 
b/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/map/coverage/RenderingData.java
@@ -398,17 +398,21 @@ public class RenderingData implements CloneAccess {
         final GridGeometry old = dataGeometry;
         final List<SampleDimension> ranges = coverage.getSampleDimensions();
         final RenderedImage image = coverage.render(sliceExtent);
-        final Object value = image.getProperty(PlanarImage.GRID_GEOMETRY_KEY);
         final GridGeometry domain;
         final int[] xyDims;
-        if (value instanceof GridGeometry) {
-            domain = (GridGeometry) value;
-            xyDims = (sliceExtent == null) ? ArraysExt.range(0, BIDIMENSIONAL)
-                     : sliceExtent.getSubspaceDimensions(BIDIMENSIONAL);
-        } else {
-            var r = new ImageRenderer(coverage, sliceExtent);
-            domain = r.getImageGeometry(BIDIMENSIONAL);
-            xyDims = r.getXYDimensions();
+        {   // For local scope of image properties.
+            Object value = image.getProperty(PlanarImage.GRID_GEOMETRY_KEY);
+            if (value instanceof GridGeometry) {
+                domain = (GridGeometry) value;
+                value  = image.getProperty(PlanarImage.XY_DIMENSIONS_KEY);
+                xyDims = (value instanceof int[]) ? (int[]) value
+                        : (sliceExtent != null) ? 
sliceExtent.getSubspaceDimensions(BIDIMENSIONAL)
+                        : ArraysExt.range(0, BIDIMENSIONAL);
+            } else {
+                var r = new ImageRenderer(coverage, sliceExtent);
+                domain = r.getImageGeometry(BIDIMENSIONAL);
+                xyDims = r.getXYDimensions();
+            }
         }
         setImageSpace(domain, ranges, xyDims);      // Implies `dataGeometry = 
domain`.
         currentSlice = sliceExtent;
diff --git 
a/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/portrayal/Canvas.java
 
b/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/portrayal/Canvas.java
index 363dc5f7ca..9ae081d419 100644
--- 
a/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/portrayal/Canvas.java
+++ 
b/endorsed/src/org.apache.sis.portrayal/main/org/apache/sis/portrayal/Canvas.java
@@ -1055,7 +1055,7 @@ public class Canvas extends Observable implements 
Localized {
              */
             final GridExtent extent = newValue.getExtent();
             final int[] displayDimensions = 
extent.getSubspaceDimensions(getDisplayDimensions());
-            final GeneralEnvelope newBounds = new 
GeneralEnvelope(getDisplayCRS());
+            final var newBounds = new GeneralEnvelope(getDisplayCRS());
             for (int i=0; i<displayDimensions.length; i++) {
                 final int s = displayDimensions[i];
                 newBounds.setRange(i, extent.getLow(s), 
Math.incrementExact(extent.getHigh(s)));

Reply via email to