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 0c35e9fa7e224bd5a272fa245a6f2200d474f77b
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Wed Sep 28 11:42:45 2022 +0200

    Preserve the type of missing values in netCDF files.
    Before this commit, missing values in GCOM files were always represented as 
floating points.
    After this commit, missing values declared as integers stay integers.
    It makes a difference when computing which value is next.
---
 .../apache/sis/internal/earth/netcdf/GCOM_C.java   | 20 +++++++--------
 .../apache/sis/internal/earth/netcdf/GCOM_W.java   |  4 +--
 .../org/apache/sis/internal/netcdf/Convention.java |  6 ++---
 .../java/org/apache/sis/internal/netcdf/Node.java  | 29 ++++++++++++++++------
 .../org/apache/sis/internal/netcdf/Variable.java   |  6 ++---
 .../apache/sis/storage/netcdf/MetadataReader.java  |  4 +--
 .../apache/sis/internal/netcdf/VariableTest.java   |  4 +--
 7 files changed, 43 insertions(+), 30 deletions(-)

diff --git 
a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
 
b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
index 8672c85d57..0f47ed5f66 100644
--- 
a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
+++ 
b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_C.java
@@ -418,7 +418,7 @@ public final class GCOM_C extends Convention {
     public MathTransform gridToCRS(final Node node, final MathTransform 
baseToCRS) throws TransformException {
         final double[] corners = new double[CORNERS.length];
         for (int i=0; i<corners.length; i++) {
-            corners[i] = node.getAttributeAsNumber(CORNERS[i]);
+            corners[i] = node.getAttributeAsDouble(CORNERS[i]);
         }
         baseToCRS.transform(corners, 0, corners, 0, corners.length / 2);
         /*
@@ -431,8 +431,8 @@ public final class GCOM_C extends Convention {
         /*
          * Transform the spans into pixel sizes (resolution), then build the 
transform.
          */
-        sx /= (node.getAttributeAsNumber("Number_of_pixels") - 1);
-        sy /= (node.getAttributeAsNumber("Number_of_lines")  - 1);
+        sx /= (node.getAttributeAsDouble("Number_of_pixels") - 1);
+        sy /= (node.getAttributeAsDouble("Number_of_lines")  - 1);
         if (Double.isFinite(sx) && Double.isFinite(sy)) {
             final Matrix3 m = new Matrix3();
             m.m00 =  sx;
@@ -472,9 +472,9 @@ public final class GCOM_C extends Convention {
     public NumberRange<?> validRange(final Variable data) {
         NumberRange<?> range = super.validRange(data);
         if (range == null) {
-            final double min = data.getAttributeAsNumber("Minimum_valid_DN");
-            final double max = data.getAttributeAsNumber("Maximum_valid_DN");
-            if (Double.isFinite(min) && Double.isFinite(max)) {
+            final Number min = data.getAttributeAsNumber("Minimum_valid_DN");
+            final Number max = data.getAttributeAsNumber("Maximum_valid_DN");
+            if (min != null || max != null) {
                 range = NumberRange.createBestFit(min, true, max, true);
             }
         }
@@ -494,8 +494,8 @@ public final class GCOM_C extends Convention {
         final Map<Number, Object> pads = super.nodataValues(data);
         for (int i=0; i<NO_DATA.length; i++) {
             String name = NO_DATA[i];
-            final double value = data.getAttributeAsNumber(name);
-            if (Double.isFinite(value)) {
+            final Number value = data.getAttributeAsNumber(name);
+            if (value != null) {
                 final Object label;
                 if (i != 0) {
                     if (name.endsWith(SUFFIX)) {
@@ -522,8 +522,8 @@ public final class GCOM_C extends Convention {
     public TransferFunction transferFunction(final Variable data) {
         final TransferFunction tr = super.transferFunction(data);
         if (tr.isIdentity()) {
-            final double slope  = data.getAttributeAsNumber("Slope");
-            final double offset = data.getAttributeAsNumber("Offset");
+            final double slope  = data.getAttributeAsDouble("Slope");
+            final double offset = data.getAttributeAsDouble("Offset");
             if (Double.isFinite(slope))  tr.setScale (slope);
             if (Double.isFinite(offset)) tr.setOffset(offset);
         }
diff --git 
a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java
 
b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java
index 82b485e1a5..6d8f432adb 100644
--- 
a/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java
+++ 
b/profiles/sis-japan-profile/src/main/java/org/apache/sis/internal/earth/netcdf/GCOM_W.java
@@ -255,8 +255,8 @@ public final class GCOM_W extends Convention {
     public TransferFunction transferFunction(final Variable data) {
         final TransferFunction tr = super.transferFunction(data);
         if (tr.isIdentity()) {
-            final double slope  = data.getAttributeAsNumber("SCALE FACTOR");
-            final double offset = data.getAttributeAsNumber("OFFSET");
+            final double slope  = data.getAttributeAsDouble("SCALE FACTOR");
+            final double offset = data.getAttributeAsDouble("OFFSET");
             if (Double.isFinite(slope))  tr.setScale (slope);
             if (Double.isFinite(offset)) tr.setOffset(offset);
         }
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
index 8570cbd890..35e1f97fa1 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Convention.java
@@ -351,7 +351,7 @@ public class Convention {
      * @return the "grid indices to data indices" scale factor, or {@link 
Double#NaN} if none.
      */
     public double gridToDataIndices(final Variable axis) {
-        return axis.getAttributeAsNumber("resampling_interval");
+        return axis.getAttributeAsDouble("resampling_interval");
     }
 
     /**
@@ -755,8 +755,8 @@ public class Convention {
          * a "packed" variable. Otherwise the transfer function is the 
identity transform.
          */
         final TransferFunction tr = new TransferFunction();
-        final double scale  = data.getAttributeAsNumber(CDM.SCALE_FACTOR);
-        final double offset = data.getAttributeAsNumber(CDM.ADD_OFFSET);
+        final double scale  = data.getAttributeAsDouble(CDM.SCALE_FACTOR);
+        final double offset = data.getAttributeAsDouble(CDM.ADD_OFFSET);
         if (!Double.isNaN(scale))  tr.setScale (scale);
         if (!Double.isNaN(offset)) tr.setOffset(offset);
         return tr;
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Node.java 
b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Node.java
index 561a8761c5..d96e7cf015 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Node.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Node.java
@@ -30,7 +30,7 @@ import org.apache.sis.internal.util.Strings;
  * The common characteristic of those objects is to have attributes.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.0
+ * @version 1.3
  * @since   1.0
  * @module
  */
@@ -182,16 +182,16 @@ public abstract class Node extends NamedElement {
     }
 
     /**
-     * Returns the value of the given attribute as a number, or {@link 
Double#NaN}.
-     * If the number is stored with single-precision, it is assumed casted 
from a
-     * representation in base 10.
+     * Returns the value of the given attribute as a number, or {@code null}.
+     * This method returns a number of the type that most closely matches the
+     * type in the netCDF file.
      *
      * @param  attributeName  the name of the attribute for which to get the 
value.
-     * @return the singleton attribute value, or {@code NaN} if none or 
ambiguous.
+     * @return the singleton attribute value, or {@code null} if none or 
ambiguous.
      */
-    public final double getAttributeAsNumber(final String attributeName) {
-        final Object value = getAttributeValue(attributeName);
+    public final Number getAttributeAsNumber(final String attributeName) {
         Number singleton = null;
+        final Object value = getAttributeValue(attributeName);
         if (value instanceof Number) {
             singleton = (Number) value;
         } else if (value instanceof String) {
@@ -205,11 +205,24 @@ public abstract class Node extends NamedElement {
                     if (singleton == null) {
                         singleton = n;
                     } else if (!singleton.equals(n)) {
-                        return Double.NaN;
+                        return null;
                     }
                 }
             }
         }
+        return singleton;
+    }
+
+    /**
+     * Returns the value of the given attribute as a number, or {@link 
Double#NaN}.
+     * If the number is stored with single-precision, it is assumed casted 
from a
+     * representation in base 10.
+     *
+     * @param  attributeName  the name of the attribute for which to get the 
value.
+     * @return the singleton attribute value, or {@code NaN} if none or 
ambiguous.
+     */
+    public final double getAttributeAsDouble(final String attributeName) {
+        Number singleton = getAttributeAsNumber(attributeName);
         if (singleton == null) {
             return Double.NaN;
         }
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 4305b22bfa..cda5fa818e 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
@@ -434,10 +434,10 @@ public abstract class Variable extends Node {
                 return convention.transferFunction(this).isIdentity();
             }
             // Shortcut for common case.
-            double c = getAttributeAsNumber(CDM.SCALE_FACTOR);
-            if (Double.isNaN(c) || c == 1) {
+            Number c = getAttributeAsNumber(CDM.SCALE_FACTOR);
+            if (c == null || c.doubleValue() == 1) {
                 c = getAttributeAsNumber(CDM.ADD_OFFSET);
-                return Double.isNaN(c) || c == 0;
+                return c == null || c.doubleValue() == 0;
             }
         }
         return false;
diff --git 
a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
 
b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
index d4996187bc..cc5409b623 100644
--- 
a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
+++ 
b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
@@ -964,8 +964,8 @@ split:  while ((start = 
CharSequences.skipLeadingWhitespaces(value, start, lengt
             addBandDescription(description);
         }
         setSampleUnits(variable.getUnit());
-        setTransferFunction(variable.getAttributeAsNumber(CDM.SCALE_FACTOR),
-                            variable.getAttributeAsNumber(CDM.ADD_OFFSET));
+        setTransferFunction(variable.getAttributeAsDouble(CDM.SCALE_FACTOR),
+                            variable.getAttributeAsDouble(CDM.ADD_OFFSET));
         addContentType(forCodeName(CoverageContentType.class, 
stringValue(ACDD.coverage_content_type)));
     }
 
diff --git 
a/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
 
b/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
index d05cf6bcf3..1074a38cb3 100644
--- 
a/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
+++ 
b/storage/sis-netcdf/src/test/java/org/apache/sis/internal/netcdf/VariableTest.java
@@ -266,7 +266,7 @@ public strictfp class VariableTest extends TestCase {
         assertArrayEquals("getAttributeAsStrings", new String[] {t}, 
variable.getAttributeAsStrings(name, ' '));
         if (expected instanceof Number) {
             final double en = ((Number) expected).doubleValue();
-            assertEquals("getAttributeAsNumber", en, 
variable.getAttributeAsNumber(name), STRICT);
+            assertEquals("getAttributeAsDouble", en, 
variable.getAttributeAsDouble(name), STRICT);
             final Vector vector = variable.getAttributeAsVector(name);
             assertNotNull("getAttributeAsVector", vector);
             assertEquals(1, vector.size());
@@ -284,7 +284,7 @@ public strictfp class VariableTest extends TestCase {
         final Vector values = variable.getAttributeAsVector(name);
         assertNotNull(name, values);
         assertEquals ("size", expected.length, values.size());
-        assertTrue   ("getAttributeAsNumber", 
Double.isNaN(variable.getAttributeAsNumber(name)));
+        assertTrue   ("getAttributeAsDouble", 
Double.isNaN(variable.getAttributeAsDouble(name)));
         assertEquals ("getAttributeValue", values, 
variable.getAttributeValue(name));
         final Object[] texts = 
Arrays.stream(expected).map(Object::toString).toArray();
         assertArrayEquals("getAttributeAsStrings", texts, 
variable.getAttributeAsStrings(name, ' '));

Reply via email to