You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2020/06/10 16:01:04 UTC
[sis] 01/03: Add a flag for reducing the amount of exceptions
created when a point is outside coverage bounds.
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 8910f3400127d1ab823cc3e4530341fbb31b25a2
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Wed Jun 10 12:41:49 2020 +0200
Add a flag for reducing the amount of exceptions created when a point is outside coverage bounds.
---
.../org/apache/sis/gui/map/ValuesUnderCursor.java | 1 +
.../sis/coverage/grid/ConvertedGridCoverage.java | 5 ++-
.../org/apache/sis/coverage/grid/Evaluator.java | 37 +++++++++++++++++++++-
.../apache/sis/coverage/grid/GridCoverage2D.java | 3 ++
.../org/apache/sis/coverage/grid/package-info.java | 20 +++++++++++-
5 files changed, 61 insertions(+), 5 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 a191e6c..4baf8a9 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
@@ -305,6 +305,7 @@ public abstract class ValuesUnderCursor {
return;
}
evaluator = coverage.forConvertedValues(true).evaluator();
+ evaluator.setNullIfOutside(true);
if (previous != null && bands.equals(previous.getSampleDimensions())) {
// Same configuration than previous coverage.
return;
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 787e6e0..3d117c0 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
@@ -215,9 +215,8 @@ final class ConvertedGridCoverage extends GridCoverage {
*/
@Override
public double[] apply(final DirectPosition point) throws CannotEvaluateException {
- final double[] values;
- try {
- values = evaluator.apply(point);
+ final double[] values = evaluator.apply(point);
+ if (values != null) try {
for (int i=0; i<converters.length; i++) {
values[i] = converters[i].transform(values[i]);
}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/Evaluator.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/Evaluator.java
index b7c16e2..c416f7e 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/Evaluator.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/Evaluator.java
@@ -54,7 +54,7 @@ public class Evaluator implements Function<DirectPosition, double[]> {
/**
* The coverage in which to evaluate sample values.
*/
- protected final GridCoverage coverage;
+ private final GridCoverage coverage;
/**
* The source coordinate reference system of the converter,
@@ -83,6 +83,14 @@ public class Evaluator implements Function<DirectPosition, double[]> {
private double[] values;
/**
+ * Whether to return {@code null} instead than throwing an exception if given point
+ * is outside coverage bounds.
+ *
+ * @see #isNullIfOutside()
+ */
+ private boolean nullIfOutside;
+
+ /**
* Creates a new evaluator for the given coverage. This constructor is protected for allowing
* {@link GridCoverage} subclasses to provide their own {@code Evaluator} implementations.
* For using an evaluator, invoke {@link GridCoverage#evaluator()} instead.
@@ -106,6 +114,30 @@ public class Evaluator implements Function<DirectPosition, double[]> {
}
/**
+ * Returns whether to return {@code null} instead than throwing an exception if a point is outside coverage bounds.
+ * The default value is {@code false}, which means that the default {@link #apply(DirectPosition)} behavior is to
+ * throw {@link PointOutsideCoverageException} for points outside bounds.
+ *
+ * @return whether {@link #apply(DirectPosition)} return {@code null} for points outside coverage bounds.
+ */
+ public boolean isNullIfOutside() {
+ return nullIfOutside;
+ }
+
+ /**
+ * Sets whether to return {@code null} instead than throwing an exception if a point is outside coverage bounds.
+ * The default value is {@code false}. Setting this flag to {@code true} may improve performances if the caller
+ * expects that many points will be outside coverage bounds, since it reduces the amount of exceptions to be
+ * created.
+ *
+ * @param flag whether {@link #apply(DirectPosition)} should use {@code null} return value instead than
+ * {@link PointOutsideCoverageException} for signaling that a point is outside coverage bounds.
+ */
+ public void setNullIfOutside(final boolean flag) {
+ nullIfOutside = flag;
+ }
+
+ /**
* 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;
* coordinate transformations will be applied as needed.
@@ -145,6 +177,9 @@ public class Evaluator implements Function<DirectPosition, double[]> {
final GridExtent subExtent = gc.toExtent(gridGeometry.extent, size);
return evaluate(coverage.render(subExtent), 0, 0);
} catch (ArithmeticException | IndexOutOfBoundsException | DisjointExtentException ex) {
+ if (nullIfOutside) {
+ return null;
+ }
throw (PointOutsideCoverageException) new PointOutsideCoverageException(
gc.pointOutsideCoverage(gridGeometry.extent), point).initCause(ex);
}
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 6f46031..27785cd 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
@@ -534,6 +534,9 @@ public class GridCoverage2D extends GridCoverage {
final int y = toIntExact(addExact(gc.getCoordinateValue(yDimension), gridToImageY));
return evaluate(data, x, y);
} catch (ArithmeticException | IndexOutOfBoundsException | DisjointExtentException ex) {
+ if (isNullIfOutside()) {
+ return null;
+ }
throw (PointOutsideCoverageException) new PointOutsideCoverageException(
gc.pointOutsideCoverage(gridGeometry.extent), point).initCause(ex);
}
diff --git a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/package-info.java b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/package-info.java
index 7e382c0..4ba9038 100644
--- a/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/package-info.java
+++ b/core/sis-feature/src/main/java/org/apache/sis/coverage/grid/package-info.java
@@ -17,9 +17,27 @@
/**
- * A coverage backed by a regular grid. In the two-dimensional case, the grid coverage is an image and the cells are pixels.
+ * A coverage backed by a regular grid.
+ * In the two-dimensional case, the grid coverage is an image and the cells are pixels.
* In the three-dimensional case, the cells are voxels.
*
+ * <p>{@link org.apache.sis.coverage.grid.GridCoverage2D}
+ * is a two-dimensional slice in a <var>n</var>-dimensional cube of data.
+ * Despite its name, {@code GridCoverage2D} instances can be associated to <var>n</var>-dimensional
+ * {@linkplain org.opengis.geometry.Envelope envelopes} providing that only two dimensions have a
+ * {@link org.apache.sis.coverage.grid.GridExtent#getSize(int) grid span} greater than 1.</p>
+ *
+ * <p>{@link org.apache.sis.coverage.grid.GridCoverageBuilder} is a convenience class
+ * making easier to create a grid coverage for some common cases.</p>
+ *
+ * <h2>Accurate definition of georeferencing information</h2>
+ * While it is possible to create a grid coverage from a geodetic
+ * {@linkplain org.opengis.geometry.Envelope envelope}, this approach should be used <em>in last resort</em> only.
+ * Instead, always specify the <cite>grid to CRS</cite> affine transform.
+ * This is preferable because envelopes have ambiguities
+ * (do we need to swap the longitude and latitude axes? Do we need to flip the <var>y</var> axis?).
+ * On the other hand, the <cite>grid to CRS</cite> affine transform is fully determinist.
+ *
* @author Martin Desruisseaux (Geomatys)
* @author Johann Sorel (Geomatys)
* @version 1.1