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: Fix inversion of (latitude, longitude) axes in some cases: Grid.getGridGeometry(…) need to check which source dimension is first before to invoke Axis.createLocalizationGrid(…).
Date Tue, 19 Feb 2019 19:55:41 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 5a1a8b2  Fix inversion of (latitude, longitude) axes in some cases: Grid.getGridGeometry(…)
need to check which source dimension is first before to invoke Axis.createLocalizationGrid(…).
5a1a8b2 is described below

commit 5a1a8b2b266f29bb8d54252cd1637ba6567a3701
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Tue Feb 19 20:54:04 2019 +0100

    Fix inversion of (latitude, longitude) axes in some cases: Grid.getGridGeometry(…) need
to check which source dimension is first before to invoke Axis.createLocalizationGrid(…).
---
 .../java/org/apache/sis/internal/netcdf/Axis.java  |  8 ++-
 .../java/org/apache/sis/internal/netcdf/Grid.java  | 70 +++++++++++++---------
 .../org/apache/sis/internal/netcdf/Variable.java   |  4 +-
 .../sis/internal/netcdf/ucar/VariableWrapper.java  | 18 +++---
 4 files changed, 61 insertions(+), 39 deletions(-)

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 3306fcd..3e4fe9a 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
@@ -352,7 +352,11 @@ public final class Axis extends NamedElement {
      * This is used for testing is a predefined axis can be used instead than invoking {@link
#toISO(CSFactory)}.
      */
     final boolean isSameUnitAndDirection(final CoordinateSystemAxis axis) {
-        return axis.getDirection().equals(direction) && axis.getUnit().equals(getUnit());
+        if (!axis.getDirection().equals(direction)) {
+            return false;
+        }
+        final Unit<?> unit = getUnit();                         // Null to be interpreted
as system unit.
+        return (unit == null) || axis.getUnit().equals(unit);
     }
 
     /**
@@ -601,7 +605,7 @@ main:   switch (getDimension()) {
      * @throws DataStoreException if a logical error occurred.
      */
     final LocalizationGridBuilder createLocalizationGrid(final Axis other) throws IOException,
DataStoreException {
-        if (other.getDimension() == 2) {
+        if (getDimension() == 2 && other.getDimension() == 2) {
             final int xd =  this.sourceDimensions[0];
             final int yd =  this.sourceDimensions[1];
             final int xo = other.sourceDimensions[0];
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 7f2fc0f..272468e 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
@@ -293,10 +293,8 @@ public abstract class Grid extends NamedElement {
                     continue;
                 }
                 int dim = axis.sourceDimensions[0];
-                if (dim >= 0) {
-                    dim = names.length - 1 - dim;               // Convert netCDF order to
"natural" order.
-                    if (dim >= 0) names[dim] = name;
-                }
+                dim = names.length - 1 - dim;               // Convert netCDF order to "natural"
order.
+                if (dim >= 0) names[dim] = name;
             }
         }
         return new GridExtent(names, null, high, false);
@@ -318,7 +316,7 @@ public abstract class Grid extends NamedElement {
             /*
              * Creates the "grid to CRS" transform. The number of columns is the number of
dimensions in the grid
              * (the source) +1, and the number of rows is the number of dimensions in the
CRS (the target) +1.
-             * The order of dimensions in the transform is the reverse of the netCDF axis
order.
+             * The order of dimensions in the transform is the reverse of the netCDF dimension
order.
              */
             int lastSrcDim = getSourceDimensions();                         // Will be decremented
later, then kept final.
             int lastTgtDim = getTargetDimensions();
@@ -334,7 +332,20 @@ public abstract class Grid extends NamedElement {
             /*
              * If we have not been able to set some coefficients in the matrix (because some
transforms are non-linear),
              * set a single scale factor to 1 in the matrix row. The coefficient that we
set to 1 is the one for the source
-             * dimension which is not already taken by another row.
+             * dimension which is not already taken by another row. If we have choice, we
give preference to the dimension
+             * which seems most closely oriented toward axis direction (i.e. the first element
in axis.sourceDimensions).
+             *
+             * Example: if the 'axes' array contains (longitude, latitude) in that order,
and if the longitude axis said
+             * that its preferred dimension is 1 (after conversion to "natural" order) while
the latitude axis said that
+             * its preferred dimension is 0, then we build the following matrix:
+             *
+             *    ┌         ┐
+             *    │ 0  1  0 │   axes[0] (longitude), preferred grid dimension = 1
+             *    │ 1  0  0 │   axes[1] (latitude),  preferred grid dimension = 0
+             *    │ 0  0  1 │
+             *    └         ┘
+             *
+             * The preferred grid dimensions are stored in the 'sourceDimensions' array.
In above example this is {1, 0}.
              */
             final int[] sourceDimensions = new int[nonLinears.size()];
             Arrays.fill(sourceDimensions, -1);
@@ -342,7 +353,7 @@ public abstract class Grid extends NamedElement {
                 final int tgtDim = deferred[i];
                 final Axis axis = axes[tgtDim];
 findFree:       for (int srcDim : axis.sourceDimensions) {
-                    srcDim = lastSrcDim - srcDim;
+                    srcDim = lastSrcDim - srcDim;                               // Convert
netCDF order to "natural" order.
                     for (int j=affine.getNumRow(); --j>=0;) {
                         if (affine.getElement(j, srcDim) != 0) {
                             continue findFree;
@@ -362,28 +373,31 @@ findFree:       for (int srcDim : axis.sourceDimensions) {
             for (int i=0; i<nonLinears.size(); i++) {         // Length of 'nonLinears'
may change in this loop.
                 if (nonLinears.get(i) == null) {
                     final Axis axis = axes[deferred[i]];
-                    if (axis.getDimension() == 2) {
-                        for (int j=i; ++j < nonLinears.size();) {
-                            if (nonLinears.get(j) == null) {
-                                final int srcDim   = sourceDimensions[i];
-                                final int otherDim = sourceDimensions[j];
-                                if (Math.abs(srcDim - otherDim) == 1) {     // Need axes
at consecutive source dimensions.
-                                    final LocalizationGridBuilder grid = axis.createLocalizationGrid(axes[deferred[j]]);
-                                    if (grid != null) {
-                                        /*
-                                         * Replace the first transform by the two-dimensional
localization grid and
-                                         * remove the other transform. Removals need to be
done in arrays too.
-                                         */
-                                        nonLinears.set(i, grid.create(factory));
-                                        nonLinears.remove(j);
-                                        final int n = nonLinears.size() - j;
-                                        System.arraycopy(deferred,         j+1, deferred,
        j, n);
-                                        System.arraycopy(sourceDimensions, j+1, sourceDimensions,
j, n);
-                                        if (otherDim < srcDim) {
-                                            sourceDimensions[i] = otherDim;
-                                        }
-                                    }
+                    for (int j=i; ++j < nonLinears.size();) {
+                        if (nonLinears.get(j) == null) {
+                            final Axis other   = axes[deferred[j]];
+                            final int srcDim   = sourceDimensions[i];
+                            final int otherDim = sourceDimensions[j];
+                            final LocalizationGridBuilder grid;
+                            switch (srcDim - otherDim) {
+                                case -1: grid = axis.createLocalizationGrid(other); break;
+                                case +1: grid = other.createLocalizationGrid(axis); break;
+                                default: continue;  // Needs axes at consecutive source dimensions.
+                            }
+                            if (grid != null) {
+                                /*
+                                 * Replace the first transform by the two-dimensional localization
grid and
+                                 * remove the other transform. Removals need to be done in
arrays too.
+                                 */
+                                nonLinears.set(i, grid.create(factory));
+                                nonLinears.remove(j);
+                                final int n = nonLinears.size() - j;
+                                System.arraycopy(deferred,         j+1, deferred,       
 j, n);
+                                System.arraycopy(sourceDimensions, j+1, sourceDimensions,
j, n);
+                                if (otherDim < srcDim) {
+                                    sourceDimensions[i] = otherDim;         // Index of the
first dimension.
                                 }
+                                break;                                      // Continue the
'i' loop.
                             }
                         }
                     }
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 612a4b3..a666fdb 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
@@ -170,7 +170,7 @@ public abstract class Variable extends NamedElement {
     public abstract String getDescription();
 
     /**
-     * Returns the unit of measurement as a string, or {@code null} or an empty string if
none.
+     * Returns the unit of measurement as a string, or {@code null} if none.
      * The empty string can not be used for meaning "dimensionless unit"; some text is required.
      *
      * <p>Note: the UCAR library has its own API for handling units (e.g. {@link ucar.nc2.units.SimpleUnit}).
@@ -230,7 +230,7 @@ public abstract class Variable extends NamedElement {
         if (!unitParsed) {
             unitParsed = true;                          // Set first for avoiding to report
errors many times.
             final String symbols = getUnitsString();
-            if (symbols != null && !symbols.isEmpty()) try {
+            if (symbols != null) try {
                 unit = parseUnit(symbols);
             } catch (Exception ex) {
                 error(Variable.class, "getUnit", ex, Errors.Keys.CanNotAssignUnitToVariable_2,
getName(), symbols);
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 addca6f..5e8d94c 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
@@ -135,25 +135,29 @@ final class VariableWrapper extends Variable {
     }
 
     /**
+     * Trims the leading and trailing spaces of the given string.
+     * If the string is null, empty or contains only spaces, then this method returns {@code
null}.
+     */
+    private static String trim(String text) {
+        return (text != null && (text = text.trim()).isEmpty()) ? null : text;
+    }
+
+    /**
      * Returns the description of this variable, or {@code null} if none.
      */
     @Override
     public String getDescription() {
-        String d = variable.getDescription();
-        if (d != null && (d = d.trim()).isEmpty()) {
-            d = null;
-        }
-        return d;
+        return trim(variable.getDescription());
     }
 
     /**
-     * Returns the unit of measurement as a string, or an empty strong if none.
+     * Returns the unit of measurement as a string, or {@code null} if none.
      * Note that the UCAR library represents missing unit by an empty string,
      * which is ambiguous with dimensionless unit.
      */
     @Override
     protected String getUnitsString() {
-        return variable.getUnitsString();
+        return trim(variable.getUnitsString());
     }
 
     /**


Mime
View raw message