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 <[email protected]>
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);