You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2026/02/11 17:37:48 UTC

(sis) branch geoapi-4.0 updated (363c87b822 -> 9cb97c64c3)

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

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


    from 363c87b822 Adjustment in warning or error messages produced by the GIMI reader.
     new a42f8a7502 Safety against a possible integer overflow. Safety against precision loss.
     new 9cb97c64c3 Add a `GridExtent.reshape(long[])` method and use that for simplifying some code. Minor opportunistic reformating.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/sis/coverage/grid/GridExtent.java   | 61 ++++++++++++++++------
 .../apache/sis/coverage/grid/GridExtentTest.java   | 10 +++-
 .../sis/storage/geotiff/ImageFileDirectory.java    |  5 +-
 .../org/apache/sis/io/stream/ChannelDataInput.java |  2 +-
 .../sis/storage/UnsupportedQueryException.java     |  1 +
 .../sis/storage/aggregate/GridSliceLocator.java    |  5 +-
 .../apache/sis/storage/base/TiledGridCoverage.java |  5 +-
 .../org/apache/sis/storage/CoverageQueryTest.java  |  8 ++-
 .../storage/MemoryGridCoverageResourceTest.java    |  6 ++-
 .../sis/storage/test/CoverageReadConsistency.java  |  2 +-
 .../main/org/apache/sis/util/ArgumentChecks.java   | 26 ++++++++-
 .../apache/sis/util/internal/shared/Numerics.java  |  4 +-
 .../main/org/apache/sis/gui/map/MapCanvas.java     |  6 ++-
 13 files changed, 101 insertions(+), 40 deletions(-)


(sis) 01/02: Safety against a possible integer overflow. Safety against precision loss.

Posted by de...@apache.org.
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 a42f8a7502954a67b8fa69f109494cabf0012817
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Feb 6 12:03:48 2026 +0100

    Safety against a possible integer overflow.
    Safety against precision loss.
---
 .../main/org/apache/sis/io/stream/ChannelDataInput.java               | 2 +-
 .../main/org/apache/sis/util/internal/shared/Numerics.java            | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java
