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 e429a0e09b Replace `GridEvaluator` class by `GridCoverage.Evaluator` interface. e429a0e09b is described below commit e429a0e09b97b35d488da64c4a89401d320767a3 Author: Martin Desruisseaux <martin.desruisse...@geomatys.com> AuthorDate: Thu Aug 4 16:06:55 2022 +0200 Replace `GridEvaluator` class by `GridCoverage.Evaluator` interface. https://issues.apache.org/jira/browse/SIS-554 --- .../org/apache/sis/gui/map/ValuesUnderCursor.java | 5 +- .../org/apache/sis/coverage/BandedCoverage.java | 32 +++++- .../sis/coverage/grid/BufferedGridCoverage.java | 6 +- .../sis/coverage/grid/ConvertedGridCoverage.java | 87 ++++---------- .../sis/coverage/grid/DerivedGridCoverage.java | 9 +- .../apache/sis/coverage/grid/EvaluatorWrapper.java | 126 +++++++++++++++++++++ .../coverage/grid/FractionalGridCoordinates.java | 6 +- .../org/apache/sis/coverage/grid/GridCoverage.java | 84 +++++++++++++- .../apache/sis/coverage/grid/GridCoverage2D.java | 6 +- .../apache/sis/coverage/grid/GridEvaluator.java | 24 ++-- .../org/apache/sis/coverage/grid/GridExtent.java | 2 +- .../sis/coverage/grid/GridCoverage2DTest.java | 13 +-- 12 files changed, 288 insertions(+), 112 deletions(-) diff --git a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesUnderCursor.java b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesUnderCursor.java index d618731a48..8ec168b956 100644 --- a/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesUnderCursor.java +++ b/application/sis-javafx/src/main/java/org/apache/sis/gui/map/ValuesUnderCursor.java @@ -42,7 +42,6 @@ import org.apache.sis.referencing.operation.transform.TransferFunction; import org.apache.sis.gui.coverage.CoverageCanvas; import org.apache.sis.coverage.grid.GridExtent; import org.apache.sis.coverage.grid.GridCoverage; -import org.apache.sis.coverage.grid.GridEvaluator; import org.apache.sis.coverage.SampleDimension; import org.apache.sis.coverage.Category; import org.apache.sis.internal.system.Modules; @@ -211,7 +210,7 @@ public abstract class ValuesUnderCursor { /** * The object computing or interpolation sample values in the coverage. */ - private GridEvaluator evaluator; + private GridCoverage.Evaluator evaluator; /** * The selection status of each band. @@ -480,7 +479,7 @@ public abstract class ValuesUnderCursor { * @param point the cursor location in arbitrary CRS, or {@code null} if outside canvas region. * @return string representation of data under given position, or {@code null} if none. * - * @see GridEvaluator#apply(DirectPosition) + * @see GridCoverage.Evaluator#apply(DirectPosition) */ @Override public String evaluate(final DirectPosition point) { 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 df5cec01bd..11d4140e53 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 @@ -49,7 +49,7 @@ import org.opengis.referencing.crs.CoordinateReferenceSystem; * {@link Evaluator#apply(DirectPosition)} method signatures. * * @author Martin Desruisseaux (IRD, Geomatys) - * @version 1.2 + * @version 1.3 * @since 1.1 * @module */ @@ -114,7 +114,7 @@ public abstract class BandedCoverage { * * <h4>Multi-threading</h4> * {@code Evaluator}s are not thread-safe. For computing sample values concurrently, - * a new {@link Evaluator} instance should be created for each thread by invoking this + * a new {@code Evaluator} instance should be created for each thread by invoking this * method multiply times. * * @return a new function for computing or interpolating sample values. @@ -131,7 +131,7 @@ public abstract class BandedCoverage { * * @author Johann Sorel (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 1.1 + * @version 1.3 * * @see BandedCoverage#evaluator() * @@ -141,6 +141,7 @@ 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. * * @return the source of sample values for this evaluator. */ @@ -165,6 +166,31 @@ public abstract class BandedCoverage { */ void setNullIfOutside(boolean flag); + /** + * Returns {@code true} if this evaluator is allowed to wraparound coordinates that are outside the coverage. + * The initial value is {@code false}. This method may continue to return {@code false} even after a call to + * {@code setWraparoundEnabled(true)} if no wraparound axis has been found in the coverage CRS, + * or if automatic wraparound is not supported. + * + * @return {@code true} if this evaluator may wraparound coordinates that are outside the coverage. + * + * @since 1.3 + */ + boolean isWraparoundEnabled(); + + /** + * Specifies whether this evaluator is allowed to wraparound coordinates that are outside the coverage. + * If {@code true} and if a given coordinate is outside the coverage, then this evaluator may translate + * the point along a wraparound axis in an attempt to get the point inside the coverage. For example if + * the coverage CRS has a longitude axis, then the evaluator may translate the longitude value by a + * multiple of 360°. + * + * @param allow whether to allow wraparound of coordinates that are outside the coverage. + * + * @since 1.3 + */ + void setWraparoundEnabled(final boolean allow); + /** * Returns a sequence of double values for a given point in the coverage. * The CRS of the given point may be any coordinate reference system; 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 8f20214e49..ec53dc5663 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 @@ -232,11 +232,11 @@ public class BufferedGridCoverage extends GridCoverage { * Creates a new function for computing or interpolating sample values at given locations. * * <h4>Multi-threading</h4> - * {@code GridEvaluator}s are not thread-safe. For computing sample values concurrently, - * a new {@link GridEvaluator} instance should be created for each thread. + * {@code Evaluator}s are not thread-safe. For computing sample values concurrently, + * a new {@link Evaluator} instance should be created for each thread. */ @Override - public GridEvaluator evaluator() { + public Evaluator evaluator() { return new CellAccessor(this); } diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ConvertedGridCoverage.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ConvertedGridCoverage.java index 582912140d..b3f2b6d9aa 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ConvertedGridCoverage.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/ConvertedGridCoverage.java @@ -16,14 +16,12 @@ */ package org.apache.sis.coverage.grid; -import java.util.Map; import java.util.List; import java.util.Arrays; import java.util.ArrayList; import java.util.Optional; import java.awt.image.RenderedImage; import org.opengis.geometry.DirectPosition; -import org.opengis.coverage.CannotEvaluateException; import org.opengis.referencing.operation.MathTransform1D; import org.opengis.referencing.operation.TransformException; import org.opengis.referencing.operation.NoninvertibleTransformException; @@ -34,6 +32,9 @@ import org.apache.sis.measure.NumberRange; import org.apache.sis.image.DataType; import org.apache.sis.image.ImageProcessor; +// Branch-dependent imports +import org.opengis.coverage.CannotEvaluateException; + /** * Decorates a {@link GridCoverage} in order to convert sample values on the fly. @@ -43,7 +44,7 @@ import org.apache.sis.image.ImageProcessor; * <li>In calls to {@link #render(GridExtent)}, sample values are converted when first needed * on a tile-by-tile basis then cached for future reuse. Note however that discarding the * returned image may result in the lost of cached tiles.</li> - * <li>In calls to {@link GridEvaluator#apply(DirectPosition)}, the conversion is applied + * <li>In calls to {@link GridCoverage.Evaluator#apply(DirectPosition)}, the conversion is applied * on-the-fly each time in order to avoid the potentially costly tile computations.</li> * </ul> * @@ -232,76 +233,33 @@ final class ConvertedGridCoverage extends DerivedGridCoverage { * Creates a new function for computing or interpolating sample values at given locations. * * <h4>Multi-threading</h4> - * {@code GridEvaluator}s are not thread-safe. For computing sample values concurrently, - * a new {@link GridEvaluator} instance should be created for each thread. + * {@code Evaluator}s are not thread-safe. For computing sample values concurrently, + * a new {@link Evaluator} instance should be created for each thread. */ @Override - public GridEvaluator evaluator() { - return new SampleConverter(this); + public Evaluator evaluator() { + return new SampleConverter(); } /** - * Implementation of evaluator returned by {@link #evaluator()}. + * Implementation of evaluator returned by {@link ConvertedGridCoverage#evaluator()}. + * This evaluator delegates all operations to the {@link #source} coverage and converts + * the returned sample values. */ - private static final class SampleConverter extends GridEvaluator { - /** - * The evaluator provided by source coverage. - */ - private final GridEvaluator evaluator; - - /** - * Conversions from {@linkplain #source source} values to converted values. - */ - private final MathTransform1D[] converters; - + private final class SampleConverter extends EvaluatorWrapper { /** * Creates a new evaluator for the enclosing coverage. */ - SampleConverter(final ConvertedGridCoverage coverage) { - super(coverage); - evaluator = coverage.source.evaluator(); - converters = coverage.converters; - } - - /** - * Returns the default slice where to perform evaluation, or an empty map if unspecified. - */ - @Override - public Map<Integer,Long> getDefaultSlice() { - return evaluator.getDefaultSlice(); - } - - /** - * Sets the default slice where to perform evaluation when the points do not have enough dimensions. - */ - @Override - public void setDefaultSlice(Map<Integer,Long> slice) { - evaluator.setDefaultSlice(slice); + SampleConverter() { + super(source.evaluator()); } /** - * Returns {@code true} if this evaluator is allowed to wraparound coordinates that are outside the grid. + * Returns the enclosing coverage. */ @Override - public boolean isWraparoundEnabled() { - return evaluator.isWraparoundEnabled(); - } - - /** - * Specifies whether this evaluator is allowed to wraparound coordinates that are outside the grid. - */ - @Override - public void setWraparoundEnabled(final boolean allow) { - evaluator.setWraparoundEnabled(allow); - } - - /** - * Forwards configuration to the wrapped evaluator. - */ - @Override - public void setNullIfOutside(final boolean flag) { - evaluator.setNullIfOutside(flag); - super.setNullIfOutside(flag); + public GridCoverage getCoverage() { + return ConvertedGridCoverage.this; } /** @@ -313,8 +271,9 @@ final class ConvertedGridCoverage extends DerivedGridCoverage { */ @Override public double[] apply(final DirectPosition point) throws CannotEvaluateException { - final double[] values = evaluator.apply(point); + final double[] values = super.apply(point); if (values != null) try { + final MathTransform1D[] converters = ConvertedGridCoverage.this.converters; for (int i=0; i<converters.length; i++) { values[i] = converters[i].transform(values[i]); } @@ -323,14 +282,6 @@ final class ConvertedGridCoverage extends DerivedGridCoverage { } return values; } - - /** - * Converts the specified geospatial position to grid coordinates. - */ - @Override - public FractionalGridCoordinates toGridCoordinates(final DirectPosition point) throws TransformException { - return evaluator.toGridCoordinates(point); - } } /** 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 67c0f3ce60..e91dffc900 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 @@ -94,13 +94,12 @@ 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 GridEvaluator#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? + * @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? */ @Override - public GridEvaluator evaluator() { + public Evaluator evaluator() { return source.evaluator(); } diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/EvaluatorWrapper.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/EvaluatorWrapper.java new file mode 100644 index 0000000000..014335bcb7 --- /dev/null +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/EvaluatorWrapper.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.coverage.grid; + +import java.util.Map; +import org.opengis.geometry.DirectPosition; +import org.opengis.referencing.operation.TransformException; + +// Branch-dependent imports +import org.opengis.coverage.CannotEvaluateException; + + +/** + * An evaluator which delegates all operations to another evaluator. + * The default implementation of all methods except {@link #getCoverage()} delegates to the source evaluator. + * + * @author Martin Desruisseaux (Geomatys) + * @version 1.3 + * @since 1.3 + * @module + */ +abstract class EvaluatorWrapper implements GridCoverage.Evaluator { + /** + * The evaluator provided by source coverage. + * This is where all operations are delegated. + */ + private final GridCoverage.Evaluator source; + + /** + * Creates a new evaluator wrapper. + * + * @param source the evaluator to wrap. + */ + EvaluatorWrapper(final GridCoverage.Evaluator source) { + this.source = source; + } + + /** + * Returns whether to return {@code null} instead of throwing an exception if a point is outside coverage bounds. + */ + @Override + public boolean isNullIfOutside() { + return source.isNullIfOutside(); + } + + /** + * Specifies whether to return {@code null} instead of throwing an exception if a point is outside coverage bounds. + */ + @Override + public void setNullIfOutside(final boolean flag) { + source.setNullIfOutside(flag); + } + + /** + * Returns {@code true} if this evaluator is allowed to wraparound coordinates that are outside the grid. + */ + @Override + public boolean isWraparoundEnabled() { + return source.isWraparoundEnabled(); + } + + /** + * Specifies whether this evaluator is allowed to wraparound coordinates that are outside the grid. + */ + @Override + public void setWraparoundEnabled(final boolean allow) { + source.setWraparoundEnabled(allow); + } + + /** + * Returns the default slice where to perform evaluation, or an empty map if unspecified. + * This method should be overridden if this evaluator has been created for a coverage + * with a different grid geometry than the coverage of the wrapped evaluator. + */ + @Override + public Map<Integer,Long> getDefaultSlice() { + return source.getDefaultSlice(); + } + + /** + * Sets the default slice where to perform evaluation when the points do not have enough dimensions. + * This method should be overridden if this evaluator has been created for a coverage + * with a different grid geometry than the coverage of the wrapped evaluator. + */ + @Override + public void setDefaultSlice(Map<Integer,Long> slice) { + source.setDefaultSlice(slice); + } + + /** + * Converts the specified geospatial position to grid coordinates. + * This method should be overridden if this evaluator has been created for a coverage + * with a different grid geometry than the coverage of the wrapped evaluator. + */ + @Override + public FractionalGridCoordinates toGridCoordinates(final DirectPosition point) throws TransformException { + return source.toGridCoordinates(point); + } + + /** + * Returns a sequence of double values for a given point in the coverage. + * This method should be overridden if this evaluator is for a coverage + * doing some on-the-fly conversion of sample values. + * + * @param point the coordinate point where to evaluate. + * @throws CannotEvaluateException if the values can not be computed. + */ + @Override + public double[] apply(final DirectPosition point) throws CannotEvaluateException { + return source.apply(point); + } +} 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 d91504dd87..2995c448ee 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 @@ -50,7 +50,7 @@ import org.apache.sis.util.resources.Errors; * @author Martin Desruisseaux (Geomatys) * @version 1.2 * - * @see GridEvaluator#toGridCoordinates(DirectPosition) + * @see GridCoverage.Evaluator#toGridCoordinates(DirectPosition) * * @since 1.1 * @module @@ -71,7 +71,7 @@ public class FractionalGridCoordinates implements GridCoordinates, Serializable * * <div class="note"><b>Note:</b> * {@code FractionalGridCoordinates} are usually not created directly, but are instead obtained - * indirectly for example from the {@linkplain GridEvaluator#toGridCoordinates(DirectPosition) + * indirectly for example from the {@linkplain GridCoverage.Evaluator#toGridCoordinates(DirectPosition) * conversion of a geospatial position}.</div> * * @param dimension the number of dimensions. @@ -348,7 +348,7 @@ public class FractionalGridCoordinates implements GridCoordinates, Serializable * @return the grid coordinates converted using the given transform. * @throws TransformException if the grid coordinates can not be converted by {@code gridToCRS}. * - * @see GridEvaluator#toGridCoordinates(DirectPosition) + * @see GridCoverage.Evaluator#toGridCoordinates(DirectPosition) */ public DirectPosition toPosition(final MathTransform gridToCRS) throws TransformException { return gridToCRS.transform(new Position(this), null); 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 bd0425eedb..f6de832713 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 @@ -16,6 +16,7 @@ */ package org.apache.sis.coverage.grid; +import java.util.Map; import java.util.List; import java.util.Locale; import java.util.Optional; @@ -26,6 +27,7 @@ import org.opengis.geometry.DirectPosition; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform1D; +import org.opengis.referencing.operation.TransformException; import org.opengis.referencing.operation.NoninvertibleTransformException; import org.apache.sis.internal.util.UnmodifiableArrayList; import org.apache.sis.measure.NumberRange; @@ -301,8 +303,8 @@ public abstract class GridCoverage extends BandedCoverage { * conversions to grid indices are applied as needed. * * <h4>Multi-threading</h4> - * {@code GridEvaluator}s are not thread-safe. For computing sample values concurrently, - * a new {@link GridEvaluator} instance should be created for each thread by invoking this + * {@code Evaluator}s are not thread-safe. For computing sample values concurrently, + * a new {@code Evaluator} instance should be created for each thread by invoking this * method multiply times. * * @return a new function for computing or interpolating sample values. @@ -310,10 +312,86 @@ public abstract class GridCoverage extends BandedCoverage { * @since 1.1 */ @Override - public GridEvaluator evaluator() { + public Evaluator evaluator() { return new GridEvaluator(this); } + /** + * Interpolates values of sample dimensions at given positions. + * Values are computed by calls to {@link #apply(DirectPosition)} and are returned as {@code double[]}. + * This method extends {@link BandedCoverage.Evaluator} with the addition of some methods specific to + * gridded data. + * + * <h2>Multi-threading</h2> + * Evaluators are not thread-safe. An instance of {@code Evaluator} should be created + * for each thread that need to interpolate sample values. + * + * @author Johann Sorel (Geomatys) + * @author Martin Desruisseaux (Geomatys) + * @version 1.3 + * + * @see GridCoverage#evaluator() + * + * @since 1.3 + * @module + */ + 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. + * + * @return the source of sample values for this evaluator. + */ + @Override + GridCoverage getCoverage(); + + /** + * Returns the default slice where to perform evaluation, or an empty map if unspecified. + * Keys are dimensions from 0 inclusive to {@link GridGeometry#getDimension()} exclusive, + * and values are the grid coordinates of the slice in the dimension specified by the key. + * + * <p>This information allows to invoke {@link #apply(DirectPosition)} with for example + * two-dimensional points even if the underlying coverage is three-dimensional. + * The missing coordinate values are replaced by the values provided in the map.</p> + * + * @return the default slice where to perform evaluation, or an empty map if unspecified. + */ + Map<Integer,Long> getDefaultSlice(); + + /** + * Sets the default slice where to perform evaluation when the points do not have enough dimensions. + * A {@code null} argument restores the default value, which is to infer the slice from the coverage + * grid geometry. + * + * @param slice the default slice where to perform evaluation, or an empty map if none. + * @throws IllegalArgumentException if the map contains an illegal dimension or grid coordinate value. + * + * @see GridExtent#getSliceCoordinates() + */ + void setDefaultSlice(Map<Integer,Long> slice); + + /** + * Converts the specified geospatial position to grid coordinates. If the given position is associated to + * a non-null coordinate reference system (CRS) different than the {@linkplain #getCoverage() coverage} CRS, + * then this method automatically transforms that position to the {@linkplain #getCoordinateReferenceSystem() + * coverage CRS} before to compute grid coordinates. + * + * <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> + * + * @param point geospatial coordinates (in arbitrary CRS) to transform to grid coordinates. + * @return the grid coordinates for the given geospatial coordinates. + * @throws IncompleteGridGeometryException if the {@linkplain GridCoverage#getGridGeometry() grid geometry} + * does not define a "grid to CRS" transform, or if the given point has a non-null CRS but the + * coverage does not {@linkplain GridCoverage#getCoordinateReferenceSystem() have a CRS}. + * @throws TransformException if the given coordinates can not be transformed. + * + * @see FractionalGridCoordinates#toPosition(MathTransform) + */ + FractionalGridCoordinates toGridCoordinates(final DirectPosition point) throws TransformException; + } + /** * Returns a two-dimensional slice of grid data as a rendered image. The given {@code sliceExtent} argument specifies * the coordinates of the slice in all dimensions that are not in the two-dimensional image. For example if this grid diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java index 273e8b2e53..82e2e81127 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridCoverage2D.java @@ -502,13 +502,13 @@ public class GridCoverage2D extends GridCoverage { * Creates a new function for computing or interpolating sample values at given locations. * * <h4>Multi-threading</h4> - * {@code GridEvaluator}s are not thread-safe. For computing sample values concurrently, - * a new {@link GridEvaluator} instance should be created for each thread. + * {@code Evaluator}s are not thread-safe. For computing sample values concurrently, + * a new {@code Evaluator} instance should be created for each thread. * * @since 1.1 */ @Override - public GridEvaluator evaluator() { + public Evaluator evaluator() { return new PixelAccessor(); } diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridEvaluator.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridEvaluator.java index a13ca901d3..85014e7280 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridEvaluator.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridEvaluator.java @@ -53,7 +53,7 @@ import static java.util.logging.Logger.getLogger; /** - * Computes or interpolates values of sample dimensions at given positions. + * Default implementation of {@link GridCoverage.Evaluator} for interpolating values at given positions. * Values are computed by calls to {@link #apply(DirectPosition)} and are returned as {@code double[]}. * * <h2>Multi-threading</h2> @@ -72,7 +72,7 @@ import static java.util.logging.Logger.getLogger; * @since 1.1 * @module */ -public class GridEvaluator implements GridCoverage.Evaluator { +class GridEvaluator implements GridCoverage.Evaluator { /** * The coverage in which to evaluate sample values. */ @@ -170,8 +170,7 @@ public class GridEvaluator implements GridCoverage.Evaluator { /** * Returns the coverage from which this evaluator is fetching sample values. - * This is usually the coverage on which the {@link GridCoverage#evaluator()} method has been invoked, - * but not necessarily. Implementations are allowed to use a different coverage for efficiency. + * This is the coverage on which the {@link GridCoverage#evaluator()} method has been invoked. * * @return the source of sample values for this evaluator. */ @@ -193,6 +192,7 @@ public class GridEvaluator implements GridCoverage.Evaluator { * * @since 1.3 */ + @Override @SuppressWarnings("ReturnOfCollectionOrArrayField") // Because the map is unmodifiable. public Map<Integer,Long> getDefaultSlice() { if (slice == null) { @@ -214,6 +214,7 @@ public class GridEvaluator implements GridCoverage.Evaluator { * * @since 1.3 */ + @Override @SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter") public void setDefaultSlice(Map<Integer,Long> slice) { if (!Objects.equals(this.slice, slice)) { @@ -243,6 +244,7 @@ public class GridEvaluator implements GridCoverage.Evaluator { * * @since 1.2 */ + @Override public boolean isWraparoundEnabled() { return (wraparoundAxes != 0); } @@ -258,6 +260,7 @@ public class GridEvaluator implements GridCoverage.Evaluator { * * @since 1.2 */ + @Override public void setWraparoundEnabled(final boolean allow) { wraparoundAxes = 0; if (allow) try { @@ -410,28 +413,25 @@ public class GridEvaluator implements GridCoverage.Evaluator { } /** - * Converts the specified geospatial position to grid coordinates. If the given position - * is associated to a non-null coordinate reference system (CRS) different than the - * {@linkplain #coverage} CRS, then this method automatically transforms that position to the + * Converts the specified geospatial position to grid coordinates. + * If the given position is associated to a non-null coordinate reference system (CRS) different than the + * {@linkplain #getCoverage() coverage} CRS, then this method automatically transforms that position to the * {@linkplain GridCoverage#getCoordinateReferenceSystem() coverage CRS} before to compute grid coordinates. * * <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> * - * <p>The grid coordinates are relative to the grid of the coverage returned by {@link #getCoverage()}. - * This is usually the coverage on which the {@link GridCoverage#evaluator()} method has been invoked, - * but not necessarily. Implementations are allowed to use a different coverage for efficiency.</p> - * * @param point geospatial coordinates (in arbitrary CRS) to transform to grid coordinates. * @return the grid coordinates for the given geospatial coordinates. * @throws IncompleteGridGeometryException if the {@linkplain GridCoverage#getGridGeometry() grid geometry} * does not define a "grid to CRS" transform, or if the given point has a non-null CRS but the - * {@linkplain #coverage} does not {@linkplain GridCoverage#getCoordinateReferenceSystem() have a CRS}. + * coverage does not {@linkplain GridCoverage#getCoordinateReferenceSystem() have a CRS}. * @throws TransformException if the given coordinates can not be transformed. * * @see FractionalGridCoordinates#toPosition(MathTransform) */ + @Override public FractionalGridCoordinates toGridCoordinates(final DirectPosition point) throws TransformException { ArgumentChecks.ensureNonNull("point", point); try { diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java index 382c111eb3..e71d284659 100644 --- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java +++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/GridExtent.java @@ -841,7 +841,7 @@ public class GridExtent implements GridEnvelope, LenientComparable, Serializable * * @return grid coordinates for all dimensions where the grid has a size of 1. * - * @see GridEvaluator#setDefaultSlice(Map) + * @see GridCoverage.Evaluator#setDefaultSlice(Map) * * @since 1.3 */ diff --git a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridCoverage2DTest.java b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridCoverage2DTest.java index bf19bdeb57..33d1abf21a 100644 --- a/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridCoverage2DTest.java +++ b/core/sis-feature/src/test/java/org/apache/sis/coverage/grid/GridCoverage2DTest.java @@ -191,11 +191,11 @@ public strictfp class GridCoverage2DTest extends TestCase { } /** - * Tests {@link GridEvaluator#apply(DirectPosition)}. + * Tests {@link GridCoverage.Evaluator#apply(DirectPosition)}. */ @Test public void testEvaluator() { - final GridEvaluator evaluator = createTestCoverage().evaluator(); + final GridCoverage.Evaluator evaluator = createTestCoverage().evaluator(); /* * Test evaluation at indeger indices. No interpolation should be applied. */ @@ -227,11 +227,8 @@ public strictfp class GridCoverage2DTest extends TestCase { } /** - * Tests {@link GridEvaluator#apply(DirectPosition)} with a wraparound on the longitude axis. + * Tests {@link GridCoverage.Evaluator#apply(DirectPosition)} with a wraparound on the longitude axis. * This method tests a coordinate that would be outside the grid if wraparound was not applied. - * - * @todo Not yet implemented. One potential place where to implement this functionality could be - * {@link GridEvaluator#toGridPosition(DirectPosition)}. */ @Test @DependsOnMethod("testEvaluator") @@ -239,12 +236,12 @@ public strictfp class GridCoverage2DTest extends TestCase { final Matrix3 gridToCRS = new Matrix3(); gridToCRS.m00 = 100; // Scale gridToCRS.m02 = 100; // Offset - final GridEvaluator evaluator = createTestCoverage(MathTransforms.linear(gridToCRS)).evaluator(); + final GridCoverage.Evaluator evaluator = createTestCoverage(MathTransforms.linear(gridToCRS)).evaluator(); evaluator.setWraparoundEnabled(true); assertArrayEquals(new double[] {2}, evaluator.apply(new DirectPosition2D(100, 0)), STRICT); assertArrayEquals(new double[] {5}, evaluator.apply(new DirectPosition2D(200, 0)), STRICT); /* - * Following tests fail if wraparound is not applied by `GridEvaluator`. + * Following tests fail if wraparound is not applied by `GridCoverage.Evaluator`. */ assertArrayEquals(new double[] {5}, evaluator.apply(new DirectPosition2D(200 - 360, 0)), STRICT); assertArrayEquals(new double[] {2}, evaluator.apply(new DirectPosition2D(100 - 360, 0)), STRICT);