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
commit c8abdcf8f0663bfabf3832893bda4cbc274ab0f7 Author: Martin Desruisseaux <[email protected]> AuthorDate: Fri Feb 22 16:19:44 2019 +0100 Move Variable.getNodataValues() implementation into Convention for allowing overriding. This move forces us to retain a reference to Decoder into Variable in order to get the conventions. --- .../java/org/apache/sis/measure/NumberRange.java | 4 +- .../java/org/apache/sis/internal/netcdf/Axis.java | 4 +- .../org/apache/sis/internal/netcdf/Convention.java | 46 ++++++++++++++ .../org/apache/sis/internal/netcdf/Dimension.java | 2 +- .../java/org/apache/sis/internal/netcdf/Grid.java | 4 +- .../org/apache/sis/internal/netcdf/Variable.java | 70 ++++++++++------------ .../sis/internal/netcdf/impl/ChannelDecoder.java | 4 +- .../apache/sis/internal/netcdf/impl/GridInfo.java | 4 +- .../sis/internal/netcdf/impl/VariableInfo.java | 39 ++++++------ .../sis/internal/netcdf/ucar/DecoderWrapper.java | 4 +- .../sis/internal/netcdf/ucar/GridWrapper.java | 2 +- .../sis/internal/netcdf/ucar/VariableWrapper.java | 15 +++-- .../apache/sis/storage/netcdf/GridResource.java | 37 +++++++----- 13 files changed, 139 insertions(+), 96 deletions(-) diff --git a/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java b/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java index 77be12c..6010bd1 100644 --- a/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java +++ b/core/sis-utility/src/main/java/org/apache/sis/measure/NumberRange.java @@ -309,7 +309,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range /** * Constructs a range using the smallest type of {@link Number} that can hold the given values. - * The given numbers don't need to be of the same type since they will + * The given numbers do not need to be of the same type since they will * be {@linkplain Numbers#cast(Number, Class) casted} as needed. * More specifically this method returns: * @@ -322,7 +322,7 @@ public class NumberRange<E extends Number & Comparable<? super E>> extends Range * {@value java.lang.Integer#MIN_VALUE} and {@value java.lang.Integer#MAX_VALUE} inclusive.</li> * <li>{@code NumberRange<Long>} if the given values are integers in the range of {@code long} values.</li> * <li>{@code NumberRange<Float>} if the given values can be casted to {@code float} values without data lost.</li> - * <li>{@code NumberRange<Double>} If none of the above types is suitable.</li> + * <li>{@code NumberRange<Double>} if none of the above types is suitable.</li> * </ul> * * This method may return a shared instance, at implementation choice. diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java index 65f139f..f9ca69b 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Axis.java @@ -656,8 +656,8 @@ main: switch (getDimension()) { /** * Reports a non-fatal error that occurred while constructing the grid geometry. This method is invoked * by methods that are themselves invoked (indirectly) by {@link Grid#getGridGeometry(Decoder)}, which - * is invoked by {@link Variable#getGridGeometry(Decoder)}. We pretend that the warning come from the - * later since it is a bit closer to a public API. + * is invoked by {@link Variable#getGridGeometry()}. We pretend that the warning come from the later + * since it is a bit closer to a public API. * * @param exception the exception that occurred, or {@code null} if none. * @param key one or {@link Errors.Keys} constants. 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 29a745e..8cfa6e6 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 @@ -16,7 +16,9 @@ */ package org.apache.sis.internal.netcdf; +import java.util.Map; import java.util.Iterator; +import java.util.LinkedHashMap; import java.awt.image.DataBuffer; import org.apache.sis.internal.referencing.LazySet; import org.apache.sis.referencing.operation.transform.TransferFunction; @@ -36,6 +38,7 @@ import ucar.nc2.constants.CDM; * * <blockquote><pre>META-INF/services/org.apache.sis.internal.netcdf.Convention</pre></blockquote> * + * Instances of this class must be immutable and thread-safe. * This class does not encapsulate all conventions needed for understanding a netCDF file, * but only conventions that are more likely to need to be overridden for some data producers. * @@ -86,6 +89,15 @@ public class Convention { }; /** + * Names of attributes where to fetch missing or pad values. Order matter since it determines the bits to be set in the + * map returned by {@link #nodataValues(Variable)}. The main bit is bit #0, which identifies the background value. + */ + private static final String[] NODATA_ATTRIBUTES = { + CDM.FILL_VALUE, + CDM.MISSING_VALUE + }; + + /** * For subclass constructors. */ protected Convention() { @@ -375,12 +387,46 @@ public class Convention { } /** + * Returns all no-data values declared for the given variable, or an empty map if none. + * The map keys are the no-data values (pad sample values or missing sample values). + * The map values can be either {@link String} or {@link org.opengis.util.InternationalString} values + * containing the description of the no-data value, or an {@link Integer} set to a bitmask identifying + * the role of the pad/missing sample value: + * + * <ul> + * <li>If bit 0 is set, then the value is a pad value. Those values can be used for background.</li> + * <li>If bit 1 is set, then the value is a missing value.</li> + * </ul> + * + * Pad values should be first in the map, followed by missing values. + * The same value may have more than one role. + * + * @param data the variable for which to get no-data values. + * @return no-data values with bitmask of their roles or textual descriptions. + */ + public Map<Number,Object> nodataValues(final Variable data) { + final Map<Number,Object> pads = new LinkedHashMap<>(); + for (int i=0; i < NODATA_ATTRIBUTES.length; i++) { + for (final Object value : data.getAttributeValues(NODATA_ATTRIBUTES[i], true)) { + if (value instanceof Number) { + pads.merge((Number) value, 1 << i, (v1, v2) -> ((Integer) v1) | ((Integer) v2)); + } + } + } + return pads; + } + + /** * Builds the function converting values from their packed formats in the variable to "real" values. * The transfer function is typically built from the {@code "scale_factor"} and {@code "add_offset"} * attributes associated to the given variable, but other conventions could use different attributes. * The returned function will be a component of the {@link org.apache.sis.coverage.SampleDimension} * to be created for each variable. * + * <p>This method is invoked only if {@link #validRange(Variable)} returned a non-null value. + * Since a transfer function is assumed to exist in such case (even if that function is identity), + * this method shall never return {@code null}.</p> + * * @param data the variable from which to determine the transfer function. * This is usually a variable containing raster data. * 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 969ab4b..0b13627 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 @@ -28,7 +28,7 @@ import org.apache.sis.util.resources.Vocabulary; * and {@code Dimension.equals(object)} must return {@code true} if two {@code Dimension} * instances represent the same netCDF dimensions. This may require subclasses to override * {@link #hashCode()} and {@link #equals(Object)} if uniqueness is not guaranteed. - * This is needed by {@link Variable#getGrid(Decoder)} default implementation.</p> + * This is needed by {@link Variable#getGrid()} default implementation.</p> * * @author Johann Sorel (Geomatys) * @author Martin Desruisseaux (Geomatys) diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Grid.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Grid.java index 91c7943..07c5a1b 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Grid.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/Grid.java @@ -106,8 +106,8 @@ public abstract class Grid extends NamedElement { /** * Returns a localization grid having the same dimensions than this grid but in a different order. - * This method is invoked by {@link Variable#getGrid(Decoder)} when the localization grids created - * by {@link Decoder} subclasses are not sufficient and must be tailored for a particular variable. + * This method is invoked by {@link Variable#getGrid()} when the localization grids created by + * {@link Decoder} subclasses are not sufficient and must be tailored for a particular variable. * Subclasses should verify that the given {@code dimensions} array meets the following conditions: * * <ul> 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 4ca118c..a6dfaaf 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 @@ -20,7 +20,6 @@ import java.util.Set; import java.util.Map; import java.util.HashSet; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Collection; import java.util.List; import java.util.ArrayList; @@ -42,7 +41,6 @@ import org.apache.sis.util.ArraysExt; import org.apache.sis.util.collection.WeakHashSet; import org.apache.sis.internal.util.Numerics; import org.apache.sis.internal.util.CollectionsExt; -import org.apache.sis.util.logging.WarningListeners; import org.apache.sis.util.resources.Errors; import ucar.nc2.constants.CDM; // We use only String constants. import ucar.nc2.constants.CF; @@ -68,13 +66,9 @@ public abstract class Variable extends NamedElement { protected static final WeakHashSet<Vector> SHARED_VECTORS = new WeakHashSet<>(Vector.class); /** - * Names of attributes where to fetch missing or pad values. Order matter since it determines the bits to be set - * in the map returned by {@link #getNodataValues()}. The main bit is bit 0, which identify the background value. + * The netCDF file where this variable is stored. */ - private static final String[] NODATA_ATTRIBUTES = { - CDM.FILL_VALUE, - CDM.MISSING_VALUE - }; + protected final Decoder decoder; /** * The pattern to use for parsing temporal units of the form "days since 1970-01-01 00:00:00". @@ -111,8 +105,11 @@ public abstract class Variable extends NamedElement { /** * All no-data values declared for this variable, or an empty map if none. * This is computed by {@link #getNodataValues()} and cached for efficiency and stability. + * The meaning of entries in this map is described in {@code getNodataValues()} method javadoc. + * + * @see #getNodataValues() */ - private Map<Number,Integer> nodataValues; + private Map<Number,Object> nodataValues; /** * Factors by which to multiply a grid index in order to get the corresponding data index, or {@code null} if none. @@ -126,17 +123,12 @@ public abstract class Variable extends NamedElement { private double[] gridToDataIndices; /** - * Where to report warnings, if any. - */ - private final WarningListeners<?> listeners; - - /** * Creates a new variable. * - * @param listeners where to report warnings. + * @param decoder the netCDF file where this variable is stored. */ - protected Variable(final WarningListeners<?> listeners) { - this.listeners = listeners; + protected Variable(final Decoder decoder) { + this.decoder = decoder; } /** @@ -145,7 +137,9 @@ public abstract class Variable extends NamedElement { * * @return name of the netCDF file containing this variable, or {@code null} if unknown. */ - public abstract String getFilename(); + public String getFilename() { + return decoder.getFilename(); + } /** * Returns the name of this variable. @@ -337,12 +331,11 @@ public abstract class Variable extends NamedElement { * Subclasses should override this class with a more direct implementation and invoke this implementation only as a fallback. * Typically, subclasses will handle case #1 in above list and this implementation is invoked for case #2. * - * @param decoder the decoder to use for constructing the grid geometry if needed. * @return the grid geometry for this variable, or {@code null} if none. * @throws IOException if an error occurred while reading the data. * @throws DataStoreException if a logical error occurred. */ - protected Grid getGrid(final Decoder decoder) throws IOException, DataStoreException { + protected Grid getGrid() throws IOException, DataStoreException { final Convention convention = decoder.convention(); /* * Collect all axis dimensions, in no particular order. We use this map for determining @@ -465,13 +458,12 @@ public abstract class Variable extends NamedElement { * Not all variables have a grid geometry. For example collections of features do not have such grid. * The same grid geometry may be shared by many variables. * - * @param decoder the decoder to use for constructing the grid geometry if needed. * @return the grid geometry for this variable, or {@code null} if none. * @throws IOException if an error occurred while reading the data. * @throws DataStoreException if a logical error occurred. */ - public final GridGeometry getGridGeometry(final Decoder decoder) throws IOException, DataStoreException { - final Grid info = getGrid(decoder); + public final GridGeometry getGridGeometry() throws IOException, DataStoreException { + final Grid info = getGrid(); if (info == null) { return null; } @@ -663,34 +655,30 @@ public abstract class Variable extends NamedElement { /** * Returns all no-data values declared for this variable, or an empty map if none. - * The map keys are pad sample values or missing sample values. The map values are - * bitmask identifying the role of the pad/missing sample value: + * The map keys are the no-data values (pad sample values or missing sample values). + * The map values can be either {@link String} or {@link org.opengis.util.InternationalString} values + * containing the description of the no-data value, or an {@link Integer} set to a bitmask identifying + * the role of the pad/missing sample value: * * <ul> * <li>If bit 0 is set, then the value is a pad value. Those values can be used for background.</li> * <li>If bit 1 is set, then the value is a missing value.</li> * </ul> * - * Pad values are first in the map, followed by missing values. + * Pad values should be first in the map, followed by missing values. * The same value may have more than one role. * The map returned by this method shall be stable, i.e. two invocations of this method shall return the * same entries in the same order. This is necessary for mapping "no data" values to the same NaN values, * since their {@linkplain MathFunctions#toNanFloat(int) ordinal values} are based on order. * * @return pad/missing values with bitmask of their role. + * + * @see Convention#nodataValues(Variable) */ @SuppressWarnings("ReturnOfCollectionOrArrayField") - public final Map<Number,Integer> getNodataValues() { + public final Map<Number,Object> getNodataValues() { if (nodataValues == null) { - final Map<Number,Integer> pads = new LinkedHashMap<>(); - for (int i=0; i < NODATA_ATTRIBUTES.length; i++) { - for (final Object value : getAttributeValues(NODATA_ATTRIBUTES[i], true)) { - if (value instanceof Number) { - pads.merge((Number) value, 1 << i, (v1, v2) -> v1 | v2); - } - } - } - nodataValues = CollectionsExt.unmodifiableOrCopy(pads); + nodataValues = CollectionsExt.unmodifiableOrCopy(decoder.convention().nodataValues(this)); } return nodataValues; } @@ -854,9 +842,11 @@ public abstract class Variable extends NamedElement { /** * Returns the locale to use for warnings and error messages. + * + * @return the locale for warnings and error messages. */ - final Locale getLocale() { - return listeners.getLocale(); + protected final Locale getLocale() { + return decoder.listeners.getLocale(); } /** @@ -877,7 +867,7 @@ public abstract class Variable extends NamedElement { * @param arguments values to be formatted in the {@link java.text.MessageFormat} pattern. */ protected final void warning(final Class<?> caller, final String method, final short key, final Object... arguments) { - warning(listeners, caller, method, null, null, key, arguments); + warning(decoder.listeners, caller, method, null, null, key, arguments); } /** @@ -890,7 +880,7 @@ public abstract class Variable extends NamedElement { * @param arguments values to be formatted in the {@link java.text.MessageFormat} pattern. */ final void error(final Class<?> caller, final String method, final Exception exception, final short key, final Object... arguments) { - warning(listeners, caller, method, exception, Errors.getResources(listeners.getLocale()), key, arguments); + warning(decoder.listeners, caller, method, exception, Errors.getResources(getLocale()), key, arguments); } /** diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java index 42f0d92..7ce2a53 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java @@ -609,8 +609,8 @@ public final class ChannelDecoder extends Decoder { default: throw malformedHeader(); } } - variables[j] = new VariableInfo(input, name, varDims, attributes, - DataType.valueOf(input.readInt()), input.readInt(), readOffset(), listeners); + variables[j] = new VariableInfo(this, input, name, varDims, attributes, + DataType.valueOf(input.readInt()), input.readInt(), readOffset()); } /* * The VariableInfo constructor determined if the variables are "unlimited" or not. diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridInfo.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridInfo.java index 90aeb08..f232f86 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridInfo.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/GridInfo.java @@ -109,8 +109,8 @@ final class GridInfo extends Grid { /** * Returns a localization grid having the same dimensions than this grid but in a different order. - * This method is invoked by {@link VariableInfo#getGrid(Decoder)} when the localization grids created - * by {@link Decoder} subclasses are not sufficient and must be tailored for a particular variable. + * This method is invoked by {@link VariableInfo#getGrid()} when the localization grids created by + * {@link Decoder} subclasses are not sufficient and must be tailored for a particular variable. * Returns {@code null} the the given dimensions are not members of this grid. */ @Override diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java index 15b3586..d2d9f09 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java @@ -45,7 +45,6 @@ import org.apache.sis.internal.util.UnmodifiableArrayList; import org.apache.sis.storage.DataStoreException; import org.apache.sis.storage.DataStoreContentException; import org.apache.sis.storage.netcdf.AttributeNames; -import org.apache.sis.util.logging.WarningListeners; import org.apache.sis.util.CharSequences; import org.apache.sis.util.ArraysExt; import org.apache.sis.util.Numbers; @@ -152,16 +151,16 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> { * computed by {@link ChannelDecoder#getGrids()} when first needed. * May stay {@code null} if the variable is not a data cube. * - * @see #getGrid(Decoder) + * @see #getGrid() */ GridInfo grid; /** * For disambiguation of the case where {@link #grid} has been computed and the result still null. - * The that {@link #grid} may be determined and non-null even if this flag is {@code false}. + * Note that {@link #grid} may be determined and non-null even if this flag is {@code false}. * * @see #grid - * @see #getGrid(Decoder) + * @see #getGrid() */ private transient boolean gridDetermined; @@ -191,6 +190,7 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> { /** * Creates a new variable. * + * @param decoder the netCDF file where this variable is stored. * @param input the channel together with a buffer for reading the variable data. * @param name the variable name. * @param dimensions the dimensions of this variable. @@ -198,20 +198,19 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> { * @param dataType the netCDF type of data, or {@code null} if unknown. * @param size the variable size. May be inaccurate and ignored. * @param offset the offset where the variable data begins in the netCDF file. - * @param listeners where to report warnings, if any. * @throws ArithmeticException if the variable size exceeds {@link Long#MAX_VALUE}. * @throws DataStoreContentException if a logical error is detected. */ - VariableInfo(final ChannelDataInput input, - final String name, - final DimensionInfo[] dimensions, - final Map<String,Object> attributes, - DataType dataType, - final int size, - final long offset, - final WarningListeners<?> listeners) throws DataStoreContentException + VariableInfo(final Decoder decoder, + final ChannelDataInput input, + final String name, + final DimensionInfo[] dimensions, + final Map<String,Object> attributes, + DataType dataType, + final int size, + final long offset) throws DataStoreContentException { - super(listeners); + super(decoder); this.name = name; this.dimensions = dimensions; this.attributes = attributes; @@ -232,7 +231,7 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> { offsetToNextRecord = Math.multiplyExact(offsetToNextRecord, dim.length()); } else if (i != 0) { // Unlimited dimension, if any, must be first in a netCDF 3 classic format. - throw new DataStoreContentException(listeners.getLocale(), Decoder.FORMAT_NAME, input.filename, null); + throw new DataStoreContentException(getLocale(), Decoder.FORMAT_NAME, input.filename, null); } } reader = new HyperRectangleReader(dataType.number, input, offset); @@ -368,7 +367,11 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> { */ @Override public String getFilename() { - return (reader != null) ? reader.filename() : null; + if (reader != null) { + final String filename = reader.filename(); + if (filename != null) return filename; + } + return super.getFilename(); } /** @@ -483,12 +486,12 @@ final class VariableInfo extends Variable implements Comparable<VariableInfo> { * @see ChannelDecoder#getGrids() */ @Override - protected Grid getGrid(final Decoder decoder) throws IOException, DataStoreException { + protected Grid getGrid() throws IOException, DataStoreException { if (grid == null && !gridDetermined) { gridDetermined = true; // Set first for avoiding other attempts in case of failure. decoder.getGrids(); // Force calculation of grid geometries if not already done. if (grid == null) { // May have been computed as a side-effect of decoder.getGrids(). - grid = (GridInfo) super.getGrid(decoder); // Non-null if grid dimensions are different than this variable. + grid = (GridInfo) super.getGrid(); // Non-null if grid dimensions are different than this variable. } } return grid; 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 5dd644e..a6963ca 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 @@ -388,7 +388,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask { final List<? extends VariableIF> all = file.getVariables(); variables = new VariableWrapper[(all != null) ? all.size() : 0]; for (int i=0; i<variables.length; i++) { - variables[i] = new VariableWrapper(listeners, all.get(i)); + variables[i] = new VariableWrapper(this, all.get(i)); } } return variables; @@ -405,7 +405,7 @@ public final class DecoderWrapper extends Decoder implements CancelTask { } } // We should not reach this point, but let be safe. - return new VariableWrapper(listeners, variable); + return new VariableWrapper(this, variable); } /** diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridWrapper.java b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridWrapper.java index 26d1220..e9eb3c0 100644 --- a/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridWrapper.java +++ b/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/ucar/GridWrapper.java @@ -97,7 +97,7 @@ final class GridWrapper extends Grid { /** * Returns a localization grid having the same dimensions than this grid but in a different order. - * This method is invoked by {@link VariableWrapper#getGrid(Decoder)} when the localization grids created + * This method is invoked by {@link VariableWrapper#getGrid()} when the localization grids created * by {@link Decoder} subclasses are not sufficient and must be tailored for a particular variable. * Returns {@code null} the the given dimensions are not members of this grid. */ 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 6593a30..83b1e44 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 @@ -42,7 +42,6 @@ import org.apache.sis.internal.netcdf.Decoder; import org.apache.sis.internal.netcdf.Grid; import org.apache.sis.internal.netcdf.Variable; 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; @@ -85,7 +84,7 @@ final class VariableWrapper extends Variable { * The grid needs to be computed if {@link #gridDetermined} is {@code false}. * * @see #gridDetermined - * @see #getGrid(Decoder) + * @see #getGrid() */ private transient GridWrapper grid; @@ -93,15 +92,15 @@ final class VariableWrapper extends Variable { * Whether {@link #grid} has been computed. Note that the result may still null. * * @see #grid - * @see #getGrid(Decoder) + * @see #getGrid() */ private transient boolean gridDetermined; /** * Creates a new variable wrapping the given netCDF interface. */ - VariableWrapper(final WarningListeners<?> listeners, VariableIF v) { - super(listeners); + VariableWrapper(final Decoder decoder, VariableIF v) { + super(decoder); variable = v; if (v instanceof VariableEnhanced) { v = ((VariableEnhanced) v).getOriginalVariable(); @@ -123,7 +122,7 @@ final class VariableWrapper extends Variable { return name.substring(Math.max(name.lastIndexOf('/'), name.lastIndexOf(File.separatorChar)) + 1); } } - return null; + return super.getFilename(); } /** @@ -247,7 +246,7 @@ final class VariableWrapper extends Variable { * @see DecoderWrapper#getGrids() */ @Override - protected Grid getGrid(final Decoder decoder) throws IOException, DataStoreException { + protected Grid getGrid() throws IOException, DataStoreException { if (!gridDetermined) { gridDetermined = true; // Set first so we don't try twice in case of failure. /* @@ -273,7 +272,7 @@ final class VariableWrapper extends Variable { * can map to the variable dimension using attribute values. This mechanism is described * in Convention.nameOfDimension(…). */ - grid = (GridWrapper) super.getGrid(decoder); + grid = (GridWrapper) super.getGrid(); } return grid; } 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 d4b015f..611b534 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 @@ -24,7 +24,6 @@ import java.nio.file.Path; import java.nio.Buffer; import java.awt.image.DataBuffer; import org.opengis.util.GenericName; -import org.opengis.util.InternationalString; import org.opengis.referencing.operation.MathTransform1D; import org.opengis.referencing.operation.TransformException; import org.apache.sis.coverage.grid.GridGeometry; @@ -166,7 +165,7 @@ final class GridResource extends AbstractGridResource implements ResourceOnFileS if (decoder.convention().roleOf(variable) != VariableRole.COVERAGE) { continue; // Skip variables that are not grid coverages. } - final GridGeometry grid = variable.getGridGeometry(decoder); + final GridGeometry grid = variable.getGridGeometry(); if (grid == null) { continue; // Skip variables that are not grid coverages. } @@ -198,7 +197,7 @@ final class GridResource extends AbstractGridResource implements ResourceOnFileS final String cn = candidate.getStandardName(); if (cn.regionMatches(cn.length() - suffixLength, name, suffixStart, suffixLength) && cn.regionMatches(0, name, 0, prefixLength) && candidate.getDataType() == type && - grid.equals(candidate.getGridGeometry(decoder))) + grid.equals(candidate.getGridGeometry())) { /* * Found another variable with the same name except for the keyword. Verify that the @@ -330,27 +329,33 @@ final class GridResource extends AbstractGridResource implements ResourceOnFileS */ boolean setBackground = true; int ordinal = data.hasRealValues() ? 0 : -1; - final InternationalString[] names = new InternationalString[2]; - for (final Map.Entry<Number,Integer> entry : data.getNodataValues().entrySet()) { + final CharSequence[] names = new CharSequence[2]; + for (final Map.Entry<Number,Object> entry : data.getNodataValues().entrySet()) { final Number n; if (ordinal >= 0) { n = MathFunctions.toNanFloat(ordinal++); // Must be consistent with Variable.replaceNaN(Object). } else { n = entry.getKey(); // Should be real number, made unique by the HashMap. } - final int role = entry.getValue(); // Bit 0 set (value 1) = pad value, bit 1 set = missing value. - final int i = (role == 1) ? 1 : 0; // i=1 if role is only pad value, i=0 otherwise. - InternationalString name = names[i]; - if (name == null) { - name = Vocabulary.formatInternational(i == 0 ? Vocabulary.Keys.MissingValue : Vocabulary.Keys.FillValue); - names[i] = name; - } - if (setBackground & (role & 1) != 0) { - setBackground = false; // Declare only one fill value. - builder.setBackground(name, n); + CharSequence name; + final Object label = entry.getValue(); + if (label instanceof Integer) { + final int role = (Integer) label; // Bit 0 set (value 1) = pad value, bit 1 set = missing value. + final int i = (role == 1) ? 1 : 0; // i=1 if role is only pad value, i=0 otherwise. + name = names[i]; + if (name == null) { + name = Vocabulary.formatInternational(i == 0 ? Vocabulary.Keys.MissingValue : Vocabulary.Keys.FillValue); + names[i] = name; + } + if (setBackground & (role & 1) != 0) { + setBackground = false; // Declare only one fill value. + builder.setBackground(name, n); + continue; + } } else { - builder.addQualitative(name, n, n); + name = (CharSequence) label; } + builder.addQualitative(name, n, n); } return builder.setName(data.getName()).build(); }
