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 0889fea803b3d3a11c39746a2392150b3d3656dd Author: Martin Desruisseaux <[email protected]> AuthorDate: Tue Apr 16 11:51:58 2019 +0200 Tuning of number of itetations and accuracy threshold. --- .../transform/EllipsoidToCentricTransform.java | 4 ++-- .../operation/transform/InterpolatedTransform.java | 19 ++++++++----------- .../org/apache/sis/storage/geotiff/Localization.java | 2 ++ .../java/org/apache/sis/internal/netcdf/Grid.java | 9 +++++++++ 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java index d3ac78b..f756550 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/EllipsoidToCentricTransform.java @@ -710,11 +710,11 @@ next: while (--numPts >= 0) { * If this code is used on a planet with high eccentricity, * the φ value may need to be improved by an iterative method. */ - for (int it=0; it<Formulas.MAXIMUM_ITERATIONS; it++) { + for (int it = Formulas.MAXIMUM_ITERATIONS; it >= 0; it--) { final double sinφ = sin(φ); final double ν = 1/sqrt(1 - eccentricitySquared * (sinφ*sinφ)); final double Δφ = φ - (φ = atan((Z + eccentricitySquared * ν * sinφ) / p)); - if (!(abs(Δφ) >= Formulas.ANGULAR_TOLERANCE * (PI/180) * 0.25)) { // Use ! for accepting NaN. + if (!(abs(Δφ) >= Formulas.ANGULAR_TOLERANCE * (PI/180) * 0.25)) { // Use ! for accepting NaN. dstPts[dstOff++] = atan2(Y, X); dstPts[dstOff++] = φ; if (withHeight) { diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java index 2044551..a70f625 100644 --- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java +++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/InterpolatedTransform.java @@ -433,13 +433,9 @@ public class InterpolatedTransform extends DatumShiftTransform { * Maximum number of iterations. This is set to a higher value than {@link Formulas#MAXIMUM_ITERATIONS} because * the data used in {@link InterpolatedTransform} grid may come from anywhere, in particular localization grids * in netCDF files. Deformations in those grids may be much higher than e.g. {@link DatumShiftTransform} grids. - * We observed that inverse transformations may converge slowly if the grid is far from a linear approximation. - * It happens when the grids have very high {@link DatumShiftGrid#interpolateInCell(double, double, double[])} - * values, for example close to 1000 while we usually expect values smaller than 1. Behavior with such grids may - * be unpredictable, sometime with the {@code abs(xi - ox)} or {@code abs(yi - oy)} errors staying high for a - * long time before to suddenly fall to zero. + * The algorithm in this class converges more slowly in area with very strong curvature. */ - private static final int MAXIMUM_ITERATIONS = Formulas.MAXIMUM_ITERATIONS * 4; + private static final int MAXIMUM_ITERATIONS = Formulas.MAXIMUM_ITERATIONS * 2; /** * The enclosing transform. @@ -600,14 +596,15 @@ public class InterpolatedTransform extends DatumShiftTransform { * 1E-7 accuracy (relative to cell size) if we don't really know what the answer should be. */ if (--it < 0) { - if (it < -1) { + if (it == -1) { + if (forward.grid.isCellInGrid(xi, yi)) { + throw new TransformException(Resources.format(Resources.Keys.NoConvergence)); + } + tol = 0.5; + } else { xi = yi = Double.NaN; break; } - if (forward.grid.isCellInGrid(xi, yi)) { - throw new TransformException(Resources.format(Resources.Keys.NoConvergence)); - } - tol = 0.5; } } /* diff --git a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Localization.java b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Localization.java index 66f5278..799cea5 100644 --- a/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Localization.java +++ b/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/Localization.java @@ -52,6 +52,8 @@ final class Localization { /** * The desired precision of coordinate transformations in units of pixels. * This is an arbitrary value that may be adjusted in any future SIS version. + * + * @todo compute the value based on the cell size in order to have an accuracy of about 1 cm on Earth. */ private static final double PRECISION = 1E-6; 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 ac5301c..ea4c3d2 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 @@ -439,6 +439,15 @@ findFree: for (int srcDim : axis.sourceDimensions) { Linearizer.applyTo(linearizers, factory, grid, gridAxes); } /* + * There is usually a one-to-one relationship between localization grid cells and image pixels. + * Consequently an accuracy set to a fraction of cell should be enough. + * + * TODO: take in account the case where Variable.Adjustment.dataToGridIndices() returns a value + * smaller than 1. For now we set the desired precision to a value 10 times smaller in order to + * take in account the case where dataToGridIndices() returns 0.1. + */ + grid.setDesiredPrecision(0.001); + /* * Replace the first transform by the two-dimensional localization grid and * remove the other transform. Removals need to be done in arrays too. */