index e2e8ed9dec..bb819a57e4 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/io/stream/ChannelDataInput.java
@@ -703,7 +703,7 @@ public class ChannelDataInput extends ChannelData implements DataInput {
         @Override
         void readFully(Buffer view, int offset, int length) throws IOException {
             final int dataSizeShift = dataSizeShift();
-            ensureBufferContains(Math.min(length << dataSizeShift, buffer.capacity()));
+            ensureBufferContains((int) Math.min(((long) length) << dataSizeShift, buffer.capacity()));
             if (view == null) {
                 view = createView();                                    // Must be after ensureBufferContains(int).
             } else {
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/internal/shared/Numerics.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/internal/shared/Numerics.java
index a7bdbc308f..2a584b08d5 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/internal/shared/Numerics.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/internal/shared/Numerics.java
@@ -313,7 +313,7 @@ public final class Numerics {
 
     /**
      * Returns the given fraction as a {@link Fraction} instance if possible,
-     * or as a {@link Double} approximation otherwise.
+     * or as a {@link DoubleDouble} approximation otherwise.
      *
      * @param  numerator    numerator of the fraction to return.
      * @param  denominator  denominator of the fraction to return.
@@ -323,7 +323,7 @@ public final class Numerics {
         try {
             return Fraction.valueOf(numerator, denominator);
         } catch (ArithmeticException e) {
-            return numerator / (double) denominator;
+            return DoubleDouble.of(numerator).divide(DoubleDouble.of(denominator));
         }
     }
 


(sis) 02/02: Add a `GridExtent.reshape(long[])` method and use that for simplifying some code. Minor opportunistic reformating.

Posted by de...@apache.org.
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 9cb97c64c3e89899bef6299568ad5f1b2a33ec5f
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Wed Feb 11 18:33:20 2026 +0100

    Add a `GridExtent.reshape(long[])` method and use that for simplifying some code.
    Minor opportunistic reformating.
---
 .../org/apache/sis/coverage/grid/GridExtent.java   | 61 ++++++++++++++++------
 .../apache/sis/coverage/grid/GridExtentTest.java   | 10 +++-
 .../sis/storage/geotiff/ImageFileDirectory.java    |  5 +-
 .../sis/storage/UnsupportedQueryException.java     |  1 +
 .../sis/storage/aggregate/GridSliceLocator.java    |  5 +-
 .../apache/sis/storage/base/TiledGridCoverage.java |  5 +-
 .../org/apache/sis/storage/CoverageQueryTest.java  |  8 ++-
 .../storage/MemoryGridCoverageResourceTest.java    |  6 ++-
 .../sis/storage/test/CoverageReadConsistency.java  |  2 +-
 .../main/org/apache/sis/util/ArgumentChecks.java   | 26 ++++++++-
 .../main/org/apache/sis/gui/map/MapCanvas.java     |  6 ++-
 11 files changed, 98 insertions(+), 37 deletions(-)

diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtent.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtent.java
index 07d68fc690..e7c887de45 100644
--- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtent.java
+++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/grid/GridExtent.java
@@ -92,7 +92,7 @@ import org.opengis.coverage.grid.GridCoordinates;
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Alexis Manin (Geomatys)
  * @author  Johann Sorel (Geomatys)
- * @version 1.5
+ * @version 1.7
  * @since   1.0
  */
 public class GridExtent implements GridEnvelope, LenientComparable, Serializable {
@@ -355,28 +355,33 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable
      *
      * @see #getLow()
      * @see #getHigh()
-     * @see #insertDimension(int, DimensionNameType, long, long, boolean)
+     * @see #reshape(long[], long[], boolean)
      */
     public GridExtent(final DimensionNameType[] axisTypes, final long[] low, final long[] high, final boolean isHighIncluded) {
-        final int dimension = high.length;
-        if (low != null && low.length != dimension) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.MismatchedDimension_2, low.length, dimension));
-        }
-        if (axisTypes != null && axisTypes.length != dimension) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.MismatchedArrayLengths));
-        }
-        coordinates = allocate(dimension);
+        ArgumentChecks.ensureNonNull("high", high);
+        coordinates = pack(axisTypes != null ? axisTypes.length : high.length, low, high, isHighIncluded);
+        types = validateAxisTypes(axisTypes);
+        validateCoordinates();
+    }
+
+    /**
+     * Returns the given coordinates packed in a single array.
+     * This method verifies that the array lengths match the expected number of dimensions.
+     */
+    private static long[] pack(final int dimension, final long[] low, final long[] high, final boolean isHighIncluded) {
+        ArgumentChecks.ensureDimensionMatches("low",  dimension, low);
+        ArgumentChecks.ensureDimensionMatches("high", dimension, high);
+        final long[] coordinates = allocate(dimension);
         if (low != null) {
             System.arraycopy(low, 0, coordinates, 0, dimension);
         }
         System.arraycopy(high, 0, coordinates, dimension, dimension);
         if (!isHighIncluded) {
-            for (int i=dimension; i < coordinates.length; i++) {
+            for (int i = dimension; i < coordinates.length; i++) {
                 coordinates[i] = Math.decrementExact(coordinates[i]);
             }
         }
-        types = validateAxisTypes(axisTypes);
-        validateCoordinates();
+        return coordinates;
     }
 
     /**
@@ -644,8 +649,8 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable
 
     /**
      * Creates a new grid extent with the same axes as the given extent, but different coordinates.
-     * This constructor does not invoke {@link #validateCoordinates()}; we presume that the caller's
-     * computation is correct.
+     * This constructor does not invoke {@link #validateCoordinates()}, instead it presumes that the
+     * caller's computation is correct.
      *
      * @param enclosing    the extent from which to copy axes, or {@code null} if none.
      * @param coordinates  the coordinates. This array is not cloned.
@@ -1644,6 +1649,32 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable
         return Arrays.equals(c, coordinates) ? this : resize;
     }
 
+    /**
+     * Returns an extent with the same number of dimensions and the same axes than this extent,
+     * but different coordinate values.
+     *
+     * @param  low             the valid minimum grid coordinates (always inclusive), or {@code null} for all zeros.
+     * @param  high            the valid maximum grid coordinates, inclusive or exclusive depending on the next argument.
+     * @param  isHighIncluded  {@code true} if the {@code high} values are inclusive, or {@code false} if they are exclusive.
+     * @throws IllegalArgumentException if a coordinate value in the low part is
+     *         greater than the corresponding coordinate value in the high part.
+     * @return a grid extent with the same axes but the given coordinates.
+     *
+     * @see #GridExtent(DimensionNameType[], long[], long[], boolean)
+     *
+     * @since 1.7
+     */
+    public GridExtent reshape(final long[] low, final long[] high, final boolean isHighIncluded) {
+        ArgumentChecks.ensureNonNull("high", high);
+        final long[] copy = pack(getDimension(), low, high, isHighIncluded);
+        if (Arrays.equals(copy, coordinates)) {
+            return this;
+        }
+        final var extent = new GridExtent(this, copy);
+        extent.validateCoordinates();
+        return extent;
+    }
+
     /**
      * Creates a new grid extent subsampled by the given number of cells along each grid dimensions.
      * This method divides {@linkplain #getLow(int) low coordinates} and {@linkplain #getSize(int) grid sizes}
diff --git a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridExtentTest.java b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridExtentTest.java
index f8d5785caf..d80f1bab6a 100644
--- a/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridExtentTest.java
+++ b/endorsed/src/org.apache.sis.feature/test/org/apache/sis/coverage/grid/GridExtentTest.java
@@ -71,8 +71,14 @@ public final class GridExtentTest extends TestCase {
      */
     private static GridExtent create3D() {
         return new GridExtent(
-                new DimensionNameType[] {DimensionNameType.COLUMN, DimensionNameType.ROW, DimensionNameType.TIME},
-                new long[] {100, 200, 40}, new long[] {500, 800, 50}, false);
+                new DimensionNameType[] {
+                    DimensionNameType.COLUMN,
+                    DimensionNameType.ROW,
+                    DimensionNameType.TIME
+                },
+                new long[] {100, 200, 40},
+                new long[] {500, 800, 50},
+                false);
     }
 
     /**
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 f7005e7c37..25570a7b9c 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
@@ -35,7 +35,6 @@ import static javax.imageio.plugins.tiff.GeoTIFFTagSet.*;
 import static javax.imageio.plugins.tiff.BaselineTIFFTagSet.*;
 import org.opengis.metadata.Metadata;
 import org.opengis.metadata.citation.DateType;
-import org.opengis.metadata.spatial.DimensionNameType;
 import org.opengis.util.GenericName;
 import org.opengis.util.NameSpace;
 import org.opengis.util.FactoryException;
@@ -1486,11 +1485,9 @@ final class ImageFileDirectory extends DataCube {
         final GridGeometry geometry = fullResolution.getGridGeometry();
         final GridExtent fullExtent = geometry.getExtent();
         final int dimension = fullExtent.getDimension();
-        final var axisTypes = new DimensionNameType[dimension];
         final var scales    = new double[dimension];
         final var high      = new long[dimension];
         for (int i=0; i<dimension; i++) {
-            axisTypes[i] = fullExtent.getAxisType(i).orElse(null);
             final long size;
             switch (i) {
                 case 0:  size = imageWidth;  break;
@@ -1503,7 +1500,7 @@ final class ImageFileDirectory extends DataCube {
         if (referencing == null) {
             gridGeometry = new GridGeometry(
                     geometry,
-                    new GridExtent(axisTypes, null, high, true),
+                    fullExtent.reshape(null, high, true),
                     MathTransforms.scale(scales));
         }
         if (samplesPerPixel == fullResolution.samplesPerPixel) {
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/UnsupportedQueryException.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/UnsupportedQueryException.java
index b0a5d879ac..1b61b1b438 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/UnsupportedQueryException.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/UnsupportedQueryException.java
@@ -27,6 +27,7 @@ package org.apache.sis.storage;
  *   <li>The query is requesting a property that does not exist in the {@link Resource}.</li>
  *   <li>The values in the {@link DataStore} are unconvertible to some characteristics
  *       (e.g., type or name) requested by the query.</li>
+ *   <li>The query is too large (e.g., overflows the capability of some integer type).</li>
  * </ul>
  *
  * This exception may be thrown when {@link FeatureSet#subset(Query)} is executed,
diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/aggregate/GridSliceLocator.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/aggregate/GridSliceLocator.java
index 5af99db062..6333116a62 100644
--- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/aggregate/GridSliceLocator.java
+++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/aggregate/GridSliceLocator.java
@@ -18,7 +18,6 @@ package org.apache.sis.storage.aggregate;
 
 import java.util.Arrays;
 import org.opengis.util.InternationalString;
-import org.opengis.metadata.spatial.DimensionNameType;
 import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.util.ArraysExt;
@@ -96,11 +95,9 @@ final class GridSliceLocator {
         this.sliceHighs      = new long[selected.length];
         GridExtent aoi = domain.getExtent();
         final int dimension = aoi.getDimension();
-        final var axes = new DimensionNameType[dimension];
         final var low  = new long[dimension];
         final var high = new long[dimension];
         for (int i=0; i<dimension; i++) {
-            axes[i] = aoi.getAxisType(i).orElse(null);
             low [i] = Long.MAX_VALUE;
             high[i] = Long.MIN_VALUE;
         }
@@ -114,7 +111,7 @@ final class GridSliceLocator {
                 high[j] = Math.max(high[j], extent.getHigh(j));
             }
         }
-        if (!aoi.equals(aoi = new GridExtent(axes, low, high, true))) {
+        if (!aoi.equals(aoi = aoi.reshape(low, high, true))) {
             var crs = domain.isDefined(GridGeometry.CRS) ? domain.getCoordinateReferenceSystem() : null;
             domain = new GridGeometry(aoi, GridSlice.CELL_ANCHOR, domain.getGridToCRS(GridSlice.CELL_ANCHOR), crs);
         }
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/base/TiledGridCoverage.java
index 332778096c..b921826c94 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/base/TiledGridCoverage.java
@@ -36,7 +36,6 @@ import static java.lang.Math.decrementExact;
 import static java.lang.Math.toIntExact;
 import static java.lang.Math.floorDiv;
 import org.opengis.util.GenericName;
-import org.opengis.metadata.spatial.DimensionNameType;
 import org.apache.sis.coverage.grid.GridCoverage;
 import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.coverage.grid.DisjointExtentException;
@@ -1076,15 +1075,13 @@ public abstract class TiledGridCoverage extends GridCoverage {
          */
         public GridExtent getFullRegionInResourceCoordinates() {
             final int dimension = tileLower.length;
-            final var    axes  = new DimensionNameType[dimension];
             final long[] lower = new long[dimension];
             final long[] upper = new long[dimension];
             for (int i=0; i<dimension; i++) {
-                axes [i] = readExtent.getAxisType(i).orElse(null);
                 lower[i] = Math.max(coverageTileToResourceCell(tileLower[i], i),   readExtent.getLow(i));
                 upper[i] = Math.min(coverageTileToResourceCell(tileUpper[i], i)-1, readExtent.getHigh(i));
             }
-            return new GridExtent(axes, lower, upper, true);
+            return readExtent.reshape(lower, upper, true);
         }
 
         /**
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/CoverageQueryTest.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/CoverageQueryTest.java
index 3202f5e829..11ea0815e6 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/CoverageQueryTest.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/CoverageQueryTest.java
@@ -37,6 +37,7 @@ import org.apache.sis.referencing.crs.HardCodedCRS;
  *
  * @author  Johann Sorel (Geomatys)
  */
