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: If correction for ±180° meridian crossing results in a GridGeometry well outside its original longitude range, apply a 360° translation on the whole grid.
Date Mon, 08 Apr 2019 12:22:30 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 b533404  If correction for ±180° meridian crossing results in a GridGeometry well
outside its original longitude range, apply a 360° translation on the whole grid.
b533404 is described below

commit b5334040c030c76548d72c75d9d7654e45eab0f1
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Mon Apr 8 14:21:08 2019 +0200

    If correction for ±180° meridian crossing results in a GridGeometry well outside its
original longitude range, apply a 360° translation on the whole grid.
---
 .../internal/referencing/WraparoundAdjustment.java |  2 +-
 .../operation/builder/LinearTransformBuilder.java  | 36 +++++++++++++++++++++-
 .../operation/builder/LocalizationGridBuilder.java |  2 +-
 .../java/org/apache/sis/internal/netcdf/Axis.java  |  2 +-
 4 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
index a18fa73..b9e9da5 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundAdjustment.java
@@ -309,7 +309,7 @@ public final class WraparoundAdjustment {
                     final double  lowerToValidStart = ((validStart - lower) / period) - lowerCycles;
   // In number of periods.
                     final double  upperToValidEnd   = ((validEnd   - upper) / period) - upperCycles;
                     final boolean lowerIsBefore     = (lowerToValidStart > 0);
-                    final boolean upperIsAfter      = (upperToValidEnd < 0);
+                    final boolean upperIsAfter      = (upperToValidEnd   < 0);
                     if (lowerIsBefore != upperIsAfter) {
                         final double upperToValidStart = ((validStart - upper) / period)
- upperCycles;
                         final double lowerToValidEnd   = ((validEnd   - lower) / period)
- lowerCycles;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
index ac05e77..eceb47a 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
@@ -1071,7 +1071,7 @@ search:         for (int j=domain(); --j >= 0;) {
      * @param  direction  the direction to walk through: 0 for columns or 1 for rows (higher
dimensions are also possible).
      *                    Value can be from 0 inclusive to {@link #getSourceDimensions()}
exclusive.
      *                    The recommended direction is the direction of most stable values,
typically 1 (rows) for longitudes.
-     * @param  period     that wraparound range (typically 360° for longitudes).
+     * @param  period     that wraparound range (typically 360° for longitudes). Must be
strictly positive.
      * @throws IllegalStateException if {@link #create(MathTransformFactory) create(…)}
has already been invoked.
      */
     final void resolveWraparoundAxis(final int dimension, final int direction, final double
period) {
@@ -1083,12 +1083,18 @@ search:         for (int j=domain(); --j >= 0;) {
         }
         final int page = stride * gridSize[direction];          // Index offset for moving
to next row or whatever is the next dimension.
         final double threshold = period / 2;
+        double minValue = Double.POSITIVE_INFINITY;
+        double maxValue = Double.NEGATIVE_INFINITY;
+        double minAfter = Double.POSITIVE_INFINITY;
+        double maxAfter = Double.NEGATIVE_INFINITY;
         double previous = coordinates[0];
         for (int x=0; x<stride; x++) {                          // For iterating over
dimensions lower than 'dimension'.
             for (int y=0; y<gridLength; y += page) {            // For iterating over
dimensions greater than 'dimension'.
                 final int stop = y + page;
                 for (int i = x+y; i<stop; i += stride) {
                     double value = coordinates[i];
+                    if (value < minValue) minValue = value;
+                    if (value > maxValue) maxValue = value;
                     double delta = value - previous;
                     if (Math.abs(delta) > threshold) {
                         delta = Math.rint(delta / period) * period;
@@ -1096,6 +1102,8 @@ search:         for (int j=domain(); --j >= 0;) {
                         coordinates[i] = value;
                     }
                     previous = value;
+                    if (value < minAfter) minAfter = value;
+                    if (value > maxAfter) maxAfter = value;
                 }
                 /*
                  * For the next scan, use as a reference the first value of this scan. If
our scan direction is 0
@@ -1115,6 +1123,32 @@ search:         for (int j=domain(); --j >= 0;) {
                 previous = coordinates[x];
             }
         }
+        /*
+         * If some coordinates have been shifted, the range may become unreasonable. For
example we may get a
+         * range of [-440 … -160]° of longitude. Shift again in the direction that provide
the best intersection
+         * with original range.
+         */
+        final double Δmin = minValue - minAfter;
+        final double Δmax = maxValue - maxAfter;
+        if (Δmin != 0 || Δmax != 0) {
+            double shift = 0;
+            double intersection = 0;
+            final double minCycles = Math.floor(Math.min(Δmin, Δmax) / period);
+            final double maxCycles = Math.ceil (Math.max(Δmin, Δmax) / period);
+            for (double cycles = minCycles; cycles <= maxCycles; cycles++) {
+                final double s = cycles * period;
+                final double p = Math.min(maxValue, maxAfter + s) - Math.max(minValue, minAfter
+ s);
+                if (p > intersection) {
+                    intersection = p;
+                    shift = s;
+                }
+            }
+            if (shift != 0) {
+                for (int i=0; i<coordinates.length; i++) {
+                    coordinates[i] += shift;
+                }
+            }
+        }
     }
 
     /**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
index ad9f013..e115b41 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
@@ -515,7 +515,7 @@ public class LocalizationGridBuilder extends TransformBuilder {
      *                    This is 0 for longitude dimension in a (<var>longitudes</var>,
<var>latitudes</var>) grid.
      * @param  direction  the direction to walk through: 0 for columns or 1 for rows.
      *                    The recommended direction is the direction of most stable values,
typically 1 (rows) for longitudes.
-     * @param  period     that wraparound range (typically 360° for longitudes).
+     * @param  period     that wraparound range (typically 360° for longitudes). Must be
strictly positive.
      * @throws IllegalStateException if {@link #create(MathTransformFactory) create(…)}
has already been invoked.
      *
      * @since 1.0
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 67e602b..2b8438a 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
@@ -412,7 +412,7 @@ public final class Axis extends NamedElement {
     @SuppressWarnings("fallthrough")
     private double wraparoundRange() {
         if (isWraparound()) {
-            double period = 360;
+            double period = Longitude.MAX_VALUE - Longitude.MIN_VALUE;
             final Unit<?> unit = getUnit();
             if (unit != null) try {
                 period = unit.getConverterToAny(Units.DEGREE).convert(period);


Mime
View raw message