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>

Reply via email to