+@SuppressWarnings("exports")
 public final class CoverageQueryTest extends TestCase {
     /**
      * The coordinate reference system used by the tests.
@@ -82,8 +83,11 @@ public final class CoverageQueryTest extends TestCase {
      * Creates an arbitrary grid geometry included inside the {@linkplain #resource} extent.
      */
     private GridGeometry createSubGrid(final int expansion) {
-        final GridExtent extent = new GridExtent(
-                new DimensionNameType[] {DimensionNameType.COLUMN, DimensionNameType.ROW},
+        final var extent = new GridExtent(
+                new DimensionNameType[] {
+                    DimensionNameType.COLUMN,
+                    DimensionNameType.ROW
+                },
                 new long[] { 7 - expansion, 19 - expansion},
                 new long[] {21 + expansion, 27 + expansion}, true);
 
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/MemoryGridCoverageResourceTest.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/MemoryGridCoverageResourceTest.java
index e900922d2f..e80ff9878d 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/MemoryGridCoverageResourceTest.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/MemoryGridCoverageResourceTest.java
@@ -75,9 +75,11 @@ public final class MemoryGridCoverageResourceTest extends TestCase {
      * Creates an arbitrary grid geometry included inside the {@linkplain #resource} extent.
      */
     private GridGeometry createSubGrid() {
-        final var extent = new GridExtent(null,
+        final var extent = new GridExtent(
+                null,
                 new long[] {7, 4},
-                new long[] {WIDTH - 9, HEIGHT - 11}, true);
+                new long[] {WIDTH - 9, HEIGHT - 11},
+                true);
 
         return new GridGeometry(extent, PixelInCell.CELL_CENTER, gridToCRS, crs);
     }
diff --git a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/test/CoverageReadConsistency.java b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/test/CoverageReadConsistency.java
index f44e47ccdf..ae7a4460bd 100644
--- a/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/test/CoverageReadConsistency.java
+++ b/endorsed/src/org.apache.sis.storage/test/org/apache/sis/storage/test/CoverageReadConsistency.java
@@ -319,7 +319,7 @@ public abstract class CoverageReadConsistency<S extends DataStore> extends TestC
                 subsampling[d] += random.nextInt(StrictMath.max(rs / 16, 1));
             }
         }
-        return gg.derive().subgrid(new GridExtent(null, low, high, true), subsampling).build();
+        return gg.derive().subgrid(fullExtent.reshape(low, high, true), subsampling).build();
     }
 
     /**
diff --git a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArgumentChecks.java b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArgumentChecks.java
index d842f5a165..ca28d60e38 100644
--- a/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArgumentChecks.java
+++ b/endorsed/src/org.apache.sis.util/main/org/apache/sis/util/ArgumentChecks.java
@@ -83,7 +83,7 @@ import org.opengis.coverage.grid.GridEnvelope;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @author  Alexis Manin (Geomatys)
- * @version 1.6
+ * @version 1.7
  * @since   0.3
  */
 public final class ArgumentChecks {
@@ -779,6 +779,30 @@ public final class ArgumentChecks {
         }
     }
 
+    /**
+     * Ensures that the given array of indices, if non-null, has the expected number of dimensions
+     * (taken as its length). This method does nothing if the given array is null.
+     *
+     * @param  name      the name of the argument to be checked. Used only if an exception is thrown.
+     * @param  expected  the expected number of dimensions.
+     * @param  indices   the array of indices to check for its number of dimensions, or {@code null}.
+     * @throws MismatchedDimensionException if the given array of indices is non-null and does not have
+     *         the expected number of dimensions (taken as its length).
+     *
+     * @since 1.7
+     */
+    public static void ensureDimensionMatches(final String name, final int expected, final long[] indices)
+            throws MismatchedDimensionException
+    {
+        if (indices != null) {
+            final int dimension = indices.length;
+            if (dimension != expected) {
+                throw new MismatchedDimensionException(Errors.format(
+                        Errors.Keys.MismatchedDimension_3, name, expected, dimension));
+            }
+        }
+    }
+
     /**
      * Ensures that the given vector, if non-null, has the expected number of dimensions
      * (taken as its length). This method does nothing if the given vector is null.
diff --git a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/MapCanvas.java b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/MapCanvas.java
index 10c3de3a84..4f3c69678b 100644
--- a/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/MapCanvas.java
+++ b/optional/src/org.apache.sis.gui/main/org/apache/sis/gui/map/MapCanvas.java
@@ -1195,9 +1195,11 @@ public abstract class MapCanvas extends PlanarCanvas {
                     return;
                 }
                 invalidObjectiveToDisplay = false;
-                final var extent = new GridExtent(null,
+                final var extent = new GridExtent(
+                        null,
                         new long[] {Math.round(target.getMinX()), Math.round(target.getMinY())},
-                        new long[] {Math.round(target.getMaxX()), Math.round(target.getMaxY())}, false);
+                        new long[] {Math.round(target.getMaxX()), Math.round(target.getMaxY())},
+                        false);
                 /*
                  * The main purpose of this block is to find the initial value of the `objectiveToDisplay` transform
                  * (named `crsToDisplay` here). If that value was explicitly specified by a call to `initialize(…)`,