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 763442662f8627f8aed7e93e53acc1114fedeaea Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Fri Mar 24 13:07:39 2023 +0100 Clarify in documentation the behavior of `GridCoverage.Evaluator.toGridCoordinates(DirectPosition)`. --- .../org/apache/sis/coverage/BandedCoverage.java | 9 ++++++++- .../sis/coverage/grid/BufferedGridCoverage.java | 22 +++++++++++----------- .../apache/sis/coverage/grid/DefaultEvaluator.java | 6 ++++-- .../sis/coverage/grid/DerivedGridCoverage.java | 16 +++++++++++++--- .../coverage/grid/FractionalGridCoordinates.java | 6 +++--- .../org/apache/sis/coverage/grid/GridCoverage.java | 18 ++++++++++++++++-- 6 files changed, 55 insertions(+), 22 deletions(-) diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/BandedCoverage.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/BandedCoverage.java index 720750fbe7..a64416ff7b 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/BandedCoverage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/BandedCoverage.java @@ -139,7 +139,14 @@ public abstract class BandedCoverage { public interface Evaluator extends Function<DirectPosition, double[]> { /** * Returns the coverage from which this evaluator is computing sample values. - * This is the coverage on which the {@link BandedCoverage#evaluator()} method has been invoked. + * This is <em>usually</em> the instance on which the {@link BandedCoverage#evaluator()} + * method has been invoked, but not necessarily. Evaluators are allowed to fetch values + * from a different source for better performances or accuracies. + * + * <h4>Example</h4> + * If the values of the enclosing coverage are interpolated from the values of another coverage, + * then this evaluator may use directly the values of the latter coverage. Doing so avoid to add + * more interpolations on values that are already interpolated. * * @return the source of sample values for this evaluator. */ diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/BufferedGridCoverage.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/BufferedGridCoverage.java index 8d2ceae008..cd94d43f5d 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/BufferedGridCoverage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/BufferedGridCoverage.java @@ -47,18 +47,11 @@ import org.opengis.coverage.PointOutsideCoverageException; * Basic access to grid data values backed by a <var>n</var>-dimensional {@link DataBuffer}. * Those data can be shown as an untiled {@link RenderedImage}. * Images are created when {@link #render(GridExtent)} is invoked instead of at construction time. - * This delayed construction makes this class better suited to <var>n</var>-dimensional grids since - * those grids cannot be wrapped into a single {@link RenderedImage}. + * This delayed construction makes this class better suited to <var>n</var>-dimensional grids + * because those grids cannot be wrapped into a single {@link RenderedImage}. * - * <div class="note"><b>Comparison with alternatives:</b> - * this class expects all data to reside in-memory and does not support tiling. - * Pixels are stored in a row-major fashion with all bands in a single array <em>or</em> one array per band. - * By contrast, {@link GridCoverage2D} allows more flexibility in data layout and supports tiling with data - * loaded or computed on-the-fly, but is restricted to two-dimensional images (which may be slices in a - * <var>n</var>-dimensional grid).</div> - * - * The number of bands is determined by the number of {@link SampleDimension}s specified at construction time. - * The {@linkplain DataBuffer#getNumBanks() number of banks} is either 1 or the number of bands. + * <p>The number of bands is determined by the number of {@link SampleDimension}s specified at construction time. + * The {@linkplain DataBuffer#getNumBanks() number of banks} is either 1 or the number of bands.</p> * * <ul class="verbose"> * <li>If the number of banks is 1, all data are packed in a single array with band indices varying fastest, @@ -75,6 +68,13 @@ import org.opengis.coverage.PointOutsideCoverageException; * but different dimensions may be used depending on which dimensions are identified as the * {@linkplain GridExtent#getSubspaceDimensions(int) subspace dimensions}. * + * <h2>Restrictions</h2> + * This class expects all data to reside in-memory and does not support tiling. + * Pixels are stored in a row-major fashion with all bands in a single array <em>or</em> one array per band. + * By contrast, {@link GridCoverage2D} allows more flexibility in data layout and supports tiling with data + * loaded or computed on-the-fly, but is restricted to two-dimensional images + * (which may be slices in a <var>n</var>-dimensional grid). + * * @author Johann Sorel (Geomatys) * @author Martin Desruisseaux (Geomatys) * @version 1.4 diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DefaultEvaluator.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DefaultEvaluator.java index 3405efa73a..66a7572630 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DefaultEvaluator.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DefaultEvaluator.java @@ -173,7 +173,7 @@ class DefaultEvaluator implements GridCoverage.Evaluator { * @return the source of sample values for this evaluator. */ @Override - public GridCoverage getCoverage() { + public final GridCoverage getCoverage() { return coverage; } @@ -192,7 +192,7 @@ class DefaultEvaluator implements GridCoverage.Evaluator { */ @Override @SuppressWarnings("ReturnOfCollectionOrArrayField") // Because the map is unmodifiable. - public Map<Integer,Long> getDefaultSlice() { + public final Map<Integer,Long> getDefaultSlice() { if (slice == null) { final GridExtent extent = coverage.getGridGeometry().getExtent(); slice = CollectionsExt.unmodifiableOrCopy(extent.getSliceCoordinates()); @@ -366,6 +366,8 @@ class DefaultEvaluator implements GridCoverage.Evaluator { * TODO: instead of restricting to a single point, keep the automatic size (1 or 2), * invoke render for each slice, then interpolate. We would keep a value of 1 in the * size array if we want to disable interpolation in some particular axis (e.g. time). + * + * See https://issues.apache.org/jira/browse/SIS-576 */ final GridGeometry gridGeometry = coverage.gridGeometry; final long[] size = new long[gridGeometry.getDimension()]; diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DerivedGridCoverage.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DerivedGridCoverage.java index 628b0dfca1..f1568db338 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DerivedGridCoverage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/DerivedGridCoverage.java @@ -93,9 +93,19 @@ abstract class DerivedGridCoverage extends GridCoverage { * That function accepts {@link DirectPosition} in arbitrary Coordinate Reference System; * conversions to grid indices are applied by the {@linkplain #source} as needed. * - * @todo The results returned by {@link GridCoverage.Evaluator#toGridCoordinates(DirectPosition)} - * would need to be transformed. But it would force us to return a wrapper, which would add - * an indirection level for all others (more important) method calls. Is it worth to do so? + * <h4>Differences with usual behavior</h4> + * The evaluator returned by the default implementation has two methods with a behavior different + * than the intuitively expected ones. Howerver those differences are allowed by methods contract. + * + * <ul> + * <li>{@link GridCoverage.Evaluator#getCoverage()} returns an instance which is not {@code this}.</li> + * <li>The results returned by {@link GridCoverage.Evaluator#toGridCoordinates(DirectPosition)} + * are coordinates in a grid potentially inconsistent with {@link #getGridGeometry()}.</li> + * </ul> + * + * Those differences are allowed because otherwise, this method would be forced to use a wrapper at + * least for transforming {@link GridCoverage.Evaluator#toGridCoordinates(DirectPosition)} results. + * It would add an indirection level for all others (more important) method calls. */ @Override public Evaluator evaluator() { diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/FractionalGridCoordinates.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/FractionalGridCoordinates.java index 08f759cc70..12c20d19a8 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/FractionalGridCoordinates.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/FractionalGridCoordinates.java @@ -37,7 +37,7 @@ import org.apache.sis.util.resources.Errors; * Grid coordinates specify the location of a cell within a {@link GridCoverage}. * They are normally integer numbers, but fractional parts may exist for example * after converting a geospatial {@link DirectPosition} to grid coordinates. - * Preserving that fractional part is sometimes useful, e.g. for interpolations. + * Preserving that fractional part is needed for interpolations. * This class can store such fractional part and can also compute a {@link GridExtent} * containing the coordinates, which can be used for requesting data for interpolations. * @@ -68,10 +68,10 @@ public class FractionalGridCoordinates implements GridCoordinates, Serializable /** * Creates a new grid coordinates with the given number of dimensions. * - * <div class="note"><b>Note:</b> + * <h4>Usage note</h4> * {@code FractionalGridCoordinates} are usually not created directly, but are instead obtained * indirectly for example from the {@linkplain GridCoverage.Evaluator#toGridCoordinates(DirectPosition) - * conversion of a geospatial position}.</div> + * conversion of a geospatial position}. * * @param dimension the number of dimensions. */ diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage.java index 4985a8f11c..35263aee2a 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage.java @@ -351,10 +351,19 @@ public abstract class GridCoverage extends BandedCoverage { */ public interface Evaluator extends BandedCoverage.Evaluator { /** - * Returns the coverage from which this evaluator is fetching sample values. - * This is the coverage on which the {@link GridCoverage#evaluator()} method has been invoked. + * Returns the grid coverage from which this evaluator is computing sample values. + * This is <em>usually</em> the instance on which the {@link GridCoverage#evaluator()} + * method has been invoked, but not necessarily. Evaluators are allowed to fetch values + * from a different source for better performances or accuracies. + * + * <h4>Example</h4> + * If the values of the enclosing coverage are interpolated from the values of another coverage, + * then this evaluator may use directly the values of the latter coverage. Doing so avoid to add + * more interpolations on values that are already interpolated. * * @return the source of sample values for this evaluator. + * + * @see #toGridCoordinates(DirectPosition) */ @Override GridCoverage getCoverage(); @@ -390,6 +399,11 @@ public abstract class GridCoverage extends BandedCoverage { * then this method automatically transforms that position to the {@linkplain #getCoordinateReferenceSystem() * coverage CRS} before to compute grid coordinates. * + * <p>The returned value are coordinates in the grid of the coverage returned by {@link #getCoverage()}. + * This is <em>usually</em> the coverage instance on which {@link GridCoverage#evaluator()} has been invoked, + * but not necessarily. Evaluators are allowed to fetch values from a different source for better performances + * or accuracies.</p> + * * <p>This method does not put any restriction on the grid coordinates result. * The result may be outside the {@linkplain GridGeometry#getExtent() grid extent} * if the {@linkplain GridGeometry#getGridToCRS(PixelInCell) grid to CRS} transform allows it.</p>