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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 7c0adf5  More complete support of "bands in variable" in 
RasterResource. We still have to add the support in Raster class. 
https://issues.apache.org/jira/browse/SIS-449
7c0adf5 is described below

commit 7c0adf54859fe2c8dd2c29aac8f87476eb5b7db6
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Thu Mar 21 16:54:08 2019 +0100

    More complete support of "bands in variable" in RasterResource. We still 
have to add the support in Raster class.
    https://issues.apache.org/jira/browse/SIS-449
---
 .../java/org/apache/sis/internal/netcdf/Grid.java  |   2 +-
 .../apache/sis/internal/netcdf/RasterResource.java | 188 ++++++++++++---------
 .../org/apache/sis/internal/netcdf/Resources.java  |   8 +-
 .../sis/internal/netcdf/Resources.properties       |   3 +-
 .../sis/internal/netcdf/Resources_fr.properties    |   3 +-
 .../org/apache/sis/internal/netcdf/Variable.java   |  20 ++-
 .../sis/internal/netcdf/impl/VariableInfo.java     |   8 -
 .../sis/internal/netcdf/ucar/VariableWrapper.java  |   8 -
 .../sis/internal/storage/AbstractGridResource.java |   2 +-
 9 files changed, 133 insertions(+), 109 deletions(-)

diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Grid.java 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Grid.java
index 5d62a06..fa0c7ee 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Grid.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Grid.java
@@ -404,7 +404,7 @@ findFree:       for (int srcDim : axis.sourceDimensions) {
                             switch (srcDim - otherDim) {
                                 case -1: grid = 
axis.createLocalizationGrid(other); break;
                                 case +1: grid = 
other.createLocalizationGrid(axis); break;
-                                default: continue;  // Needs axes at 
consecutive source dimensions.
+                                default: continue;            // Needs axes at 
consecutive source dimensions.
                             }
                             if (grid != null) {
                                 /*
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
index 0b3e6b8..3501ee1 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/RasterResource.java
@@ -18,6 +18,7 @@ package org.apache.sis.internal.netcdf;
 
 import java.util.Map;
 import java.util.List;
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.io.IOException;
 import java.nio.file.Path;
@@ -110,14 +111,24 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
     private final SampleDimension[] ranges;
 
     /**
-     * The netCDF variable wrapped by this resource. The length of this array 
shall be equal to {@code ranges.length},
-     * except if a variable dimension represents bands. In the later case, 
this array should contain only one element.
+     * The netCDF variable wrapped by this resource. The length of this array 
shall be equal to {@code ranges.length}.
+     * The same variable may be repeated if it contains many bands, in which 
case the bands are in dimension at index
+     * {@link #bandDimension}.
      */
     private final Variable[] data;
 
     /**
-     * If one of {@link #data} dimension provides values for different bands, 
that dimension index.
-     * Otherwise -1.
+     * If one of {@link #data} dimension provides values for different bands, 
that dimension index. Otherwise -1.
+     * This is an index in a list of dimensions in "natural" order (reverse of 
netCDF order).
+     * There is three ways to read the data, determined by the {@code 
bandDimension} value:
+     *
+     * <ul>
+     *   <li>{@code (bandDimension < 0)}: one variable per band (usual 
case).</li>
+     *   <li>{@code (bandDimension = 0)}: one variable containing all bands, 
with bands in the first dimension.</li>
+     *   <li>{@code (bandDimension > 0)}: one variable containing all bands, 
with bands in the last dimension.</li>
+     * </ul>
+     *
+     * @see Variable#bandDimension
      */
     private final int bandDimension;
 
@@ -137,38 +148,31 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
     /**
      * Creates a new resource. All variables in the {@code data} list shall 
have the same domain and the same grid geometry.
      *
-     * @param  decoder  the implementation used for decoding the netCDF file.
-     * @param  name     the name for the resource.
-     * @param  grid     the grid geometry (size, CRS…) of the {@linkplain 
#data} cube.
-     * @param  bands    the variables providing actual data. Shall contain at 
least one variable.
-     * @param  lock     the lock to use in {@code synchronized(lock)} 
statements.
+     * @param  decoder   the implementation used for decoding the netCDF file.
+     * @param  name      the name for the resource.
+     * @param  grid      the grid geometry (size, CRS…) of the {@linkplain 
#data} cube.
+     * @param  bands     the variables providing actual data. Shall contain at 
least one variable.
+     * @param  numBands  the number of bands, or -1 for using {@code 
bands.length}.
+     * @param  inner     if one of {@link #data} dimension provides values for 
different bands, that dimension index. Otherwise -1.
+     * @param  lock      the lock to use in {@code synchronized(lock)} 
statements.
      */
     private RasterResource(final Decoder decoder, final String name, final 
GridGeometry grid, final List<Variable> bands,
-            final Object lock) throws IOException, DataStoreException
+            final int numBands, final int inner, final Object lock) throws 
IOException, DataStoreException
     {
         super(decoder.listeners);
-        data         = bands.toArray(new Variable[bands.size()]);
-        ranges       = new SampleDimension[data.length];
-        identifier   = decoder.nameFactory.createLocalName(decoder.namespace, 
name);
-        location     = decoder.location;
-        gridGeometry = grid;
-        this.lock    = lock;
-        switch (data[0].getDimension() - grid.getDimension()) {
-            case 0: {
-                // All dimensions are in the CRS. This is the usual case.
-                bandDimension = -1;
-                break;
-            }
-            case 1: {
-                // One dimension is interpreted as bands.
-                bandDimension = data[0].bandDimension;
+        data = bands.toArray(new Variable[numBands >= 0 ? numBands : 
bands.size()]);
+        for (int i=data.length; --i >= 0;) {
+            if (data[i] != null) {
+                Arrays.fill(data, i+1, data.length, data[i]);                  
 // Repeat the last variable for all bands.
                 break;
             }
-            default: {
-                // Too many missing dimensions.
-                throw new DataStoreException();
-            }
         }
+        ranges        = new SampleDimension[data.length];
+        identifier    = decoder.nameFactory.createLocalName(decoder.namespace, 
name);
+        location      = decoder.location;
+        gridGeometry  = grid;
+        bandDimension = inner;
+        this.lock     = lock;
     }
 
     /**
@@ -195,67 +199,93 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
             if (grid == null) {
                 continue;                                                   // 
Skip variables that are not grid coverages.
             }
-            siblings.add(variable);
+            siblings.add(variable);                                         // 
Variable will the first band of raster.
             String name = variable.getStandardName();
-            final DataType type = variable.getDataType();
             /*
              * At this point we found a variable for which to create a 
resource. Most of the time, there is nothing else to do;
-             * the resource will have a single variable and the same name than 
that unique variable.  However in some cases, we
-             * should put other variables together with the one we just found. 
Example:
+             * the resource will have a single variable and the same name than 
that unique variable. The resulting raster will
+             * have only one band (sample dimension). However in some cases 
the raster should have more than one band:
              *
-             *    1) baroclinic_eastward_sea_water_velocity
-             *    2) baroclinic_northward_sea_water_velocity
+             *   1) if the variable has an extra dimension compared to the 
grid geometry;
+             *   2) of if two or more variables should be grouped together.
              *
-             * We use the "eastward" and "northward" keywords for recognizing 
such pairs, providing that everything else in the
-             * name is the same and the grid geometries are the same.
+             * The following  if {…} else {…}  blocks implement those two 
cases.
              */
-            for (final String keyword : VECTOR_COMPONENT_NAMES) {
-                final int prefixLength = name.indexOf(keyword);
-                if (prefixLength >= 0) {
-                    int suffixStart  = prefixLength + keyword.length();
-                    int suffixLength = name.length() - suffixStart;
-                    for (int j=i; ++j < variables.length;) {
-                        final Variable candidate = variables[j];
-                        if (candidate == null || candidate.getRole() != 
VariableRole.COVERAGE) {
-                            variables[j] = null;                               
 // For avoiding to revisit that variable again.
-                            continue;
-                        }
-                        final String cn = candidate.getStandardName();
-                        if (cn.regionMatches(cn.length() - suffixLength, name, 
suffixStart, suffixLength) &&
-                            cn.regionMatches(0, name, 0, prefixLength) && 
candidate.getDataType() == type &&
-                            grid.equals(candidate.getGridGeometry()))
-                        {
-                            /*
-                             * Found another variable with the same name 
except for the keyword. Verify that the
-                             * keyword is replaced by another word in the 
vector component keyword list. If this
-                             * is the case, then we consider that those two 
variables should be kept together.
-                             */
-                            for (final String k : VECTOR_COMPONENT_NAMES) {
-                                if (cn.regionMatches(prefixLength, k, 0, 
k.length())) {
-                                    siblings.add(candidate);
-                                    variables[j] = null;
-                                    break;
+            final List<Dimension> gridDimensions = 
variable.getGridDimensions();
+            final int dataDimension = gridDimensions.size();
+            final int gridDimension = grid.getDimension();
+            final int bandDimension, numBands;
+            if (dataDimension != gridDimension) {
+                if (dataDimension != gridDimension + 1) {
+                    throw new 
DataStoreContentException(Resources.forLocale(decoder.listeners.getLocale())
+                            .getString(Resources.Keys.UnmappedDimensions_4, 
name, decoder.getFilename(), dataDimension, gridDimension));
+                }
+                bandDimension = variable.bandDimension;                        
    // One variable dimension is interpreted as bands.
+                Dimension dim = gridDimensions.get(dataDimension - 1 - 
bandDimension);  // Note: "natural" → netCDF index conversion.
+                numBands = Math.toIntExact(dim.length());
+            } else {
+                /*
+                 * At this point we found a variable where all dimensions are 
in the CRS. This is the usual case;
+                 * there is no band explicitly declared in the netCDF file. 
However in some cases, we should put
+                 * other variables together with the one we just found. 
Example:
+                 *
+                 *    1) baroclinic_eastward_sea_water_velocity
+                 *    2) baroclinic_northward_sea_water_velocity
+                 *
+                 * We use the "eastward" and "northward" keywords for 
recognizing such pairs, providing that everything else in the
+                 * name is the same and the grid geometries are the same.
+                 */
+                bandDimension = -1;                                            
     // No dimension to be interpreted as bands.
+                numBands = -1;                                                 
     // To be determined by siblings.size().
+                final DataType type = variable.getDataType();
+                for (final String keyword : VECTOR_COMPONENT_NAMES) {
+                    final int prefixLength = name.indexOf(keyword);
+                    if (prefixLength >= 0) {
+                        int suffixStart  = prefixLength + keyword.length();
+                        int suffixLength = name.length() - suffixStart;
+                        for (int j=i; ++j < variables.length;) {
+                            final Variable candidate = variables[j];
+                            if (candidate == null || candidate.getRole() != 
VariableRole.COVERAGE) {
+                                variables[j] = null;                           
     // For avoiding to revisit that variable again.
+                                continue;
+                            }
+                            final String cn = candidate.getStandardName();
+                            if (cn.regionMatches(cn.length() - suffixLength, 
name, suffixStart, suffixLength) &&
+                                cn.regionMatches(0, name, 0, prefixLength) && 
candidate.getDataType() == type &&
+                                grid.equals(candidate.getGridGeometry()))
+                            {
+                                /*
+                                 * Found another variable with the same name 
except for the keyword. Verify that the
+                                 * keyword is replaced by another word in the 
vector component keyword list. If this
+                                 * is the case, then we consider that those 
two variables should be kept together.
+                                 */
+                                for (final String k : VECTOR_COMPONENT_NAMES) {
+                                    if (cn.regionMatches(prefixLength, k, 0, 
k.length())) {
+                                        siblings.add(candidate);
+                                        variables[j] = null;
+                                        break;
+                                    }
                                 }
                             }
                         }
-                    }
-                    /*
-                     * If we have more than one variable, omit the keyword 
from the name. For example instead
-                     * of "baroclinic_eastward_sea_water_velocity", construct 
"baroclinic_sea_water_velocity".
-                     * Note that we may need to remove duplicated '_' 
character after keyword removal.
-                     */
-                    if (siblings.size() > 1) {
-                        if (suffixLength != 0) {
-                            final int c = name.codePointAt(suffixStart);
-                            if ((prefixLength != 0) ? (c == 
name.codePointBefore(prefixLength)) : (c == '_')) {
-                                suffixStart += Character.charCount(c);
+                        /*
+                         * If we have more than one variable, omit the keyword 
from the name. For example instead
+                         * of "baroclinic_eastward_sea_water_velocity", 
construct "baroclinic_sea_water_velocity".
+                         * Note that we may need to remove duplicated '_' 
character after keyword removal.
+                         */
+                        if (siblings.size() > 1) {
+                            if (suffixLength != 0) {
+                                final int c = name.codePointAt(suffixStart);
+                                if ((prefixLength != 0) ? (c == 
name.codePointBefore(prefixLength)) : (c == '_')) {
+                                    suffixStart += Character.charCount(c);
+                                }
                             }
+                            name = new 
StringBuilder(name).delete(prefixLength, suffixStart).toString();
                         }
-                        name = new StringBuilder(name).delete(prefixLength, 
suffixStart).toString();
                     }
                 }
             }
-            resources.add(new RasterResource(decoder, name.trim(), grid, 
siblings, lock));
+            resources.add(new RasterResource(decoder, name.trim(), grid, 
siblings, numBands, bandDimension, lock));
             siblings.clear();
         }
         return resources;
@@ -414,7 +444,7 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
         if (domain == null) {
             domain = gridGeometry;
         }
-        final Variable first = data[bandDimension >= 0 ? 0 : 
rangeIndices.first()];     // Only one variable if bandDimension ≧ 0.
+        final Variable first = data[rangeIndices.first()];
         final DataType dataType = first.getDataType();
         if (bandDimension < 0) {
             for (int i=0; i<rangeIndices.getNumBands(); i++) {
@@ -455,7 +485,7 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
             synchronized (lock) {
                 for (int i=0; i<bands.length; i++) {
                     final int r = rangeIndices.getSourceIndex(i);              
     // In strictly increasing order.
-                    final Variable variable = data[bandDimension >= 0 ? 0 : 
r];     // Only one variable if bandDimension ≧ 0.
+                    final Variable variable = data[r];
                     SampleDimension sd = ranges[r];
                     if (sd == null) {
                         ranges[r] = sd = 
createSampleDimension(rangeIndices.builder(), variable);
@@ -490,7 +520,7 @@ public final class RasterResource extends 
AbstractGridResource implements Resour
             throw new DataStoreContentException(e);
         }
         if (imageBuffer == null) {
-            throw new 
DataStoreContentException(Errors.format(Errors.Keys.UnsupportedType_1, 
dataType.name()));
+            throw new 
DataStoreContentException(Errors.getResources(getLocale()).getString(Errors.Keys.UnsupportedType_1,
 dataType.name()));
         }
         return new Raster(domain, UnmodifiableArrayList.wrap(bands), 
imageBuffer, first.getStandardName());
     }
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.java
index bd6577d..f24dab9 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.java
@@ -117,7 +117,7 @@ public final class Resources extends IndexedResourceBundle {
         public static final short IllegalValueRange_4 = 16;
 
         /**
-         * The declared size of variable “{1}” in netCDF file “{0}” is 
{2,number}} bytes greater than
+         * The declared size of variable “{1}” in netCDF file “{0}” is 
{2,number} bytes greater than
          * expected.
          */
         public static final short MismatchedVariableSize_3 = 8;
@@ -145,6 +145,12 @@ public final class Resources extends IndexedResourceBundle 
{
         public static final short UnexpectedDimensionForVariable_4 = 2;
 
         /**
+         * Variable “{1}” in file “{0}” has {2,number} dimensions but only 
{3,number} can be associated
+         * to a coordinate reference system.
+         */
+        public static final short UnmappedDimensions_4 = 19;
+
+        /**
          * NetCDF file “{0}” uses unsupported data type {2} for variable “{1}”.
          */
         public static final short UnsupportedDataType_3 = 5;
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.properties
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.properties
index 1dd77af..7a05771 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.properties
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources.properties
@@ -30,10 +30,11 @@ CanNotUseUCAR                     = Can not use UCAR 
library for netCDF format.
 DimensionNotFound_3               = Dimension \u201c{2}\u201d declared by 
attribute \u201c{1}\u201d is not found in the \u201c{0}\u201d file.
 DuplicatedAxis_2                  = Duplicated axis \u201c{1}\u201d in a grid 
of netCDF file \u201c{0}\u201d.
 IllegalValueRange_4               = Illegal value range {2,number} \u2026 
{3,number} for variable \u201c{1}\u201d in netCDF file \u201c{0}\u201d.
-MismatchedVariableSize_3          = The declared size of variable 
\u201c{1}\u201d in netCDF file \u201c{0}\u201d is {2,number}} bytes greater 
than expected.
+MismatchedVariableSize_3          = The declared size of variable 
\u201c{1}\u201d in netCDF file \u201c{0}\u201d is {2,number} bytes greater than 
expected.
 MismatchedVariableType_3          = Variables \u201c{1}\u201d and 
\u201c{2}\u201d in netCDF file \u201c{0}\u201d does not have the same type.
 ResamplingIntervalNotFound_2      = Variable \u201c{1}\u201d or netCDF file 
\u201c{0}\u201d has a different size than its coordinate system, but no 
resampling interval is specified.
 UnexpectedAxisCount_4             = Reference system of type \u2018{1}\u2019 
can not have {2}\u00a0axes. The axes found in the \u201c{0}\u201d netCDF file 
are: {3}.
 UnexpectedDimensionForVariable_4  = Variable \u201c{1}\u201d in file 
\u201c{0}\u201d has a dimension \u201c{3}\u201d while we expected 
\u201c{2}\u201d.
+UnmappedDimensions_4              = Variable \u201c{1}\u201d in file 
\u201c{0}\u201d has {2,number} dimensions but only {3,number} can be associated 
to a coordinate reference system.
 UnsupportedDataType_3             = NetCDF file \u201c{0}\u201d uses 
unsupported data type {2} for variable \u201c{1}\u201d.
 VariableNotFound_2                = Variable \u201c{1}\u201d is not found in 
the \u201c{0}\u201d file.
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources_fr.properties
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources_fr.properties
index 7cb59c7..b32eff7 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources_fr.properties
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Resources_fr.properties
@@ -35,10 +35,11 @@ CanNotUseUCAR                     = Ne peut pas utiliser la 
biblioth\u00e8que de
 DimensionNotFound_3               = La dimension \u00ab\u202f{2}\u202f\u00bb 
d\u00e9clar\u00e9e par l\u2019attribut \u00ab\u202f{1}\u202f\u00bb n\u2019a pas 
\u00e9t\u00e9 trouv\u00e9e dans le fichier \u00ab\u202f{0}\u202f\u00bb.
 DuplicatedAxis_2                  = Axe \u00ab\u202f{1}\u202f\u00bb 
dupliqu\u00e9 dans une grille du fichier netCDF \u00ab\u202f{0}\u202f\u00bb.
 IllegalValueRange_4               = Plage de valeurs {2,number} \u2026 
{3,number} ill\u00e9gale pour la variable \u00ab\u202f{1}\u202f\u00bb dans le 
fichier netCDF \u00ab\u202f{0}\u202f\u00bb.
-MismatchedVariableSize_3          = La longueur d\u00e9clar\u00e9e de la 
variable \u00ab\u202f{1}\u202f\u00bb dans le fichier netCDF 
\u00ab\u202f{0}\u202f\u00bb d\u00e9passe de {2,number}} octets la valeur 
attendue.
+MismatchedVariableSize_3          = La longueur d\u00e9clar\u00e9e de la 
variable \u00ab\u202f{1}\u202f\u00bb dans le fichier netCDF 
\u00ab\u202f{0}\u202f\u00bb d\u00e9passe de {2,number} octets la valeur 
attendue.
 MismatchedVariableType_3          = Les variables \u00ab\u202f{1}\u202f\u00bb 
et \u00ab\u202f{2}\u202f\u00bb dans le fichier netCDF 
\u00ab\u202f{0}\u202f\u00bb ne sont pas du m\u00eame type.
 ResamplingIntervalNotFound_2      = La variable \u00ab\u202f{1}\u202f\u00bb du 
fichier netCDF \u00ab\u202f{0}\u202f\u00bb a une taille diff\u00e9rente de 
celle de son syst\u00e8me de coordonn\u00e9es, mais l\u2019intervalle 
d\u2019\u00e9chantillonnage n\u2019a pas \u00e9t\u00e9 sp\u00e9cifi\u00e9.
 UnexpectedAxisCount_4             = Les syst\u00e8mes de r\u00e9f\u00e9rence 
de type \u2018{1}\u2019 ne peuvent pas avoir {2}\u00a0axes. Les axes 
trouv\u00e9s dans le fichier netCDF \u00ab\u202f{0}\u202f\u00bb sont\u2008: {3}.
 UnexpectedDimensionForVariable_4  = La variable \u00ab\u202f{1}\u202f\u00bb 
dans le fichier \u00ab\u202f{0}\u202f\u00bb a une dimension 
\u00ab\u202f{3}\u202f\u00bb alors qu\u2019on attendait 
\u00ab\u202f{2}\u202f\u00bb.
+UnmappedDimensions_4              = La variable \u00ab\u202f{1}\u202f\u00bb 
dans le fichier \u00ab\u202f{0}\u202f\u00bb a {2,number} dimensions mais 
seulement {3,number} peuvent \u00eatre associ\u00e9es \u00e0 un syst\u00e8me de 
r\u00e9f\u00e9rence des coordonn\u00e9es.
 UnsupportedDataType_3             = Le fichier netCDF 
\u00ab\u202f{0}\u202f\u00bb utilise un type de donn\u00e9es non-support\u00e9 
{2} pour la variable \u00ab\u202f{1}\u202f\u00bb.
 VariableNotFound_2                = La variable \u00ab\u202f{1}\u202f\u00bb 
n\u2019a pas \u00e9t\u00e9 trouv\u00e9e dans le fichier 
\u00ab\u202f{0}\u202f\u00bb.
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java
index 68d44ba..fb3e8ec 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Variable.java
@@ -133,6 +133,8 @@ public abstract class Variable extends NamedElement {
     /**
      * If {@link #gridGeometry} has less dimensions than this variable, index 
of a grid dimension to take as raster bands.
      * Otherwise this field is left uninitialized. If set, the index is 
relative to "natural" order (reverse of netCDF order).
+     *
+     * @see RasterResource#bandDimension
      */
     int bandDimension;
 
@@ -640,13 +642,6 @@ public abstract class Variable extends NamedElement {
     }
 
     /**
-     * Returns the number of grid dimension. This is the length of the array 
returned by {@link #getGridDimensions()}.
-     *
-     * @return number of grid dimensions.
-     */
-    public abstract int getDimension();
-
-    /**
      * Returns the grid geometry for this variable, or {@code null} if this 
variable is not a data cube.
      * Not all variables have a grid geometry. For example collections of 
features do not have such grid.
      * The same grid geometry may be shared by many variables.
@@ -669,7 +664,8 @@ public abstract class Variable extends NamedElement {
                  * those dimensions may not have the same length (this 
mismatch is handled in the next block).
                  */
                 List<Dimension> dimensions = getGridDimensions();              
         // In netCDF order.
-                if (dimensions.size() > info.getSourceDimensions()) {
+                final int dataDimension = dimensions.size();
+                if (dataDimension > info.getSourceDimensions()) {
                     boolean copied = false;
                     final List<Dimension> toKeep = info.getDimensions();       
         // Also in netCDF order.
                     final int numToKeep = toKeep.size();
@@ -687,7 +683,13 @@ public abstract class Variable extends NamedElement {
                                 copied = true;
                                 dimensions = new ArrayList<>(dimensions);
                             }
-                            bandDimension = getDimension() - i - 1;         // 
Convert netCDF order to "natural" order.
+                            /*
+                             * It is possible that we never reach this point 
if the unexpected dimension is last.
+                             * However in such case the dimension to declare 
is the last one in netCDF order,
+                             * which corresponds to the first dimension (i.e. 
dimension 0) in "natural" order.
+                             * Since the 'bandDimension' field is initialized 
to zero, its value is correct.
+                             */
+                            bandDimension = dataDimension - 1 - i;          // 
Convert netCDF order to "natural" order.
                             dimensions.remove(i);
                             if (dimensions.size() < numToKeep) {
                                 throw new InternalDataStoreException();     // 
Should not happen (see above comment).
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
index 7d82287..1d58f8a 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
@@ -500,14 +500,6 @@ final class VariableInfo extends Variable implements 
Comparable<VariableInfo> {
     }
 
     /**
-     * Returns the number of grid dimension. This is the length of the array 
returned by {@link #getGridDimensions()}.
-     */
-    @Override
-    public int getDimension() {
-        return dimensions.length;
-    }
-
-    /**
      * Returns the names of all attributes associated to this variable.
      *
      * @return names of all attributes associated to this variable.
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
index 0d20e46..0505744 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/VariableWrapper.java
@@ -287,14 +287,6 @@ final class VariableWrapper extends Variable {
     }
 
     /**
-     * Returns the number of grid dimension. This is the length of the array 
returned by {@link #getGridDimensions()}.
-     */
-    @Override
-    public int getDimension() {
-        return variable.getRank();
-    }
-
-    /**
      * Returns the names of all attributes associated to this variable.
      *
      * @return names of all attributes associated to this variable.
diff --git 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractGridResource.java
 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractGridResource.java
index bd596ae..5ffb2a9 100644
--- 
a/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractGridResource.java
+++ 
b/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/AbstractGridResource.java
@@ -141,7 +141,7 @@ public abstract class AbstractGridResource extends 
AbstractResource implements G
         /**
          * Name of the extent dimension for bands.
          */
-        private static DimensionNameType BAND = 
DimensionNameType.valueOf("BAND");
+        private static final DimensionNameType BAND = 
DimensionNameType.valueOf("BAND");
 
         /**
          * The user-specified range indices in high bits, together with 
indices order in the low bits.

Reply via email to