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: Resolve name collision in RasterResource.identifier when two netCDF variables use the same "standard_name" attribute value.
Date Tue, 09 Apr 2019 14:43:51 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 fdf30a0  Resolve name collision in RasterResource.identifier when two netCDF variables
use the same "standard_name" attribute value.
fdf30a0 is described below

commit fdf30a0e8133ac5f67f4d1d1e033623bfaf4f5db
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Tue Apr 9 16:42:58 2019 +0200

    Resolve name collision in RasterResource.identifier when two netCDF variables use the
same "standard_name" attribute value.
---
 .../apache/sis/internal/netcdf/RasterResource.java | 46 +++++++++++++++++++---
 .../org/apache/sis/internal/netcdf/Variable.java   |  6 ++-
 2 files changed, 45 insertions(+), 7 deletions(-)

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 96259f8..e384680 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.HashMap;
 import java.util.ArrayList;
 import java.io.IOException;
 import java.nio.file.Path;
@@ -87,11 +88,16 @@ public final class RasterResource extends AbstractGridResource implements
Resour
     };
 
     /**
-     * The identifier of this grid resource. This is the variable name.
+     * The identifier of this grid resource. This is {@link Variable#getStandardName()}.
We prefer netCDF standard name instead
+     * than variable name because the former is controlled vocabulary. The use of controlled
vocabulary for identifiers increases
+     * the chances of stability or consistency between similar products.
+     *
+     * <p>The value set by constructor may be updated by {@link #resolveNameCollision(RasterResource,
Decoder)},
+     * but should not be modified after that point.</p>
      *
      * @see #getIdentifier()
      */
-    private final GenericName identifier;
+    private GenericName identifier;
 
     /**
      * The grid geometry (size, CRS…) of the {@linkplain #data} cube.
@@ -187,8 +193,9 @@ public final class RasterResource extends AbstractGridResource implements
Resour
     public static List<Resource> create(final Decoder decoder, final Object lock) throws
IOException, DataStoreException {
         assert Thread.holdsLock(lock);
         final Variable[]     variables = decoder.getVariables().clone();        // Needs
a clone because may be modified.
-        final List<Variable> siblings  = new ArrayList<>(4);
-        final List<Resource> resources = new ArrayList<>();
+        final List<Variable> siblings  = new ArrayList<>(4);                
   // Usually has only 1 element, sometime 2.
+        final List<Resource> resources = new ArrayList<>(variables.length); 
   // The raster resources to be returned.
+        final Map<GenericName,RasterResource> firstOfName = new HashMap<>();
   // For detecting name collisions.
         for (int i=0; i<variables.length; i++) {
             final Variable variable = variables[i];
             if (variable == null || variable.getRole() != VariableRole.COVERAGE) {
@@ -290,13 +297,40 @@ public final class RasterResource extends AbstractGridResource implements
Resour
                 }
                 numBands = siblings.size();
             }
-            resources.add(new RasterResource(decoder, name.trim(), grid, siblings, numBands,
bandDimension, lock));
+            final RasterResource r = new RasterResource(decoder, name.trim(), grid, siblings,
numBands, bandDimension, lock);
+            r.resolveNameCollision(firstOfName.putIfAbsent(r.identifier, r), decoder);
+            resources.add(r);
             siblings.clear();
         }
         return resources;
     }
 
     /**
+     * If the given resource is non-null, modifies the name of this resource for avoiding
name collision.
+     * The {@code other} resource shall be non-null when the caller detected that there is
a name collision
+     * with that resource.
+     *
+     * @param  other  the other resource for which there is a name collision, or {@code null}
if no collision.
+     */
+    private void resolveNameCollision(final RasterResource other, final Decoder decoder)
{
+        if (other != null) {
+            if (identifier.equals(other.identifier)) {
+                other.resolveNameCollision(decoder);
+            }
+            resolveNameCollision(decoder);
+        }
+    }
+
+    /**
+     * Invoked when the name of this resource needs to be changed because it collides with
the name of another resource.
+     * This method appends the variable name, which should be unique in each netCDF file.
+     */
+    private void resolveNameCollision(final Decoder decoder) {
+        String name = identifier + " (" + data[0].getName() + ')';
+        identifier = decoder.nameFactory.createLocalName(decoder.namespace, name);
+    }
+
+    /**
      * Returns the variable name as an identifier of this resource.
      */
     @Override
@@ -571,7 +605,7 @@ public final class RasterResource extends AbstractGridResource implements
Resour
             throw new DataStoreContentException(Errors.getResources(getLocale()).getString(Errors.Keys.UnsupportedType_1,
dataType.name()));
         }
         return new Raster(domain, UnmodifiableArrayList.wrap(bands), imageBuffer,
-                rangeIndices.getPixelStride(), bandOffsets, first.getStandardName());
+                rangeIndices.getPixelStride(), bandOffsets, String.valueOf(identifier));
     }
 
     /**
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 d009902..a0f9737 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
@@ -168,9 +168,13 @@ public abstract class Variable extends NamedElement {
 
     /**
      * Returns the standard name if available, or the long name other, or the ordinary name
otherwise.
-     * May be used as the label of a {@link Raster} as a whole (including all bands).
+     * May be used as the {@link RasterResource} label, or the label of a {@link Raster}
as a whole
+     * (including all bands). Standard name is preferred to variable name when controlled
vocabulary
+     * is desired, for example for more stable identifier or more consistency between similar
data.
      *
      * @return the standard name, or a fallback if there is no standard name.
+     *
+     * @see RasterResource#identifier
      */
     public final String getStandardName() {
         String name = getAttributeAsString(CF.STANDARD_NAME);


Mime
View raw message