sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 04/04: Move more methods in order to improve a bit the encapsulation.
Date Sat, 26 Jan 2019 17:18:58 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

commit 6c47bc29fda3476be5cd0f0c7ef2856e50bd4c59
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Jan 26 17:22:12 2019 +0100

    Move more methods in order to improve a bit the encapsulation.
---
 .../java/org/apache/sis/internal/netcdf/Axis.java  | 113 ++++++++++++++++++++-
 .../java/org/apache/sis/internal/netcdf/Grid.java  |  94 ++++-------------
 .../apache/sis/storage/netcdf/MetadataReader.java  |   4 +-
 3 files changed, 133 insertions(+), 78 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 5736831..d015017 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
@@ -38,10 +38,12 @@ import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.iso.Types;
+import org.apache.sis.util.ArraysExt;
 import org.apache.sis.measure.Longitude;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Units;
 import org.apache.sis.math.Vector;
+import org.apache.sis.referencing.operation.builder.LocalizationGridBuilder;
 import ucar.nc2.constants.CDM;
 import ucar.nc2.constants.CF;
 
@@ -115,7 +117,7 @@ public final class Axis extends NamedElement implements Comparable<Axis>
{
      * equals to the {@link #sourceDimensions} length. For each element, {@code sourceSizes[i]}
shall
      * be equals to the number of grid cells in the grid dimension at index {@code sourceDimensions[i]}.
      */
-    public final int[] sourceSizes;
+    final int[] sourceSizes;
 
     /**
      * Values of coordinates on this axis for given grid indices. This variables is often
one-dimensional,
@@ -204,6 +206,71 @@ public final class Axis extends NamedElement implements Comparable<Axis>
{
     }
 
     /**
+     * Swaps the two first source dimensions if needed for making the fastest varying dimension
first.
+     * This is a helper method for {@link Grid#getAxes()} invoked after all axes of a grid
have been created.
+     * This method needs to know other axes in order to avoid collision.
+     *
+     * @param  axes   previously created axes.
+     * @param  count  number of elements to consider in the {@code axes} array.
+     * @throws IOException if an I/O operation was necessary but failed.
+     * @throws DataStoreException if a logical error occurred.
+     * @throws ArithmeticException if the size of an axis exceeds {@link Integer#MAX_VALUE},
or other overflow occurs.
+     *
+     * @see #getDimension()
+     */
+    final void mainDimensionFirst(final Axis[] axes, final int count) throws IOException,
DataStoreException {
+        final int d0 = sourceDimensions[0];
+        final int d1 = sourceDimensions[1];
+        boolean s = false;
+        for (int i=0; i<count; i++) {
+            final int[] other = axes[i].sourceDimensions;
+            if (other.length != 0) {
+                final int first = other[0];
+                if  (first == d1) return;          // Swapping would cause a collision.
+                s = (first == d0);
+                if (s) break;                      // Need swapping for avoiding collision.
+            }
+        }
+        if (!s) {
+            final int up0  = sourceSizes[0];
+            final int up1  = sourceSizes[1];
+            final int mid0 = up0 / 2;
+            final int mid1 = up1 / 2;
+            final double inc0 = (coordinates.coordinateForAxis(    0, mid1) -
+                                 coordinates.coordinateForAxis(up0-1, mid1)) / up0;
+            final double inc1 = (coordinates.coordinateForAxis(mid0,     0) -
+                                 coordinates.coordinateForAxis(mid0, up1-1)) / up1;
+            if (!(Math.abs(inc1) > Math.abs(inc0))) {
+                return;
+            }
+        }
+        ArraysExt.swap(sourceSizes,      0, 1);
+        ArraysExt.swap(sourceDimensions, 0, 1);
+    }
+
+    /**
+     * Returns the number of dimension of the localization grid used by this axis.
+     * This method returns 2 if this axis if backed by a localization grid having 2 or more
dimensions.
+     * In the netCDF UCAR library, such axes are handled by a {@link ucar.nc2.dataset.CoordinateAxis2D}.
+     *
+     * @return number of dimension of the localization grid used by this axis.
+     */
+    public final int getDimension() {
+        return sourceDimensions.length;
+    }
+
+    /**
+     * Returns the number of cells in the first dimension of the localization grid used by
this axis.
+     * If the localization grid has more than one dimension ({@link #getDimension()} {@literal
> 1}),
+     * then all additional dimensions are ignored. The first dimension should be the main
one.
+     *
+     * @return number of cells in the first (main) dimension of the localization grid.
+     */
+    public final int getLength() {
+        return (sourceSizes.length != 0) ? sourceSizes[0] : 0;
+    }
+
+    /**
      * Returns the name of this axis.
      *
      * @return the name of this element.
@@ -381,7 +448,7 @@ public final class Axis extends NamedElement implements Comparable<Axis>
{
     final boolean trySetTransform(final Matrix gridToCRS, final int lastSrcDim, final int
tgtDim,
             final List<MathTransform> nonLinears) throws IOException, DataStoreException
     {
-main:   switch (sourceDimensions.length) {
+main:   switch (getDimension()) {
             /*
              * Defined as a matter of principle, but should never happen.
              */
@@ -456,4 +523,46 @@ main:   switch (sourceDimensions.length) {
         nonLinears.add(null);
         return false;
     }
+
+    /**
+     * Tries to create a two-dimensional localization grid using this axis and the given
axis.
+     * This method is invoked as a fallback when {@link #trySetTransform(Matrix, int, int,
List)}
+     * could not set coefficients in the matrix of an affine transform.
+     *
+     * @param  other  the other axis to use for creating a localization grid.
+     * @return the localization grid, or {@code null} if none can be built.
+     * @throws IOException if an error occurred while reading the data.
+     * @throws DataStoreException if a logical error occurred.
+     */
+    final LocalizationGridBuilder createLocalizationGrid(final Axis other) throws IOException,
DataStoreException {
+        if (other.getDimension() == 2) {
+            final int d1 =       sourceDimensions[0];
+            final int d2 =       sourceDimensions[1];
+            final int o1 = other.sourceDimensions[0];
+            final int o2 = other.sourceDimensions[1];
+            if ((o1 == d1 && o2 == d2) || (o1 == d2 && o2 == d1)) {
+                /*
+                 * Found two axes for the same set of dimensions, which implies that they
have
+                 * the same shape (width and height).
+                 */
+                final int width  = sourceSizes[0];
+                final int height = sourceSizes[1];
+                final LocalizationGridBuilder grid = new LocalizationGridBuilder(width, height);
+                final Vector v1 =       coordinates.read();
+                final Vector v2 = other.coordinates.read();
+                final double[] target = new double[2];
+                int index = 0;
+                for (int y=0; y<height; y++) {
+                    for (int x=0; x<width; x++) {
+                        target[0] = v1.doubleValue(index);
+                        target[1] = v2.doubleValue(index);
+                        grid.setControlPoint(x, y, target);
+                        index++;
+                    }
+                }
+                return grid;
+            }
+        }
+        return null;
+    }
 }
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 3c8f52f..49ce6b7 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
@@ -40,8 +40,6 @@ import org.apache.sis.coverage.grid.GridGeometry;
 import org.apache.sis.coverage.grid.IllegalGridGeometryException;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.util.NullArgumentException;
-import org.apache.sis.util.ArraysExt;
-import org.apache.sis.math.Vector;
 
 
 /**
@@ -159,12 +157,11 @@ public abstract class Grid extends NamedElement {
             int i = 0, deferred = workspace.length;
             for (final Axis axis : axes) {
                 // Put one-dimensional axes first, all other axes last.
-                workspace[axis.sourceDimensions.length <= 1 ? i++ : --deferred] = axis;
+                workspace[axis.getDimension() <= 1 ? i++ : --deferred] = axis;
             }
             deferred = workspace.length;        // Will become index of the first axis whose
examination has been deferred.
             while (i < workspace.length) {      // Start the loop at the first n-dimensional
axis (n > 1).
                 final Axis axis = workspace[i];
-                final int[] sourceDimensions = axis.sourceDimensions;
                 /*
                  * If an axis has a "wraparound" range (for example a longitude axis where
the next value after +180°
                  * may be -180°), we will examine it last. The reason is that if a wraparound
occurs in the middle of
@@ -175,35 +172,10 @@ public abstract class Grid extends NamedElement {
                 if (i < deferred && axis.isWraparound()) {
                     System.arraycopy(workspace, i+1, workspace, i, --deferred - i);
                     workspace[deferred] = axis;
-                    continue;                                           // Continue the loop
without incrementing 'i'.
-                }
-                Boolean swap = null;
-                for (int p=0; p<i; p++) {
-                    final int[] other = workspace[p].sourceDimensions;
-                    if (other.length != 0) {
-                        final int first = other[0];
-                        if (first == sourceDimensions[1]) {swap=false; break;}    // Swapping
would cause a collision.
-                        if (first == sourceDimensions[0]) {swap=true;  break;}    // Need
swapping for avoiding collision.
-                    }
-                }
-                final int[] sourceSizes = axis.sourceSizes;
-                if (swap == null) {
-                    final int up0  = sourceSizes[0];
-                    final int up1  = sourceSizes[1];
-                    final int mid0 = up0 / 2;
-                    final int mid1 = up1 / 2;
-                    final Variable coordinates = axis.coordinates;
-                    final double inc0 = (coordinates.coordinateForAxis(    0, mid1) -
-                                         coordinates.coordinateForAxis(up0-1, mid1)) / up0;
-                    final double inc1 = (coordinates.coordinateForAxis(mid0,     0) -
-                                         coordinates.coordinateForAxis(mid0, up1-1)) / up1;
-                    swap = Math.abs(inc1) > Math.abs(inc0);
-                }
-                if (swap) {
-                    ArraysExt.swap(sourceSizes,      0, 1);
-                    ArraysExt.swap(sourceDimensions, 0, 1);
+                } else {
+                    axis.mainDimensionFirst(workspace, i);
+                    i++;
                 }
-                i++;
             }
         }
         return axes;
@@ -269,7 +241,7 @@ public abstract class Grid extends NamedElement {
             case 0:  break;
         }
         for (final Axis axis : axes) {
-            if (axis.sourceDimensions.length == 1) {
+            if (axis.getDimension() == 1) {
                 final DimensionNameType name;
                 if (AxisDirections.isVertical(axis.direction)) {
                     name = DimensionNameType.VERTICAL;
@@ -349,51 +321,25 @@ 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.sourceDimensions.length == 2) {
-                        final int d1 = axis.sourceDimensions[0];
-                        final int d2 = axis.sourceDimensions[1];
+                    if (axis.getDimension() == 2) {
                         for (int j=i; ++j < nonLinears.size();) {
                             if (nonLinears.get(j) == null) {
-                                final Axis other = axes[deferred[j]];
-                                if (other.sourceDimensions.length == 2) {
-                                    final int o1 = other.sourceDimensions[0];
-                                    final int o2 = other.sourceDimensions[1];
-                                    if ((o1 == d1 && o2 == d2) || (o1 == d2 &&
o2 == d1)) {
+                                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) {
                                         /*
-                                         * Found two axes for the same set of dimensions,
which implies that they have
-                                         * the same shape (width and height).  In current
implementation, we also need
-                                         * those axes to be at consecutive source dimensions.
+                                         * Replace the first transform by the two-dimensional
localization grid and
+                                         * remove the other transform. Removals need to be
done in arrays too.
                                          */
-                                        final int srcDim   = sourceDimensions[i];
-                                        final int otherDim = sourceDimensions[j];
-                                        if (Math.abs(srcDim - otherDim) == 1) {
-                                            final int width  = axis.sourceSizes[0];
-                                            final int height = axis.sourceSizes[1];
-                                            final LocalizationGridBuilder grid = new LocalizationGridBuilder(width,
height);
-                                            final Vector v1 =  axis.coordinates.read();
-                                            final Vector v2 = other.coordinates.read();
-                                            final double[] target = new double[2];
-                                            int index = 0;
-                                            for (int y=0; y<height; y++) {
-                                                for (int x=0; x<width; x++) {
-                                                    target[0] = v1.doubleValue(index);
-                                                    target[1] = v2.doubleValue(index);
-                                                    grid.setControlPoint(x, y, target);
-                                                    index++;
-                                                }
-                                            }
-                                            /*
-                                             * 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;
-                                            }
+                                        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;
                                         }
                                     }
                                 }
diff --git a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
index 950819f..2127810 100644
--- a/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
+++ b/storage/sis-netcdf/src/main/java/org/apache/sis/storage/netcdf/MetadataReader.java
@@ -724,8 +724,8 @@ split:  while ((start = CharSequences.skipLeadingWhitespaces(value, start,
lengt
              * the 'sourceDimensions' and 'sourceSizes' arrays are for the grid dimension
which is most closely
              * oriented toward the axis direction.
              */
-            if (axis.sourceSizes.length >= 1) {
-                setAxisLength(dim, axis.sourceSizes[0]);
+            if (axis.getDimension() >= 1) {
+                setAxisLength(dim, axis.getLength());
             }
             final AttributeNames.Dimension attributeNames;
             switch (axis.abbreviation) {


Mime
View raw message