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 2019/04/09 14:43:51 UTC
[sis] branch geoapi-4.0 updated: Resolve name collision in
RasterResource.identifier when two netCDF variables use the same
"standard_name" attribute value.
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 <ma...@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);