sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Range of valid values provided by the UCAR library are converted values, not packed values.
Date Wed, 30 Jan 2019 09:00:30 GMT
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 08904cd  Range of valid values provided by the UCAR library are converted values,
not packed values.
08904cd is described below

commit 08904cd15570a61e6652544b4e73e05449bcc078
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Wed Jan 30 09:59:40 2019 +0100

    Range of valid values provided by the UCAR library are converted values, not packed values.
---
 .../org/apache/sis/internal/netcdf/Variable.java   | 28 ++++++++++++++--
 .../sis/internal/netcdf/ucar/VariableWrapper.java  | 15 ++++++---
 .../apache/sis/storage/netcdf/GridResource.java    | 39 ++++++++++------------
 3 files changed, 52 insertions(+), 30 deletions(-)

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 6a66ed9..1528a11 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
@@ -31,6 +31,7 @@ import org.apache.sis.coverage.grid.GridExtent;
 import org.apache.sis.math.Vector;
 import org.apache.sis.math.MathFunctions;
 import org.apache.sis.math.DecimalFunctions;
+import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.measure.NumberRange;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.ArraysExt;
@@ -469,6 +470,12 @@ public abstract class Variable extends NamedElement {
      *   <li>{@code "valid_max"}    — idem.</li>
      * </ol>
      *
+     * Whether the returned range is a range of packed values or a range of real values is
ambiguous.
+     * An heuristic rule is documented in UCAR {@link ucar.nc2.dataset.EnhanceScaleMissing}
interface.
+     * If both type of ranges are available, this method should return the range of packed
value.
+     * Otherwise if this method return the range of real values, then that range shall be
an instance
+     * of {@link MeasurementRange} for allowing the caller to distinguish the two cases.
+     *
      * @return the range of valid values, or {@code null} if unknown.
      */
     public NumberRange<?> getValidValues() {
@@ -497,9 +504,24 @@ public abstract class Variable extends NamedElement {
                 }
             }
             if (minimum != null && maximum != null) {
-                @SuppressWarnings({"unchecked", "rawtypes"})
-                final NumberRange<?> range = new NumberRange(type, minimum, true, maximum,
true);
-                return range;
+                /*
+                 * Heuristic rule defined in UCAR documentation (see EnhanceScaleMissing
interface):
+                 * if the type of the range is equal to the type of the scale, and the type
of the
+                 * data is not wider, then assume that the minimum and maximum are real values.
+                 */
+                final int rangeType = Numbers.getEnumConstant(type);
+                if (rangeType >= getDataType().number &&
+                    rangeType >= Math.max(Numbers.getEnumConstant(getAttributeType(CDM.SCALE_FACTOR)),
+                                          Numbers.getEnumConstant(getAttributeType(CDM.ADD_OFFSET))))
+                {
+                    @SuppressWarnings({"unchecked", "rawtypes"})
+                    final NumberRange<?> range = new MeasurementRange(type, minimum,
true, maximum, true, getUnit());
+                    return range;
+                } else {
+                    @SuppressWarnings({"unchecked", "rawtypes"})
+                    final NumberRange<?> range = new NumberRange(type, minimum, true,
maximum, true);
+                    return range;
+                }
             }
         }
         /*
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 8927cb1..0723d78 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
@@ -46,6 +46,7 @@ import org.apache.sis.internal.netcdf.VariableRole;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.util.logging.WarningListeners;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.measure.NumberRange;
 import org.apache.sis.measure.Units;
 
@@ -339,18 +340,22 @@ final class VariableWrapper extends Variable {
     }
 
     /**
-     * Returns the minimum and maximum values as determined by the UCAR library.
-     * If that library has not seen valid range, then fallbacks on Apache SIS.
+     * Returns the minimum and maximum values as determined by Apache SIS, using the UCAR
library as a fallback.
+     * This method gives precedence to the range computed by Apache SIS instead than the
range provided by UCAR
+     * because we need the range of packed values instead than the range of converted values.
Only if Apache SIS
+     * can not determine that range, we use the UCAR library and returns the value in a {@link
MeasurementRange}
+     * instance of signaling the caller that this is converted values.
      */
     @Override
     public NumberRange<?> getValidValues() {
-        if (variable instanceof EnhanceScaleMissing) {
+        NumberRange<?> range = super.getValidValues();
+        if (range == null && variable instanceof EnhanceScaleMissing) {
             final EnhanceScaleMissing ev = (EnhanceScaleMissing) variable;
             if (ev.hasInvalidData()) {
-                return NumberRange.create(ev.getValidMin(), true, ev.getValidMax(), true);
+                range = MeasurementRange.create(ev.getValidMin(), true, ev.getValidMax(),
true, getUnit());
             }
         }
-        return super.getValidValues();
+        return range;
 
     }
 
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/GridResource.java
b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/GridResource.java
index fdffc18..28b3bf7 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/GridResource.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/GridResource.java
@@ -46,6 +46,7 @@ import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.storage.DataStoreReferencingException;
 import org.apache.sis.storage.Resource;
 import org.apache.sis.math.MathFunctions;
+import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.measure.NumberRange;
 import org.apache.sis.util.Numbers;
 import org.apache.sis.util.resources.Errors;
@@ -281,32 +282,26 @@ final class GridResource extends AbstractGridResource implements ResourceOnFileS
             if (!Double.isNaN(scale))  tr.setScale (scale);
             if (!Double.isNaN(offset)) tr.setOffset(offset);
             final MathTransform1D mt = tr.getTransform();
-            if (!mt.isIdentity()) {
+            if (!mt.isIdentity() && range instanceof MeasurementRange<?>) {
                 /*
                  * Heuristic rule defined in UCAR documentation (see EnhanceScaleMissing
interface):
-                 * if the type of the range is equals to the type of the scale, and the type
of the
+                 * if the type of the range is equal to the type of the scale, and the type
of the
                  * data is not wider, then assume that the minimum and maximum are real values.
+                 * This is identified in Apache SIS by the range given as a MeasurementRange.
                  */
-                final int dataType  = data.getDataType().number;
-                final int rangeType = Numbers.getEnumConstant(range.getElementType());
-                if (rangeType >= dataType &&
-                    rangeType >= Math.max(Numbers.getEnumConstant(data.getAttributeType(CDM.SCALE_FACTOR)),
-                                          Numbers.getEnumConstant(data.getAttributeType(CDM.ADD_OFFSET))))
-                {
-                    final boolean isMinIncluded = range.isMinIncluded();
-                    final boolean isMaxIncluded = range.isMaxIncluded();
-                    double minimum = (range.getMinDouble() - offset) / scale;
-                    double maximum = (range.getMaxDouble() - offset) / scale;
-                    if (maximum > minimum) {
-                        final double swap = maximum;
-                        maximum = minimum;
-                        minimum = swap;
-                    }
-                    if (dataType < Numbers.FLOAT && minimum >= Long.MIN_VALUE
&& maximum <= Long.MAX_VALUE) {
-                        range = NumberRange.create(Math.round(minimum), isMinIncluded, Math.round(maximum),
isMaxIncluded);
-                    } else {
-                        range = NumberRange.create(minimum, isMinIncluded, maximum, isMaxIncluded);
-                    }
+                final boolean isMinIncluded = range.isMinIncluded();
+                final boolean isMaxIncluded = range.isMaxIncluded();
+                double minimum = (range.getMinDouble() - offset) / scale;
+                double maximum = (range.getMaxDouble() - offset) / scale;
+                if (maximum < minimum) {
+                    final double swap = maximum;
+                    maximum = minimum;
+                    minimum = swap;
+                }
+                if (data.getDataType().number < Numbers.FLOAT && minimum >=
Long.MIN_VALUE && maximum <= Long.MAX_VALUE) {
+                    range = NumberRange.create(Math.round(minimum), isMinIncluded, Math.round(maximum),
isMaxIncluded);
+                } else {
+                    range = NumberRange.create(minimum, isMinIncluded, maximum, isMaxIncluded);
                 }
             }
             String name = data.getDescription();


Mime
View raw message