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 9de980b207e6647eb7908327524dc0e8a52ba792 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Thu Sep 12 19:15:16 2024 +0200 Add a `int[] bands` argument to the `TiledGridResource.getSampleModel(…)` and `getColorModel(…)` methods. It allows some data stores to perform a better work than the default band selection mechanism. This is useful with the GDAL model of bands. --- .../sis/coverage/privy/ColorModelFactory.java | 2 +- .../apache/sis/coverage/privy/RangeArgument.java | 2 - .../org/apache/sis/storage/geotiff/DataCube.java | 6 +- .../sis/storage/geotiff/ImageFileDirectory.java | 22 ++-- .../apache/sis/storage/base/TiledGridResource.java | 144 +++++++++++++++++---- .../org/apache/sis/storage/gdal/TiledResource.java | 61 ++++++--- .../storage/gimi/internal/MatrixGridRessource.java | 10 +- 7 files changed, 183 insertions(+), 64 deletions(-) diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelFactory.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelFactory.java index e1a22790e1..2f9750f88b 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelFactory.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/ColorModelFactory.java @@ -505,7 +505,7 @@ public final class ColorModelFactory { cm = new ComponentColorModel(cs, false, true, Transparency.OPAQUE, dataType); // Note: `ComponentColorModel` does not work well with negative values. } else { - final ScaledColorSpace cs = new ScaledColorSpace(numComponents, visibleBand, minimum, maximum); + final var cs = new ScaledColorSpace(numComponents, visibleBand, minimum, maximum); cm = new ScaledColorModel(cs, dataType); } return unique(cm); diff --git a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/RangeArgument.java b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/RangeArgument.java index 3fdd7ba79b..4c152d901c 100644 --- a/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/RangeArgument.java +++ b/endorsed/src/org.apache.sis.feature/main/org/apache/sis/coverage/privy/RangeArgument.java @@ -24,8 +24,6 @@ import java.awt.image.RasterFormatException; import org.opengis.metadata.spatial.DimensionNameType; import org.apache.sis.coverage.SampleDimension; import org.apache.sis.coverage.grid.GridExtent; -import org.apache.sis.coverage.privy.ColorModelFactory; -import org.apache.sis.coverage.privy.SampleModelFactory; import org.apache.sis.feature.internal.Resources; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.ArraysExt; diff --git a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java index bb7ff44fce..2891c0400f 100644 --- a/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java +++ b/endorsed/src/org.apache.sis.storage.geotiff/main/org/apache/sis/storage/geotiff/DataCube.java @@ -121,10 +121,10 @@ abstract class DataCube extends TiledGridResource implements ResourceOnFileSyste /** * Returns the number of components per pixel in the image stored in GeoTIFF file. - * This the same value as the one returned by {@code getSampleModel().getNumBands()}, + * This the same value as the one returned by {@code getSampleModel(null).getNumBands()}, * and is also the size of the collection returned by {@link #getSampleDimensions()}. * - * @see #getSampleModel() + * @see #getSampleModel(int[]) * @see SampleModel#getNumBands() */ abstract int getNumBands(); @@ -201,7 +201,7 @@ abstract class DataCube extends TiledGridResource implements ResourceOnFileSyste * a multiple of 8. */ private boolean canReadDirect(final Subset subset) throws DataStoreException { - final SampleModel model = getSampleModel(); + final SampleModel model = getSampleModel(null); int b = model.getNumBands(); if (b != 1 && !(model instanceof BandedSampleModel)) { // First condition (see Javadoc). if (!subset.isXContiguous()) { // Exception to first consition. 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 723f16516e..582b560f27 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 @@ -425,14 +425,14 @@ final class ImageFileDirectory extends DataCube { * The image sample model, created when first needed. The raster size is the tile size. * Sample models with different size and number of bands can be derived from this model. * - * @see #getSampleModel() + * @see #getSampleModel(int[]) */ private SampleModel sampleModel; /** * The image color model, created when first needed. * - * @see #getColorModel() + * @see #getColorModel(int[]) */ private ColorModel colorModel; @@ -1592,12 +1592,15 @@ final class ImageFileDirectory extends DataCube { * * @see SampleModel#createCompatibleSampleModel(int, int) * @see SampleModel#createSubsetSampleModel(int[]) - * @see #getColorModel() + * @see #getColorModel(int[]) * @see #getTileSize() */ @Override - protected SampleModel getSampleModel() throws DataStoreContentException { + protected SampleModel getSampleModel(final int[] bands) throws DataStoreContentException { assert Thread.holdsLock(getSynchronizationLock()); + if (bands != null) { + return null; // Let `TileGridResource` derive a model itself. + } if (sampleModel == null) { RuntimeException error = null; final DataType type = getDataType(); @@ -1637,7 +1640,7 @@ final class ImageFileDirectory extends DataCube { * The number of dimensions is always 2 for {@code ImageFileDirectory}. * * @see #getExtent() - * @see #getSampleModel() + * @see #getSampleModel(int[]) */ @Override protected int[] getTileSize() { @@ -1690,13 +1693,16 @@ final class ImageFileDirectory extends DataCube { * * @throws DataStoreContentException if the data type is not supported. * - * @see #getSampleModel() + * @see #getSampleModel(int[]) */ @Override - protected ColorModel getColorModel() throws DataStoreContentException { + protected ColorModel getColorModel(final int[] bands) throws DataStoreContentException { assert Thread.holdsLock(getSynchronizationLock()); + if (bands != null) { + return null; // Let `TileGridResource` derive a model itself. + } if (colorModel == null) { - final SampleModel sm = getSampleModel(); + final SampleModel sm = getSampleModel(null); final int dataType = sm.getDataType(); final int visibleBand = 0; // May be configurable in a future version. short missing = 0; // Non-zero if there is a warning about missing information. diff --git a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridResource.java b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridResource.java index 74128e6099..47cf1469e5 100644 --- a/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridResource.java +++ b/endorsed/src/org.apache.sis.storage/main/org/apache/sis/storage/base/TiledGridResource.java @@ -18,6 +18,7 @@ package org.apache.sis.storage.base; import java.util.List; import java.util.Arrays; +import java.util.Objects; import java.awt.image.DataBuffer; import java.awt.image.ColorModel; import java.awt.image.SampleModel; @@ -33,12 +34,14 @@ import org.apache.sis.coverage.grid.GridDerivation; import org.apache.sis.coverage.grid.GridExtent; import org.apache.sis.coverage.grid.GridGeometry; import org.apache.sis.coverage.grid.GridRoundingMode; +import org.apache.sis.coverage.privy.ColorModelFactory; import org.apache.sis.coverage.privy.RangeArgument; import org.apache.sis.storage.Resource; import org.apache.sis.storage.AbstractGridCoverageResource; import org.apache.sis.storage.DataStoreException; import org.apache.sis.storage.RasterLoadingStrategy; import org.apache.sis.storage.event.StoreListeners; +import org.apache.sis.measure.NumberRange; import org.apache.sis.util.ArraysExt; import org.apache.sis.util.collection.WeakValueHashMap; import static org.apache.sis.storage.base.TiledGridCoverage.X_DIMENSION; @@ -52,6 +55,29 @@ import org.opengis.coverage.CannotEvaluateException; * Base class of grid coverage resource storing data in tiles. * The word "tile" is used for simplicity but can be understood * as "chunk" in a <var>n</var>-dimensional generalization. + * Subclasses need to implement the following methods: + * + * <ul> + * <li>{@link #getGridGeometry()}</li> + * <li>{@link #getSampleDimensions()}</li> + * <li>{@link #getTileSize()}</li> + * <li>{@link #getSampleModel(int[])} (optional but recommended)</li> + * <li>{@link #getColorModel(int[])} (optional but recommended)</li> + * <li>{@link #read(GridGeometry, int...)}</li> + * </ul> + * + * The read method can be implemented simply as below: + * + * {@snippet lang="java" : + * @Override + * public GridCoverage read(GridGeometry domain, int... ranges) throws DataStoreException { + * synchronized (getSynchronizationLock()) { + * var subset = new Subset(domain, ranges); + * var result = new MySubclassOfTiledGridCoverage(this, subset); + * return preload(result); + * } + * } + * } * * @author Martin Desruisseaux (Geomatys) */ @@ -141,7 +167,7 @@ public abstract class TiledGridResource extends AbstractGridCoverageResource { /** * Returns the size of tiles in this resource. - * The length of the returned array is the number of dimensions. + * The length of the returned array is the number of dimensions, which must be 2 or more. * * @return the size of tiles (in pixels) in this resource. * @throws DataStoreException if an error occurred while fetching the tile size. @@ -166,7 +192,7 @@ public abstract class TiledGridResource extends AbstractGridCoverageResource { * @throws DataStoreException if an error occurred while fetching the sample model. */ protected int getAtomSize(final int dim) throws DataStoreException { - return (dim == 0) ? TiledGridCoverage.getPixelsPerElement(getSampleModel()) : 1; + return (dim == 0) ? TiledGridCoverage.getPixelsPerElement(getSampleModel(null)) : 1; } /** @@ -176,7 +202,7 @@ public abstract class TiledGridResource extends AbstractGridCoverageResource { * * <ul class="verbose"> * <li>If {@code false}, then {@link TiledGridCoverage#model} will expect the same {@link DataBuffer} - * than the one expected by the {@linkplain #getSampleModel() sample model of this resource}. + * than the one expected by the {@linkplain #getSampleModel(int[]) sample model of this resource}. * All bands will be loaded but the coverage sample model will ignore the bands that were not * enumerated in the {@code range} argument. This strategy is convenient when skipping bands * at reading time is difficult.</li> @@ -197,33 +223,86 @@ public abstract class TiledGridResource extends AbstractGridCoverageResource { * @see RangeArgument#select(SampleModel, boolean) */ protected boolean getDissociableBands() throws DataStoreException { - return getSampleModel() instanceof ComponentSampleModel; + return getSampleModel(null) instanceof ComponentSampleModel; } /** - * Returns the Java2D sample model describing pixel type and layout for all bands. - * The raster size is the {@linkplain #getTileSize() tile size} as stored in the resource. + * Returns the Java2D sample model describing pixel type and layout for the specified bands. + * The raster size shall be the two first dimensions of the {@linkplain #getTileSize() tile size}. + * This is the size of tiles as stored in the resource, i.e. ignoring sub-sampling. + * + * <p>If the {@code bands} argument is {@code null}, then this method <em>shall</em> return the sample model + * for all bands and cannot return {@code null}. If the {@code bands} argument is non-null, then this method + * <em>may</em> compute the sample model for the specified bands, or return {@code null} for instructing the + * caller to derive the sample model from {@code getSampleModel(null)}.</p> * - * <h4>Multi-dimensional data cube</h4> - * If this resource has more than 2 dimensions, then this model is for the two first ones (usually horizontal). - * The images for all levels in additional dimensions shall use the same sample model. + * <h4>Implementation note</h4> + * The default implementation creates a sample model compatible with the {@linkplain #getColorModel(int[]) + * color model} if available, or otherwise defaults to a {@link BandedSampleModel} which stores samples as + * floating point values. This is okay for prototyping, but it is recommended to override this method with + * a simple model that better matches the data. A simple implementation can be as below: * - * <h4>Performance note</h4> - * Implementation should return a cached value, because this method may be invoked many times. + * {@snippet lang="java" : + * private SampleModel sampleModel; * - * @return the sample model for tiles at full resolution with all their bands. + * @Override + * protected SampleModel getSampleModel(int[] bands) throws DataStoreException { + * if (bands != null) { + * return null; + * } + * synchronized (getSynchronizationLock()) { + * if (sampleModel == null) { + * sampleModel = ...; // Compute and cache, because requested many times. + * } + * return sampleModel; + * } + * } + * } + * + * @param bands indices (not necessarily in increasing order) of desired bands, or {@code null} for all bands. + * @return the sample model for tiles at full resolution with the specified bands. + * Shall be non-null if {@code bands} is null (i.e. the caller is requesting the main sample model). * @throws DataStoreException if an error occurred during sample model construction. */ - protected abstract SampleModel getSampleModel() throws DataStoreException; + protected SampleModel getSampleModel(final int[] bands) throws DataStoreException { + final int[] tileSize = getTileSize(); + final int width = tileSize[X_DIMENSION]; + final int height = tileSize[Y_DIMENSION]; + final ColorModel colors = getColorModel(bands); + if (colors != null) { + return colors.createCompatibleSampleModel(width, height); + } + int numBands = (bands != null) ? bands.length : getSampleDimensions().size(); + return new BandedSampleModel(DataBuffer.TYPE_FLOAT, width, height, numBands); + } /** * Returns the Java2D color model for rendering images, or {@code null} if none. - * The color model shall be compatible with the sample model returned by {@link #getSampleModel()}. + * The color model shall be compatible with the sample model returned by {@link #getSampleModel(int[])}. + * + * <p>The default implementation returns a gray scale color model if there is only one band + * to show and the range of the {@linkplain #getSampleDimensions() sample dimension} is known. + * OTherwise, this method returns {@code null}. + * This is okay for prototyping, but it is recommended to override.</p> * - * @return a color model compatible with {@link #getSampleModel()}, or {@code null} if none. + * @param bands indices (not necessarily in increasing order) of desired bands, or {@code null} for all bands. + * @return a color model compatible with {@link #getSampleModel(int[])}, or {@code null} if none. * @throws DataStoreException if an error occurred during color model construction. */ - protected abstract ColorModel getColorModel() throws DataStoreException; + protected ColorModel getColorModel(final int[] bands) throws DataStoreException { + final List<SampleDimension> sd = getSampleDimensions(); + if ((bands != null && bands.length == 1) || sd.size() == 1) { + NumberRange<?> range = sd.get((bands != null) ? bands[0] : 0).getSampleRange().orElse(null); + if (range != null) { + final double min = range.getMinDouble(); + final double max = range.getMaxDouble(); + if (Double.isFinite(min) && Double.isFinite(max)) { + return ColorModelFactory.createGrayScale(DataBuffer.TYPE_FLOAT, 1, 0, min, max); + } + } + } + return null; + } /** * Returns the value to use for filling empty spaces in rasters, @@ -400,30 +479,39 @@ public abstract class TiledGridResource extends AbstractGridCoverageResource { * If user has specified bands in a different order, that change of band order will * be handled by the `SampleModel`, not in `includedBands` array. */ - @SuppressWarnings("LocalVariableHidesMemberVariable") - int[] includedBands = null; + @SuppressWarnings("LocalVariableHidesMemberVariable") int[] includedBands = null; + @SuppressWarnings("LocalVariableHidesMemberVariable") SampleModel modelForBandSubset = null; + @SuppressWarnings("LocalVariableHidesMemberVariable") ColorModel colorsForBandSubset = null; boolean loadAllBands = rangeIndices.isIdentity(); if (!loadAllBands) { bands = Arrays.asList(rangeIndices.select(bands)); loadAllBands = !getDissociableBands(); if (!loadAllBands) { sharedCache = false; - includedBands = new int[rangeIndices.getNumBands()]; - for (int i=0; i<includedBands.length; i++) { - includedBands[i] = rangeIndices.getSourceIndex(i); - } - assert ArraysExt.isSorted(includedBands, true); - if (rangeIndices.hasAllBands) { - assert ArraysExt.isRange(0, includedBands); - includedBands = null; + if (!rangeIndices.hasAllBands) { + includedBands = new int[rangeIndices.getNumBands()]; + for (int i=0; i<includedBands.length; i++) { + includedBands[i] = rangeIndices.getSourceIndex(i); + } + assert ArraysExt.isSorted(includedBands, true); } + // Same as `includedBands`, but in the order requested by the user. + int[] requestedBands = rangeIndices.getSelectedBands(); + modelForBandSubset = getSampleModel(requestedBands); + colorsForBandSubset = getColorModel (requestedBands); } } + if (modelForBandSubset == null) { + modelForBandSubset = rangeIndices.select(getSampleModel(null), loadAllBands); + } + if (colorsForBandSubset == null) { + colorsForBandSubset = rangeIndices.select(getColorModel(null)); + } this.domain = domain; this.ranges = bands; this.includedBands = includedBands; - this.modelForBandSubset = rangeIndices.select(getSampleModel(), loadAllBands); - this.colorsForBandSubset = rangeIndices.select(getColorModel()); + this.modelForBandSubset = Objects.requireNonNull(modelForBandSubset); + this.colorsForBandSubset = colorsForBandSubset; this.fillValue = getFillValue(); /* * All `TiledGridCoverage` instances can share the same cache if they read all tiles fully. diff --git a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java index 5c3a576b84..3025ab2255 100644 --- a/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java +++ b/incubator/src/org.apache.sis.storage.gdal/main/org/apache/sis/storage/gdal/TiledResource.java @@ -18,6 +18,7 @@ package org.apache.sis.storage.gdal; import java.util.Map; import java.util.List; +import java.util.Arrays; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.Optional; @@ -104,17 +105,25 @@ final class TiledResource extends TiledGridResource { private List<SampleDimension> sampleDimensions; /** - * The color model, created when first requested. + * Indices of the {@linkplain #bands} selected for creating {@link #colorModel} and {@link #sampleModel}. + * A null value means that all bands are used. + */ + private int[] selectedBandIndices; + + /** + * The color model for the bands specified by {@link #selectedBandIndices}, created when first requested. + * This model is recreated when {@link #selectedBandIndices} changed. * - * @see #getColorModel() + * @see #getColorModel(int[]) */ private ColorModel colorModel; /** - * The sample model, created when first requested. - * Its size is the tile size with no sub-sampling. + * The sample model for the bands specified by {@link #selectedBandIndices}, created when first requested. + * All sample models shall have the size of the tile size with no sub-sampling. + * This model is recreated when {@link #selectedBandIndices} changed. * - * @see #getSampleModel() + * @see #getSampleModel(int[]) */ private SampleModel sampleModel; @@ -334,14 +343,25 @@ final class TiledResource extends TiledGridResource { /** * Creates the color model and sample model. + * + * @param bandIndices indices of the selected bands. */ - private void createColorAndSampleModel() throws DataStoreException { + private void createColorAndSampleModel(final int[] bandIndices) throws DataStoreException { + final Band[] selectedBands; + if (bandIndices == null) { + selectedBands = bands; + } else { + selectedBands = new Band[bandIndices.length]; + for (int i=0; i<bandIndices.length; i++) { + selectedBands[i] = bands[bandIndices[i]]; + } + } final GDAL gdal = parent.getProvider().GDAL(); int[] palette = null; int paletteIndex = 0; int alpha = -1, red = -1, green = -1, blue = -1, gray = -1; - for (int i=0; i < bands.length; i++) { - final Band band = bands[i]; + for (int i=0; i < selectedBands.length; i++) { + final Band band = selectedBands[i]; switch (band.getColorInterpretation(gdal)) { case ALPHA: if (alpha < 0) alpha = i; break; case RED: if (red < 0) red = i; break; @@ -370,15 +390,15 @@ final class TiledResource extends TiledGridResource { // TODO: needs custom color model if too many bands, or if order is not (A)RGB. } else if (palette != null) { visibleBand = paletteIndex; - colorModel = ColorModelFactory.createIndexColorModel(bands.length, visibleBand, palette, true, -1); + colorModel = ColorModelFactory.createIndexColorModel(selectedBands.length, visibleBand, palette, true, -1); } else { visibleBand = Math.max(gray, 0); - final Band band = bands[visibleBand]; + final Band band = selectedBands[visibleBand]; final double min = band.getValue(gdal.getRasterMinimum, MemorySegment.NULL); final double max = band.getValue(gdal.getRasterMaximum, MemorySegment.NULL); - colorModel = ColorModelFactory.createGrayScale(dataType.imageType, bands.length, visibleBand, min, max); + colorModel = ColorModelFactory.createGrayScale(dataType.imageType, selectedBands.length, visibleBand, min, max); } - sampleModel = new BandedSampleModel(dataType.imageType, width, height, bands.length); + sampleModel = new BandedSampleModel(dataType.imageType, width, height, selectedBands.length); /* * Also compute the fill value here because the current method needs the visible band. * TODO: we should compute the fill value for all bands instead, and move this code to @@ -386,21 +406,22 @@ final class TiledResource extends TiledGridResource { */ try (final Arena arena = Arena.ofConfined()) { final MemorySegment flag = arena.allocate(ValueLayout.JAVA_INT); - final double value = bands[visibleBand].getValue(gdal.getRasterNoDataValue, flag); + final double value = selectedBands[visibleBand].getValue(gdal.getRasterNoDataValue, flag); if (value != 0 && Band.isTrue(flag)) { fillValue = value; } } + selectedBandIndices = bandIndices; } /** * Returns the Java2D color model for rendering images. */ @Override - protected ColorModel getColorModel() throws DataStoreException { + protected ColorModel getColorModel(final int[] bandIndices) throws DataStoreException { synchronized (getSynchronizationLock()) { - if (colorModel == null) { - createColorAndSampleModel(); + if (colorModel == null || !Arrays.equals(bandIndices, selectedBandIndices)) { + createColorAndSampleModel(bandIndices); } return colorModel; } @@ -411,10 +432,10 @@ final class TiledResource extends TiledGridResource { * The raster size is the {@linkplain #getTileSize() tile size} as stored in the resource. */ @Override - protected SampleModel getSampleModel() throws DataStoreException { + protected SampleModel getSampleModel(final int[] bandIndices) throws DataStoreException { synchronized (getSynchronizationLock()) { - if (sampleModel == null) { - createColorAndSampleModel(); + if (sampleModel == null || !Arrays.equals(bandIndices, selectedBandIndices)) { + createColorAndSampleModel(bandIndices); } return sampleModel; } @@ -429,7 +450,7 @@ final class TiledResource extends TiledGridResource { protected Number getFillValue() throws DataStoreException { synchronized (getSynchronizationLock()) { if (fillValue == null) { - createColorAndSampleModel(); + createColorAndSampleModel(null); } return fillValue; } diff --git a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/internal/MatrixGridRessource.java b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/internal/MatrixGridRessource.java index d65b4b0eaf..be0abc9bca 100644 --- a/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/internal/MatrixGridRessource.java +++ b/incubator/src/org.apache.sis.storage.gimi/main/org/apache/sis/storage/gimi/internal/MatrixGridRessource.java @@ -67,13 +67,19 @@ public abstract class MatrixGridRessource extends TiledGridResource { } @Override - protected SampleModel getSampleModel() throws DataStoreException { + protected SampleModel getSampleModel(int[] bands) throws DataStoreException { + if (bands != null) { + return null; + } initialize(); return sampleModel; } @Override - protected ColorModel getColorModel() throws DataStoreException { + protected ColorModel getColorModel(int[] bands) throws DataStoreException { + if (bands != null) { + return null; + } initialize(); return colorModel; }