sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1763108 - in /sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl: ChannelDecoder.java FeaturesInfo.java VariableInfo.java
Date Sun, 02 Oct 2016 22:57:03 GMT
Author: desruisseaux
Date: Sun Oct  2 22:57:03 2016
New Revision: 1763108

URL: http://svn.apache.org/viewvc?rev=1763108&view=rev
Log:
Move findDimension(String) method from Variable to Decoder.
Search harder for the variable having the "cf_role" attribute.
Use Vector.range() for finding the maximal value.

Modified:
    sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
    sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/FeaturesInfo.java
    sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java

Modified: sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java?rev=1763108&r1=1763107&r2=1763108&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/ChannelDecoder.java
[UTF-8] Sun Oct  2 22:57:03 2016
@@ -181,12 +181,21 @@ public final class ChannelDecoder extend
 
     /**
      * The attributes found in the NetCDF file.
+     * Values in this map give directly the attribute value (there is no {@code Attribute}
object).
      *
      * @see #findAttribute(String)
      */
     private final Map<String,Object> attributeMap;
 
     /**
+     * All dimensions in the NetCDF files.
+     *
+     * @see #readDimensions(int)
+     * @see #findDimension(String)
+     */
+    private Map<String,Dimension> dimensionMap;
+
+    /**
      * The grid geometries, created when first needed.
      *
      * @see #getGridGeometries()
@@ -463,6 +472,7 @@ public final class ChannelDecoder extend
             }
             dimensions[i] = new Dimension(name, length);
         }
+        dimensionMap = Dimension.toCaseInsensitiveNameMap(dimensions, NAME_LOCALE);
         return dimensions;
     }
 
@@ -520,7 +530,6 @@ public final class ChannelDecoder extend
         if (allDimensions == null) {
             throw malformedHeader();        // May happen if readDimensions(…) has not
been invoked.
         }
-        final Map<String,Dimension> dimByNames = Dimension.toCaseInsensitiveNameMap(allDimensions,
NAME_LOCALE);
         final VariableInfo[] variables = new VariableInfo[nelems];
         for (int j=0; j<nelems; j++) {
             final String name = readName();
@@ -551,7 +560,7 @@ public final class ChannelDecoder extend
                     default:        throw malformedHeader();
                 }
             }
-            variables[j] = new VariableInfo(input, name, varDims, dimByNames, attributes,
+            variables[j] = new VariableInfo(input, name, varDims, attributes,
                     DataType.valueOf(input.readInt()), input.readInt(), readOffset());
         }
         return variables;
@@ -598,6 +607,25 @@ public final class ChannelDecoder extend
     }
 
     /**
+     * Returns the dimension of the given name (eventually ignoring case), or {@code null}
if none.
+     * This method searches in all dimensions found in the NetCDF file, regardless of variables.
+     * The search will ignore case only if no exact match is found for the given name.
+     *
+     * @param  dimName  the name of the dimension to search.
+     * @return dimension of the given name, or {@code null} if none.
+     */
+    final Dimension findDimension(final String dimName) {
+        Dimension dim = dimensionMap.get(dimName);         // Give precedence to exact match
before to ignore case.
+        if (dim == null) {
+            final String lower = dimName.toLowerCase(ChannelDecoder.NAME_LOCALE);
+            if (lower != dimName) {                         // Identity comparison is okay
here.
+                dim = dimensionMap.get(lower);
+            }
+        }
+        return dim;
+    }
+
+    /**
      * Returns the NetCDF variable of the given name, or {@code null} if none.
      *
      * @param  name  the name of the variable to search, or {@code null}.

Modified: sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/FeaturesInfo.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/FeaturesInfo.java?rev=1763108&r1=1763107&r2=1763108&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/FeaturesInfo.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/FeaturesInfo.java
[UTF-8] Sun Oct  2 22:57:03 2016
@@ -56,20 +56,23 @@ final class FeaturesInfo extends Discret
      */
     private FeaturesInfo(final Vector cpf, final VariableInfo identifiers) {
         final int n = cpf.size();
-        int max = 1;
-        for (int i=0; i<n; i++) {
-            final int v = cpf.intValue(i);
-            if (v > max) max = v;
+        int max = cpf.range().getMaxValue().intValue();
+        if (max <= 0) {
+            max = Integer.MAX_VALUE;
         }
         counts = new IntegerList(n, max);
         for (int i=0; i<n; i++) {
             counts.addInt(cpf.intValue(i));
         }
         this.identifiers = identifiers;
-        final Object role = identifiers.getAttributeValue(CF.CF_ROLE);
-        if (role instanceof String && ((String) role).equalsIgnoreCase(CF.TRAJECTORY_ID))
{
-            // TODO
-        }
+    }
+
+    /**
+     * Returns {@code true} if the given attribute value is one of the {@code cf_role} attribute
values
+     * supported by this implementation.
+     */
+    private static boolean isSupportedRole(final Object role) {
+        return (role instanceof String) && ((String) role).equalsIgnoreCase(CF.TRAJECTORY_ID);
     }
 
     /**
@@ -78,22 +81,66 @@ final class FeaturesInfo extends Discret
     static FeaturesInfo[] create(final ChannelDecoder decoder) throws IOException, DataStoreException
{
         final List<FeaturesInfo> features = new ArrayList<>(3);     // Will usually
contain at most one element.
 search: for (final VariableInfo counts : decoder.variables) {
+            /*
+             * Any one-dimensional integer variable having a "sample_dimension" attribute
string value
+             * will be taken as an indication that we have Discrete Sampling Geometries.
That variable
+             * shall be counting the number of feature instances, and another variable having
the same
+             * dimension (optionally plus a character dimension) shall give the feature identifiers.
+             * Example:
+             *
+             *     dimensions:
+             *         identifiers = 100;
+             *         points = UNLIMITED;
+             *     variables:
+             *         int identifiers(identifiers);
+             *             identifiers:cf_role = "trajectory_id";
+             *         int counts(identifiers);
+             *             counts:sample_dimension = "points";
+             */
             if (counts.dimensions.length == 1 && counts.getDataType().isInteger)
{
                 final Object sampleDimName = counts.getAttributeValue(CF.SAMPLE_DIMENSION);
                 if (sampleDimName instanceof String) {
-                    /*
-                     * Any one-dimensional integer variable having a "sample_dimension" attribute
string value
-                     * will be taken as an indication that we have Discrete Sampling Geometries.
That variable
-                     * shall be counting the number of feature instances, and another variable
having the same
-                     * dimension (optionally plus a character dimension) shall give the feature
identifiers.
-                     */
                     final Dimension featureDimension = counts.dimensions[0];
-                    final VariableInfo identifiers = decoder.findVariable(featureDimension.name);
-                    if (identifiers == null) {
-                        decoder.listeners.warning(decoder.resources().getString(Resources.Keys.VariableNotFound_2,
-                                decoder.getFilename(), featureDimension.name), null);
+                    final Dimension sampleDimension = decoder.findDimension((String) sampleDimName);
+                    if (sampleDimension == null) {
+                        decoder.listeners.warning(decoder.resources().getString(Resources.Keys.DimensionNotFound_3,
+                                decoder.getFilename(), counts.getName(), sampleDimName),
null);
                         continue;
                     }
+                    /*
+                     * We should have another variable of the same name than the feature
dimension name
+                     * ("identifiers" in above example). That variable should have a "cf_role"
attribute
+                     * set to one of the values known to current implementation.  If we do
not find such
+                     * variable, search among other variables before to give up. That second
search is not
+                     * part of CF convention and will be accepted only if there is no ambiguity.
+                     */
+                    VariableInfo identifiers = decoder.findVariable(featureDimension.name);
+                    if (identifiers == null || !isSupportedRole(identifiers.getAttributeValue(CF.CF_ROLE)))
{
+                        VariableInfo replacement = null;
+                        for (final VariableInfo alt : decoder.variables) {
+                            if (alt.dimensions.length != 0 && alt.dimensions[0] ==
featureDimension
+                                    && isSupportedRole(alt.getAttributeValue(CF.CF_ROLE)))
+                            {
+                                if (replacement != null) {
+                                    replacement = null;
+                                    break;                  // Ambiguity found: consider
that we found no replacement.
+                                }
+                                replacement = alt;
+                            }
+                        }
+                        if (replacement != null) {
+                            identifiers = replacement;
+                        }
+                        if (identifiers == null) {
+                            decoder.listeners.warning(decoder.resources().getString(Resources.Keys.VariableNotFound_2,
+                                    decoder.getFilename(), featureDimension.name), null);
+                            continue;
+                        }
+                    }
+                    /*
+                     * At this point we found a variable that should be the feature identifiers.
+                     * Verify that the variable dimensions are valid.
+                     */
                     for (int i=0; i<identifiers.dimensions.length; i++) {
                         final boolean isValid;
                         switch (i) {
@@ -110,16 +157,8 @@ search: for (final VariableInfo counts :
                         }
                     }
                     /*
-                     * The "sample_dimension" attribute value shall be the name of a dimension.
-                     * Those dimensions are associated to other variables (not the count
one),
-                     * but the 'findDimension' method below searches in all dimensions.
+                     * At this point, all information has been verified as valid.
                      */
-                    final Dimension sampleDim = counts.findDimension((String) sampleDimName);
-                    if (sampleDim == null) {
-                        decoder.listeners.warning(decoder.resources().getString(Resources.Keys.DimensionNotFound_3,
-                                decoder.getFilename(), counts.getName(), sampleDimName),
null);
-                        continue;
-                    }
                     features.add(new FeaturesInfo(counts.read(), identifiers));
                 }
             }

Modified: sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java?rev=1763108&r1=1763107&r2=1763108&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-netcdf/src/main/java/org/apache/sis/internal/netcdf/impl/VariableInfo.java
[UTF-8] Sun Oct  2 22:57:03 2016
@@ -80,11 +80,6 @@ final class VariableInfo extends Variabl
     final Dimension[] dimensions;
 
     /**
-     * All dimensions in the NetCDF files.
-     */
-    private final Map<String,Dimension> allDimensions;
-
-    /**
      * The attributes associates to the variable, or an empty map if none.
      * Values can be:
      *
@@ -129,7 +124,6 @@ final class VariableInfo extends Variabl
      * @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.
-     * @param  allDimensions  all dimensions in the NetCDF files.
      * @param  attributes     the attributes associates to the variable, or an empty map
if none.
      * @param  dataType       the NetCDF type of data, or {@code null} if unknown.
      * @param  size           the variable size, used for verification purpose only.
@@ -138,7 +132,6 @@ final class VariableInfo extends Variabl
     VariableInfo(final ChannelDataInput      input,
                  final String                name,
                  final Dimension[]           dimensions,
-                 final Map<String,Dimension> allDimensions,
                  final Map<String,Object>    attributes,
                        DataType              dataType,
                  final int                   size,
@@ -148,11 +141,10 @@ final class VariableInfo extends Variabl
         if (isUnsigned != null) {
             dataType = dataType.unsigned(booleanValue(isUnsigned));
         }
-        this.name          = name;
-        this.dimensions    = dimensions;
-        this.allDimensions = allDimensions;
-        this.attributes    = attributes;
-        this.dataType      = dataType;
+        this.name       = name;
+        this.dimensions = dimensions;
+        this.attributes = attributes;
+        this.dataType   = dataType;
         /*
          * The 'size' value is provided in the NetCDF files, but doesn't need to be stored
since it
          * is redundant with the dimension lengths and is not large enough for big variables
anyway.
@@ -270,26 +262,6 @@ final class VariableInfo extends Variabl
     }
 
     /**
-     * Returns the dimension of the given name (eventually ignoring case), or {@code null}
if none.
-     * This method searches in all dimensions found in the NetCDF file,
-     * regardless of whether the dimension is used by this variable or not.
-     * The search will ignore case only if no exact match is found for the given name.
-     *
-     * @param  dimName  the name of the dimension to search.
-     * @return dimension of the given name, or {@code null} if none.
-     */
-    final Dimension findDimension(final String dimName) {
-        Dimension dim = allDimensions.get(dimName);         // Give precedence to exact match
before to ignore case.
-        if (dim == null) {
-            final String lower = dimName.toLowerCase(ChannelDecoder.NAME_LOCALE);
-            if (lower != dimName) {                         // Identity comparison is okay
here.
-                dim = allDimensions.get(lower);
-            }
-        }
-        return dim;
-    }
-
-    /**
      * Returns the value of the given attribute, or {@code null} if none.
      * This method should be invoked only for hard-coded names that mix lower-case and upper-case
letters.
      *



Mime
View raw message