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 e13ceef898df46163c0681f4d968be5687d9053a
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Thu Dec 30 20:41:33 2021 +0100

    Fix an exception when opening a netCDF file with one-dimensional variables.
---
 .../sis/internal/map/coverage/RenderingData.java   |  4 +-
 .../org/apache/sis/internal/netcdf/CRSBuilder.java | 47 +++++++++++++---------
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git 
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
 
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
index 994ec06..e746df5 100644
--- 
a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
+++ 
b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
@@ -602,7 +602,9 @@ public class RenderingData implements Cloneable {
          * This method is invoked with `sourceMedian` expressed in the 
transform source CRS.
          * But by contract, `WraparoundApplicator` needs that point in the 
transform target CRS.
          */
-        sourceMedian = transform.transform(sourceMedian, null);
+        if (sourceMedian != null && !transform.isIdentity()) {
+            sourceMedian = transform.transform(sourceMedian, null);
+        }
         return new WraparoundApplicator(sourceMedian, targetMedian, 
targetCRS.getCoordinateSystem()).forDomainOfUse(transform);
     }
 
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/CRSBuilder.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/CRSBuilder.java
index 13b04dd..ee2f90b 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/CRSBuilder.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/CRSBuilder.java
@@ -80,12 +80,18 @@ import org.apache.sis.measure.Units;
  * which is a {@linkplain Axis#abbreviation controlled vocabulary} for this 
implementation.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   1.0
  * @module
  */
 abstract class CRSBuilder<D extends Datum, CS extends CoordinateSystem> {
     /**
+     * An arbitrary limit on the number of dimensions, for catching what may 
be malformed data.
+     * We rarely have more than 4 dimensions.
+     */
+    private static final int MAXDIM = 1000;
+
+    /**
      * The type of datum as a GeoAPI sub-interface of {@link Datum}.
      * Used for verifying the type of cached datum at {@link #datumIndex}.
      */
@@ -102,19 +108,19 @@ abstract class CRSBuilder<D extends Datum, CS extends 
CoordinateSystem> {
      * The datum type at that index must be an instance of {@link #datumType}. 
We cache only the datum because they do
      * not depend on the netCDF file content in the common case where the CRS 
is not explicitly specified.
      */
-    private final byte datumIndex;
+    private final int datumIndex;
 
     /**
      * Specify the range of valid number of dimensions, inclusive.
      * The {@link #dimension} value shall be in that range.
      */
-    private final byte minDim, maxDim;
+    private final int minDim, maxDim;
 
     /**
      * Number of valid elements in the {@link #axes} array. The count should 
not be larger than 3,
      * even if the netCDF file has more axes, because each {@code CRSBuilder} 
is only for a subset.
      */
-    private byte dimension;
+    private int dimension;
 
     /**
      * The axes to use for creating the coordinate reference system.
@@ -158,7 +164,7 @@ abstract class CRSBuilder<D extends Datum, CS extends 
CoordinateSystem> {
      * @param  minDim      minimum number of dimensions (usually 1, 2 or 3).
      * @param  maxDim      maximum number of dimensions (usually 1, 2 or 3).
      */
-    private CRSBuilder(final Class<D> datumType, final String datumBase, final 
byte datumIndex, final byte minDim, final byte maxDim) {
+    private CRSBuilder(final Class<D> datumType, final String datumBase, final 
int datumIndex, final int minDim, final int maxDim) {
         this.datumType  = datumType;
         this.datumBase  = datumBase;
         this.datumIndex = datumIndex;
@@ -321,9 +327,9 @@ previous:   for (int i=components.size(); --i >= 0;) {
      * @throws DataStoreContentException if the given axis can not be added in 
this builder.
      */
     private void add(final Axis axis) throws DataStoreContentException {
-        if (dimension == Byte.MAX_VALUE) {
+        if (dimension > MAXDIM) {
             throw new 
DataStoreContentException(getFirstAxis().coordinates.errors()
-                    .getString(Errors.Keys.ExcessiveListSize_2, "axes", 
(short) (Byte.MAX_VALUE + 1)));
+                    .getString(Errors.Keys.ExcessiveListSize_2, "axes", 
dimension));
         }
         if (dimension >= axes.length) {
             axes = Arrays.copyOf(axes, dimension * 2);        // Should not 
happen (see method javadoc).
@@ -556,8 +562,8 @@ previous:   for (int i=components.size(); --i >= 0;) {
          *
          * @param  minDim  minimum number of dimensions (2 or 3).
          */
-        Geodetic(final byte minDim) {
-            super(GeodeticDatum.class, "GRS 1980", (byte) 0, minDim, (byte) 3);
+        Geodetic(final int minDim) {
+            super(GeodeticDatum.class, "GRS 1980", 0, minDim, 3);
         }
 
         /**
@@ -610,7 +616,7 @@ previous:   for (int i=components.size(); --i >= 0;) {
          * Creates a new builder (invoked by lambda function).
          */
         public Spherical() {
-            super((byte) 3);
+            super(3);
         }
 
         /**
@@ -662,7 +668,7 @@ previous:   for (int i=components.size(); --i >= 0;) {
          * Creates a new builder (invoked by lambda function).
          */
         public Geographic() {
-            super((byte) 2);
+            super(2);
         }
 
         /**
@@ -755,7 +761,7 @@ previous:   for (int i=components.size(); --i >= 0;) {
          * Creates a new builder (invoked by lambda function).
          */
         public Projected() {
-            super((byte) 2);
+            super(2);
         }
 
         /**
@@ -810,7 +816,7 @@ previous:   for (int i=components.size(); --i >= 0;) {
          * Creates a new builder (invoked by lambda function).
          */
         public Vertical() {
-            super(VerticalDatum.class, "Mean Sea Level", (byte) 1, (byte) 1, 
(byte) 1);
+            super(VerticalDatum.class, "Mean Sea Level", 1, 1, 1);
         }
 
         /**
@@ -870,7 +876,7 @@ previous:   for (int i=components.size(); --i >= 0;) {
          * Creates a new builder (invoked by lambda function).
          */
         public Temporal() {
-            super(TemporalDatum.class, "", (byte) 2, (byte) 1, (byte) 1);
+            super(TemporalDatum.class, "", 2, 1, 1);
         }
 
         /**
@@ -948,7 +954,7 @@ previous:   for (int i=components.size(); --i >= 0;) {
          * Creates a new builder (invoked by lambda function).
          */
         public Engineering() {
-            super(EngineeringDatum.class, "affine coordinate system", (byte) 
3, (byte) 2, (byte) 3);
+            super(EngineeringDatum.class, "affine coordinate system", 3, 1, 3);
         }
 
         /**
@@ -969,10 +975,11 @@ previous:   for (int i=components.size(); --i >= 0;) {
          */
         @Override void createCS(CSFactory factory, Map<String,?> properties, 
CoordinateSystemAxis[] axes) throws FactoryException {
             try {
-                if (axes.length > 2) {
-                    coordinateSystem = factory.createAffineCS(properties, 
axes[0], axes[1], axes[2]);
-                } else {
-                    coordinateSystem = factory.createAffineCS(properties, 
axes[0], axes[1]);
+                switch (axes.length) {
+                    case 0:  break;     // Should never happen but we are 
paranoiac.
+                    case 1:  coordinateSystem = 
factory.createParametricCS(properties, axes[0]); return;
+                    case 2:  coordinateSystem = 
factory.createAffineCS(properties, axes[0], axes[1]); return;
+                    default: coordinateSystem = 
factory.createAffineCS(properties, axes[0], axes[1], axes[2]); return;
                 }
             } catch (InvalidGeodeticParameterException e) {
                 /*
@@ -980,9 +987,9 @@ previous:   for (int i=components.size(); --i >= 0;) {
                  * Cartesian or affine coordinate system.  The fallback object 
created below is not abstract in
                  * the Java sense, but in the sense that we don't have more 
specific information on the CS type.
                  */
-                coordinateSystem = new AbstractCS(properties, axes);
                 recoverableException(e);
             }
+            coordinateSystem = new AbstractCS(properties, axes);
         }
 
         /**

Reply via email to