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 c50df4d  Provides a default accuracy value when no accuracy is 
explicitly given in a NTv2 file. https://issues.apache.org/jira/browse/SIS-432
c50df4d is described below

commit c50df4d283ff23c7f9ad907b7452ecfeba7da8be
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Sat Oct 13 23:15:37 2018 +0200

    Provides a default accuracy value when no accuracy is explicitly given in a 
NTv2 file.
    https://issues.apache.org/jira/browse/SIS-432
---
 .../referencing/provider/DatumShiftGridFile.java   |  6 ++--
 .../provider/FranceGeocentricInterpolation.java    |  2 +-
 .../sis/internal/referencing/provider/NTv2.java    | 39 +++++++++++++++++-----
 .../operation/builder/LocalizationGridBuilder.java | 14 +++++---
 .../operation/builder/ResidualGrid.java            |  4 ++-
 5 files changed, 48 insertions(+), 17 deletions(-)

diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java
index 7cc2603..cf1439d 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/DatumShiftGridFile.java
@@ -104,6 +104,7 @@ public abstract class DatumShiftGridFile<C extends 
Quantity<C>, T extends Quanti
 
     /**
      * The best translation accuracy that we can expect from this file.
+     * The unit of measurement depends on {@link #isCellValueRatio()}.
      *
      * <p>This field is initialized to {@link Double#NaN}. It is loader 
responsibility
      * to assign a value to this field after {@code DatumShiftGridFile} 
construction.</p>
@@ -235,13 +236,14 @@ public abstract class DatumShiftGridFile<C extends 
Quantity<C>, T extends Quanti
 
     /**
      * Suggests a precision for the translation values in this grid.
-     * The default implementation returns a value smaller than the accuracy.
+     * This information is used for deciding when to stop iterations in 
inverse transformations.
+     * The default implementation returns the {@linkplain #accuracy} divided 
by an arbitrary value.
      *
      * @return a precision for the translation values in this grid.
      */
     @Override
     public double getCellPrecision() {
-        return accuracy / 10;   // Division by 10 is arbitrary.
+        return accuracy / 10;               // Division by 10 is arbitrary.
     }
 
     /**
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
index 7f7d8f3..347c78e 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
@@ -475,7 +475,7 @@ public class FranceGeocentricInterpolation extends 
GeodeticOperation {
             tX[p] = -parseFloat(t.nextToken());     // See javadoc for the 
reason why we reverse the sign.
             tY[p] = -parseFloat(t.nextToken());
             tZ[p] = -parseFloat(t.nextToken());
-            final double accuracy = ACCURACY[Math.min(ACCURACY.length-1,
+            final double accuracy = ACCURACY[Math.min(ACCURACY.length - 1,
                     Math.max(0, Integer.parseInt(t.nextToken()) - 1))];
             if (!(accuracy >= grid.accuracy)) {     // Use '!' for replacing 
the initial NaN.
                 grid.accuracy = accuracy;
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
index e87f2fc..baf0c4c 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/NTv2.java
@@ -60,7 +60,7 @@ import org.apache.sis.measure.Units;
  *
  * @author  Simon Reynard (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.7
  * @module
  */
