You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2021/12/07 13:29:07 UTC

[sis] branch geoapi-4.0 updated: Partial workaround of unnamed netCDF dimensions considered equal. This workaround does not completely solve the problem because a fix relative to `ucar.nc2.dataset.CoordinateSystem` is also needed.

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 658a46a  Partial	workaround of unnamed netCDF dimensions considered equal. This workaround	does not completely solve the problem because a fix relative to `ucar.nc2.dataset.CoordinateSystem` is also needed.
658a46a is described below

commit 658a46a134ce39423995d6b6a274d032a0203502
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Tue Dec 7 14:25:30 2021 +0100

    Partial	workaround of unnamed netCDF dimensions considered equal.
    This workaround	does not completely solve the problem because a
    fix relative to `ucar.nc2.dataset.CoordinateSystem` is also needed.
    
    https://github.com/Unidata/netcdf-java/issues/951
---
 .../org/apache/sis/internal/netcdf/Convention.java |  2 +-
 .../org/apache/sis/internal/netcdf/Dimension.java  |  3 +-
 .../apache/sis/internal/netcdf/NamedElement.java   |  3 +-
 .../sis/internal/netcdf/ucar/DecoderWrapper.java   |  4 +-
 .../sis/internal/netcdf/ucar/DimensionWrapper.java | 53 ++++++++++++++++++----
 .../sis/internal/netcdf/ucar/package-info.java     |  2 +-
 6 files changed, 52 insertions(+), 15 deletions(-)

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 d73cf32..0fd1d73 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
@@ -280,7 +280,7 @@ public class Convention {
      *
      * @param  data  the variable for which the list of axis variables are desired, in CRS order.
      * @return names of the variables containing axis values, or {@code null} if this
-     *         method performs applies no special convention for the given variable.
+     *         method applies no special convention for the given variable.
      */
     public String[] namesOfAxisVariables(Variable data) {
         return null;
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Dimension.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Dimension.java
index daece51..26caff7 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Dimension.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Dimension.java
@@ -45,8 +45,9 @@ public abstract class Dimension extends NamedElement {
 
     /**
      * Returns the name of this netCDF dimension.
+     * Note that dimensions in HDF5 files may be unnamed.
      *
-     * @return the name of this netCDF dimension.
+     * @return the name of this netCDF dimension, or {@code null} if unnamed.
      */
     @Override
     public abstract String getName();
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/NamedElement.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/NamedElement.java
index 9ac2622..2a0c9cb 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/NamedElement.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/NamedElement.java
@@ -45,8 +45,9 @@ public abstract class NamedElement {
 
     /**
      * Returns the dimension, variable or attribute name.
+     * Note that dimensions in HDF5 files may be unnamed.
      *
-     * @return the name of this element.
+     * @return the name of this element, or {@code null} if unnamed.
      */
     public abstract String getName();
 
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
index 720b880..bdb3093 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DecoderWrapper.java
@@ -58,7 +58,7 @@ import org.apache.sis.storage.event.StoreListeners;
  * Provides netCDF decoding services based on the netCDF library.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.3
  * @module
  */
@@ -498,7 +498,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask {
     @Override
     protected Dimension findDimension(final String dimName) {
         final ucar.nc2.Dimension dimension = file.findDimension(dimName);
-        return (dimension != null) ? new DimensionWrapper(dimension) : null;
+        return (dimension != null) ? new DimensionWrapper(dimension, -1) : null;
     }
 
     /**
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DimensionWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DimensionWrapper.java
index fde99e4..caa7c54 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DimensionWrapper.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/DimensionWrapper.java
@@ -18,7 +18,8 @@ package org.apache.sis.internal.netcdf.ucar;
 
 import java.util.List;
 import java.util.Collection;
-import java.util.stream.Collectors;
+import org.apache.sis.internal.util.UnmodifiableArrayList;
+import org.apache.sis.util.ArraysExt;
 import ucar.nc2.Dimension;
 
 
@@ -29,7 +30,7 @@ import ucar.nc2.Dimension;
  *
  * @author  Johann Sorel (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   1.0
  * @module
  */
@@ -38,7 +39,13 @@ final class DimensionWrapper extends org.apache.sis.internal.netcdf.Dimension {
      * Wraps all given dimensions.
      */
     static List<org.apache.sis.internal.netcdf.Dimension> wrap(final Collection<Dimension> dimensions) {
-        return dimensions.stream().map(DimensionWrapper::new).collect(Collectors.toList());
+        final DimensionWrapper[] wrappers = new DimensionWrapper[dimensions.size()];
+        int i = 0;
+        for (final Dimension dim : dimensions) {
+            wrappers[i] = new DimensionWrapper(dim, i);
+            i++;
+        }
+        return UnmodifiableArrayList.wrap(ArraysExt.resize(wrappers, i));
     }
 
     /**
@@ -58,14 +65,26 @@ final class DimensionWrapper extends org.apache.sis.internal.netcdf.Dimension {
     private final Dimension netcdf;
 
     /**
+     * Index of the dimension in the variable, or -1 if unknown. Used during comparisons of
+     * dimensions that are private to a variable, because those dimensions may be unnamed.
+     * Consequently value -1 should be used only for shared dimensions.
+     *
+     * <a href="https://github.com/Unidata/netcdf-java/issues/951">Issue #951 on netcdf-java</a>
+     */
+    private final int index;
+
+    /**
      * Wraps the given netCDF dimension object.
      */
-    DimensionWrapper(final Dimension netcdf) {
+    DimensionWrapper(final Dimension netcdf, final int index) {
         this.netcdf = netcdf;
+        this.index  = index;
     }
 
     /**
-     * Returns the name of this netCDF dimension.
+     * Returns the name of this netCDF dimension, or {@code null} if none.
+     * Should always be non-null if {@link Dimension#isShared()} is {@code true},
+     * but may be null for non-shared dimensions (i.e. dimensions private to a variable).
      */
     @Override
     public String getName() {
@@ -91,22 +110,38 @@ final class DimensionWrapper extends org.apache.sis.internal.netcdf.Dimension {
 
     /**
      * Returns {@code true} if the given object represents the same dimension than this object.
+     * If the dimension is shared, then it has a unique name and {@link Dimension#equals(Object)}
+     * can distinguish dimensions based on their name. But if the dimension is private to a variable,
+     * then the dimension name can be null and the only remaining discriminant is the dimension length.
+     * A problem is that the length may by coincidence be the same for different dimensions.
+     * Consequently for non-shared dimensions we need to add {@link #index} in the comparison.
      *
-     * @param  other  the other object to compare with this dimension.
+     * @param  obj  the other object to compare with this dimension.
      * @return whether the other object wraps the same netCDF dimension than this object.
      */
     @Override
-    public boolean equals(final Object other) {
-        return (other instanceof DimensionWrapper) && netcdf.equals(((DimensionWrapper) other).netcdf);
+    public boolean equals(final Object obj) {
+        if (obj instanceof DimensionWrapper) {
+            final DimensionWrapper other = (DimensionWrapper) obj;
+            if (netcdf.equals(other.netcdf)) {
+                return netcdf.isShared() || other.index == index;
+            }
+        }
+        return false;
     }
 
     /**
      * Returns a hash code value for this dimension.
+     * See {@link #equals(Object)} for a discussion about the use of {@link #index}.
      *
      * @return a hash code value.
      */
     @Override
     public int hashCode() {
-        return ~netcdf.hashCode();
+        int code = ~netcdf.hashCode();
+        if (!netcdf.isShared()) {
+            code += 37 * index;
+        }
+        return code;
     }
 }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
index 105353e..533a115 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/package-info.java
@@ -20,7 +20,7 @@
  * as wrappers around the UCAR netCDF library.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 1.1
+ * @version 1.2
  * @since   0.3
  * @module
  */