sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 01/03: Add a flag for reducing the amount of exceptions created when a point is outside coverage bounds.
Date Wed, 10 Jun 2020 16:01:04 GMT
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 <martin.desruisseaux@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


Mime
View raw message