@@ -277,7 +277,8 @@ public final class NTv2 extends AbstractProvider {
          * Current SIS implementation does not yet handle the above-cited 
hierarchy of grids.
          * For now we just take the first one.
          *
-         * <p>NTv2 grids contain also information about shifts accuracy. This 
is not yet handled by SIS.</p>
+         * <p>NTv2 grids contain also information about shifts accuracy. This 
is not yet handled by SIS,
+         * except for determining an approximate grid cell resolution.</p>
          */
         final DatumShiftGridFile<Angle,Angle> readGrid() throws IOException, 
FactoryException, NoninvertibleTransformException {
             if (--remainingGrids < 0) {
@@ -321,12 +322,12 @@ public final class NTv2 extends AbstractProvider {
                 throw new 
FactoryException(Errors.format(Errors.Keys.UnexpectedValueInElement_2, 
"GS_COUNT", declared));
             }
             /*
-             * Construct the grid with the sign of longitude values reversed, 
in order to have longitude values
-             * increasing toward East. We set isCellValueRatio = true (by the 
arguments given to the constructor)
-             * because this is required by our InterpolatedTransform 
implementation. This setting implies that we
-             * divide translation values by dx or dy at reading time. Note 
that this free us from reversing the
-             * sign of longitude translations; instead, this reversal will be 
handled by grid.coordinateToGrid
-             * MathTransform and its inverse.
+             * Construct the grid. The sign of longitude translations will 
need to be reversed in order to have
+             * longitudes increasing toward East. We set isCellValueRatio = 
true (by the arguments given to the
+             * DatumShiftGridFile constructor) because this is required by 
InterpolatedTransform implementation.
+             * This setting implies that we divide translation values by dx or 
dy at reading time. Note that this
+             * free us from reversing the sign of longitude translations in 
the code below; instead, this reversal
+             * will be handled by grid.coordinateToGrid MathTransform and its 
inverse.
              */
             final DatumShiftGridFile.Float<Angle,Angle> grid = new 
DatumShiftGridFile.Float<>(2,
                     unit, unit, true, -xmin, ymin, -dx, dy, width, height, 
PARAMETERS, file);
@@ -338,9 +339,29 @@ public final class NTv2 extends AbstractProvider {
                 tx[i] = (float) (buffer.getFloat() / dx);
                 final double accuracy = Math.min(buffer.getFloat() / dy, 
buffer.getFloat() / dx);
                 if (accuracy > 0 && !(accuracy >= grid.accuracy)) {   // Use 
'!' for replacing the initial NaN.
-                    grid.accuracy = accuracy;
+                    grid.accuracy = accuracy;                         // 
Smallest non-zero accuracy.
                 }
             }
+            /*
+             * We need an estimation of translation accuracy, in order to 
decide when to stop iterations
+             * during inverse transformations. If we did not found that 
information in the file, compute
+             * an arbitrary default accuracy derived from the variations found 
in actual values.
+             */
+            if (Double.isNaN(grid.accuracy)) {
+                double txmin = Double.POSITIVE_INFINITY;
+                double txmax = Double.NEGATIVE_INFINITY;
+                double tymin = Double.POSITIVE_INFINITY;
+                double tymax = Double.NEGATIVE_INFINITY;
+                for (int i=Math.min(tx.length, ty.length); --i >= 0;) {
+                    double x = tx[i];
+                    double y = ty[i];
+                    if (x < txmin) txmin = x;
+                    if (x > txmax) txmax = x;
+                    if (y < tymin) tymin = y;
+                    if (y > tymax) tymax = y;
+                }
+                grid.accuracy = Math.min(txmax - txmin, tymax - tymin) / 1000;
+            }
             header.keySet().retainAll(Arrays.asList(overviewKeys));   // Keep 
only overview records.
             return DatumShiftGridCompressed.compress(grid, null, precision / 
Math.max(dx, dy));
         }
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 7fc6e80..6b15576 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
@@ -96,12 +96,17 @@ public class LocalizationGridBuilder extends 
TransformBuilder {
 
     /**
      * The desired precision of inverse transformations in unit of source 
coordinates, or 0 in unspecified.
-     * If no {@link #sourceToGrid} transform has been specified, than this is 
in unit of grid cell.
+     * If no {@link #sourceToGrid} transform has been specified, then this is 
in unit of grid cells
+     * (i.e. a value of 1 is the size of one grid cell).
+     *
+     * @see #setDesiredPrecision(double)
      */
     private double precision;
 
     /**
-     * Arbitrary default {@link #precision} value. May change in any future 
SIS version.
+     * Arbitrary default {@link #precision} value, in unit of grid cells. Used 
if no explicit inverse transform
+     * precision has been specified. The {@code sourceToGrid} transform shall 
not be applied on this value.
+     * This default precision may change in any future SIS version.
      */
     static final double DEFAULT_PRECISION = 1E-7;
 
@@ -246,7 +251,8 @@ public class LocalizationGridBuilder extends 
TransformBuilder {
     /**
      * Sets the desired precision of <em>inverse</em> transformations, in 
units of source coordinates.
      * If a conversion from "real world" to grid coordinates {@linkplain 
#setSourceToGrid has been specified},
-     * then the given precision is in "real world" units. Otherwise the 
precision is in units of grid cells.
+     * then the given precision is in "real world" units. Otherwise the 
precision is in units of grid cells
+     * (i.e. a value of 1 is the size of one grid cell).
      *
      * <div class="note"><b>Note:</b>
      * there is no method for setting the desired target precision because 
forward transformations <em>precision</em>
@@ -433,7 +439,7 @@ public class LocalizationGridBuilder extends 
TransformBuilder {
         boolean isLinear = true;
         for (final double c : linear.correlation()) {
             isExact &= (c == 1);
-            if (c < 0.9999) {                               // Empirical 
threshold (may need to be revisited).
+            if (!(c >= 0.9999)) {                           // Empirical 
threshold (may need to be revisited).
                 isLinear = false;
                 break;
             }
diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ResidualGrid.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ResidualGrid.java
index f9e222b..7d99315 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ResidualGrid.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ResidualGrid.java
@@ -73,6 +73,7 @@ final class ResidualGrid extends 
DatumShiftGridFile<Dimensionless,Dimensionless>
      * @param gridToTarget  conversion from grid coordinates to the final 
"real world" coordinates.
      * @param numDim        number of dimension of target coordinates.
      * @param residuals     the residual data, as translations to apply on the 
result of affine transform.
+     * @param precision     desired precision of inverse transformations in 
unit of grid cells.
      */
     ResidualGrid(final LinearTransform sourceToGrid, final LinearTransform 
gridToTarget,
             final int nx, final int ny, final int numDim, final double[] 
residuals, final double precision)
@@ -131,7 +132,8 @@ final class ResidualGrid extends 
DatumShiftGridFile<Dimensionless,Dimensionless>
 
     /**
      * Returns the desired precision in iterative calculation performed by 
inverse transform.
-     * The returned value is in unit of grid cell.
+     * The returned value is in unit of grid cell, i.e. a value of 1 is the 
size of one cell.
+     * This unit of measurement is fixed by {@link #isCellValueRatio()} = 
{@code true}.
      */
     @Override
     public double getCellPrecision() {

Reply via email to