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 2022/07/02 16:02:36 UTC
[sis] branch geoapi-4.0 updated (7af56f6285 -> d41d7fa838)
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git
from 7af56f6285 Replace `ProjectionLimits` by a more reliable mechanism defined directly in `MathTransform` implementations. For now only `Mercator` and `TransverseMercator` defines those limit. More will be added in the future.
new c71a1d11dc Better implementation of `getDomain(…)` on inverse transforms. Remove infinite values in Mercator.getDomain(…).
new 29beeb7358 Add `getDomain(…)` implementations for a few more map projections (only the easiest cases).
new d41d7fa838 Make a better use of new `MathTransforms.getDomain(…)` API in JavaFX viewer.
The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../sis/internal/map/coverage/RenderingData.java | 67 ++++------------------
.../java/org/apache/sis/geometry/Shapes2D.java | 22 ++++++-
.../projection/LambertConicConformal.java | 21 ++++++-
.../referencing/operation/projection/Mercator.java | 11 ++--
.../operation/projection/NormalizedProjection.java | 2 +-
.../operation/projection/PolarStereographic.java | 19 +++++-
.../operation/projection/TransverseMercator.java | 12 ++--
.../operation/projection/ZonedGridSystem.java | 21 ++++++-
.../operation/transform/AbstractMathTransform.java | 7 +--
.../operation/transform/DomainDefinition.java | 67 ++++++++++++++++------
10 files changed, 152 insertions(+), 97 deletions(-)
[sis] 03/03: Make a better use of new `MathTransforms.getDomain(…)` API in JavaFX viewer.
Posted by de...@apache.org.
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 d41d7fa8386e0d9e196fe92e5bbbd5c8dbac0041
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Sat Jul 2 17:36:42 2022 +0200
Make a better use of new `MathTransforms.getDomain(…)` API in JavaFX viewer.
---
.../sis/internal/map/coverage/RenderingData.java | 67 ++++------------------
.../java/org/apache/sis/geometry/Shapes2D.java | 22 ++++++-
2 files changed, 31 insertions(+), 58 deletions(-)
diff --git a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
index bb24a390cb..f87b995e2e 100644
--- a/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
+++ b/core/sis-portrayal/src/main/java/org/apache/sis/internal/map/coverage/RenderingData.java
@@ -30,7 +30,6 @@ import java.awt.geom.Rectangle2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import org.opengis.util.FactoryException;
-import org.opengis.geometry.Envelope;
import org.opengis.geometry.DirectPosition;
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.referencing.datum.PixelInCell;
@@ -48,7 +47,6 @@ import org.apache.sis.coverage.grid.PixelTranslation;
import org.apache.sis.coverage.SampleDimension;
import org.apache.sis.geometry.AbstractEnvelope;
import org.apache.sis.geometry.Envelope2D;
-import org.apache.sis.geometry.Envelopes;
import org.apache.sis.geometry.Shapes2D;
import org.apache.sis.image.PlanarImage;
import org.apache.sis.image.ErrorHandler;
@@ -185,21 +183,6 @@ public class RenderingData implements Cloneable {
*/
private GridGeometry dataGeometry;
- /**
- * The domain of validity of the objective CRS in units of the {@link #data} image.
- * This value needs to be recomputed when the objective CRS or the {@link #dataGeometry} changes.
- * It is used for avoiding failure to project a part of the image too far from what the projection
- * can handle, for example polar areas with a Mercator projection.
- */
- private Rectangle domainOfValidity;
-
- /**
- * A value for {@link #domainOfValidity} meaning that there is no limits. Should not be modified.
- */
- private static final Rectangle NO_LIMITS = new Rectangle(
- Integer.MIN_VALUE/2, Integer.MIN_VALUE/2,
- Integer.MAX_VALUE, Integer.MAX_VALUE);
-
/**
* Ranges of sample values in each band of {@link #data}. This is used for determining on which sample values
* to apply colors when user asked to apply a color ramp. May be {@code null}.
@@ -289,7 +272,6 @@ public class RenderingData implements Cloneable {
changeOfCRS = null;
cornerToObjective = null;
objectiveToCenter = null;
- domainOfValidity = null;
}
/**
@@ -439,7 +421,6 @@ public class RenderingData implements Cloneable {
final MathTransform inverse = concatenate(PixelInCell.CELL_CENTER, old, dataGeometry, toNew);
cornerToObjective = MathTransforms.concatenate(forward, cornerToObjective);
objectiveToCenter = MathTransforms.concatenate(objectiveToCenter, inverse);
- domainOfValidity = null; // Will be recomputed when needed.
}
return true;
}
@@ -568,40 +549,6 @@ public class RenderingData implements Cloneable {
}
}
- /**
- * Returns the bounds of the given image clipped to the domain of validity of the objective CRS.
- * The intent is to avoid a failure to reproject the image, for example if the image reaches the
- * poles and the objective CRS is a Mercator projection.
- */
- private Rectangle getValidImageBounds(final RenderedImage image) throws TransformException {
- Rectangle bounds = ImageUtilities.getBounds(image);
- if (domainOfValidity == NO_LIMITS) { // Identity comparison is okay here (quick check).
- return bounds;
- }
- if (domainOfValidity == null) {
- Envelope domain = MathTransforms.getDomain(changeOfCRS.getMathTransform().inverse()).orElse(null);
- if (domain == null) {
- domainOfValidity = NO_LIMITS;
- return bounds;
- }
- domain = Envelopes.transform(cornerToObjective.inverse(), domain);
- double x = domain.getMinimum(0);
- double y = domain.getMinimum(1);
- double w = domain.getSpan(0);
- double h = domain.getSpan(1);
- if (!(x >= Integer.MIN_VALUE)) x = Integer.MIN_VALUE/2; // Use `!` for catching NaN.
- if (!(y >= Integer.MIN_VALUE)) y = Integer.MIN_VALUE/2;
- if (!(h <= Integer.MAX_VALUE)) h = Integer.MAX_VALUE;
- if (!(w <= Integer.MAX_VALUE)) w = Integer.MAX_VALUE;
- domainOfValidity = new Rectangle(
- (int) Math.min(x, Integer.MAX_VALUE),
- (int) Math.min(y, Integer.MAX_VALUE),
- (int) Math.max(w, 0),
- (int) Math.max(h, 0));
- }
- return bounds.intersection(domainOfValidity);
- }
-
/**
* Creates the resampled image, then optionally applies an index color model.
* This method will compute the {@link MathTransform} steps from image coordinate system
@@ -650,7 +597,7 @@ public class RenderingData implements Cloneable {
/*
* Create a resampled image for current zoom level. If the image is zoomed, the resampled image bounds
* will be very large, potentially larger than 32 bit integer capacity (calculation done below clamps
- * the result to 32 bit integer range). This is okay since only visible tiles will be created.
+ * the result to 32 bit integer range). This is okay because only visible tiles will be created.
*
* NOTE: if user pans image close to integer range limit, a new resampled image will need to be computed
* for shifting away from integer overflow risk situation. This check is done by the caller.
@@ -659,9 +606,15 @@ public class RenderingData implements Cloneable {
displayToObjective = AffineTransforms2D.castOrCopy(inverse);
MathTransform cornerToDisplay = MathTransforms.concatenate(cornerToObjective, objectiveToDisplay);
MathTransform displayToCenter = MathTransforms.concatenate(inverse, objectiveToCenter);
- final Rectangle bounds = (Rectangle) Shapes2D.transform(
- MathTransforms.bidimensional(cornerToDisplay),
- getValidImageBounds(recoloredImage), new Rectangle());
+ /*
+ * If the source image is world-wide and if the transform involves a projection that can not represent
+ * the whole world, then we need to clip the image to a domain supported by the map projection.
+ */
+ final Rectangle bounds = ImageUtilities.getBounds(recoloredImage);
+ MathTransforms.getDomain(cornerToDisplay).ifPresent((domain) -> {
+ Shapes2D.intersect(bounds, domain, 0, 1);
+ });
+ Shapes2D.transform(MathTransforms.bidimensional(cornerToDisplay), bounds, bounds);
/*
* Verify if wraparound is really necessary. We do this check because the `displayToCenter` transform
* may be used for every pixels, so it is worth to make that transform more efficient if possible.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java b/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java
index ed6d594bf1..31b37d4f20 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java
@@ -22,6 +22,8 @@ import java.awt.geom.Line2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.AffineTransform;
+import java.awt.geom.RectangularShape;
+import org.opengis.geometry.Envelope;
import org.opengis.referencing.cs.CoordinateSystem;
import org.opengis.referencing.cs.CoordinateSystemAxis;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -49,7 +51,7 @@ import org.apache.sis.util.Static;
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Johann Sorel (Geomatys)
- * @version 1.1
+ * @version 1.3
* @since 0.8
* @module
*/
@@ -148,6 +150,24 @@ public final class Shapes2D extends Static {
2*radius, 2*radius);
}
+ /**
+ * Sets the given shape to the intersection of that shape with the given envelope.
+ *
+ * @param shape the shape to intersect. Will be modified in-place.
+ * @param envelope the envelope to intersect with the given shape.
+ * @param xdim dimension of <var>x</var> coordinates in the envelope. This is usually 0.
+ * @param ydim dimension of <var>y</var> coordinates in the envelope. This is usually 1.
+ *
+ * @since 1.3
+ */
+ public static void intersect(final RectangularShape shape, final Envelope envelope, final int xdim, final int ydim) {
+ final double xmin = Math.max(shape.getMinX(), envelope.getMinimum(xdim));
+ final double ymin = Math.max(shape.getMinY(), envelope.getMinimum(ydim));
+ final double xmax = Math.min(shape.getMaxX(), envelope.getMaximum(xdim));
+ final double ymax = Math.min(shape.getMaxY(), envelope.getMaximum(ydim));
+ shape.setFrame(xmin, ymin, xmax - xmin, ymax - ymin);
+ }
+
/**
* Transforms a rectangular envelope using the given math transform.
* The transformation is only approximated: the returned envelope may be bigger than
[sis] 01/03: Better implementation of `getDomain(…)` on inverse transforms. Remove infinite values in Mercator.getDomain(…).
Posted by de...@apache.org.
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 c71a1d11dc2d70cfb050d815e4ab4bba7e5097cb
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Fri Jul 1 18:23:37 2022 +0200
Better implementation of `getDomain(…)` on inverse transforms.
Remove infinite values in Mercator.getDomain(…).
---
.../referencing/operation/projection/Mercator.java | 11 ++--
.../operation/projection/NormalizedProjection.java | 2 +-
.../operation/projection/TransverseMercator.java | 12 ++--
.../operation/transform/AbstractMathTransform.java | 7 +--
.../operation/transform/DomainDefinition.java | 67 ++++++++++++++++------
5 files changed, 63 insertions(+), 36 deletions(-)
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
index 11d5b4b0fd..90097ef0a1 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
@@ -27,7 +27,7 @@ import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.geometry.GeneralEnvelope;
+import org.apache.sis.geometry.Envelope2D;
import org.apache.sis.internal.referencing.provider.Mercator1SP;
import org.apache.sis.internal.referencing.provider.Mercator2SP;
import org.apache.sis.internal.referencing.provider.MercatorSpherical;
@@ -402,12 +402,9 @@ subst: if ((variant.spherical || eccentricity == 0) && getClass() == Mercator.c
* @since 1.3
*/
@Override
- public final Optional<Envelope> getDomain(final DomainDefinition criteria) {
- final double limit = (variant == Variant.MILLER) ? PI/2 : PI/2 * (84d/90);
- final GeneralEnvelope domain = new GeneralEnvelope(2);
- domain.setRange(0, NEGATIVE_INFINITY, POSITIVE_INFINITY);
- domain.setRange(1, -limit, +limit);
- return Optional.of(domain);
+ public Optional<Envelope> getDomain(final DomainDefinition criteria) {
+ final double limit = (variant == Variant.MILLER) ? -PI/2 : -PI/2 * (84d/90);
+ return Optional.of(new Envelope2D(null, -0.5, limit, 1, -2*limit));
}
/**
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
index f8582c5bae..8b7e0c16a5 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
@@ -129,7 +129,7 @@ import static java.util.logging.Logger.getLogger;
* @author André Gosselin (MPO)
* @author Rueben Schulz (UBC)
* @author Rémi Maréchal (Geomatys)
- * @version 1.2
+ * @version 1.3
*
* @see ContextualParameters
* @see <a href="https://mathworld.wolfram.com/MapProjection.html">Map projections on MathWorld</a>
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
index cb227afa1f..10ee4214b5 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
@@ -26,7 +26,7 @@ import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.OperationMethod;
-import org.apache.sis.geometry.GeneralEnvelope;
+import org.apache.sis.geometry.Envelope2D;
import org.apache.sis.referencing.operation.matrix.Matrix2;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.referencing.operation.transform.DomainDefinition;
@@ -383,10 +383,12 @@ public class TransverseMercator extends NormalizedProjection {
* @since 1.3
*/
@Override
- public final Optional<Envelope> getDomain(final DomainDefinition criteria) {
- final GeneralEnvelope domain = new GeneralEnvelope(2);
- domain.setRange(0, -PI/2 * (40d/90), +PI/2 * (40d/90));
- domain.setRange(1, -PI/2 * (84d/90), +PI/2 * (84d/90));
+ public Optional<Envelope> getDomain(final DomainDefinition criteria) {
+ final Envelope2D domain = new Envelope2D();
+ domain.x = -PI/2 * (40d/90);
+ domain.y = -PI/2 * (84d/90);
+ domain.width = -2 * domain.x;
+ domain.height = -2 * domain.y;
return Optional.of(domain);
}
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
index efe0307a20..8e3709d859 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
@@ -31,7 +31,6 @@ import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.opengis.referencing.operation.OperationMethod;
-import org.apache.sis.geometry.Envelopes;
import org.apache.sis.geometry.GeneralDirectPosition;
import org.apache.sis.parameter.Parameterized;
import org.apache.sis.referencing.operation.matrix.Matrices;
@@ -1125,13 +1124,11 @@ public abstract class AbstractMathTransform extends FormattableObject
* @since 1.3
*/
@Override
- public Optional<Envelope> getDomain(DomainDefinition criteria) throws TransformException {
+ public Optional<Envelope> getDomain(final DomainDefinition criteria) throws TransformException {
final MathTransform inverse = inverse();
if (inverse instanceof AbstractMathTransform) {
final Optional<Envelope> domain = ((AbstractMathTransform) inverse).getDomain(criteria);
- if (domain.isPresent()) {
- return Optional.of(Envelopes.transform(inverse, domain.get()));
- }
+ return Optional.ofNullable(criteria.intersectOrTransform(domain.orElse(null), inverse));
}
return Optional.empty();
}
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DomainDefinition.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DomainDefinition.java
index 32d198c066..868536b017 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DomainDefinition.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/DomainDefinition.java
@@ -17,12 +17,13 @@
package org.apache.sis.referencing.operation.transform;
import java.util.Optional;
-import org.apache.sis.geometry.Envelopes;
import org.opengis.geometry.Envelope;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.apache.sis.referencing.CRS;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.geometry.Envelopes;
import org.apache.sis.geometry.GeneralEnvelope;
@@ -147,7 +148,13 @@ public class DomainDefinition {
*/
public void estimate(final MathTransform evaluated) throws TransformException {
if (evaluated instanceof AbstractMathTransform) {
- intersect(((AbstractMathTransform) evaluated).getDomain(this).orElse(null));
+ Envelope domain = ((AbstractMathTransform) evaluated).getDomain(this).orElse(null);
+ if (domain != null) {
+ if (stepToDomain != null) {
+ domain = Envelopes.transform(stepToDomain.concatenation(), domain);
+ }
+ intersect(domain);
+ }
}
}
@@ -197,29 +204,53 @@ public class DomainDefinition {
/**
* Sets the domain to the intersection of current domain with the specified envelope.
- * The envelope coordinates shall be in units of the inputs of the {@link MathTransform} given to
- * {@link #estimate(MathTransform)}. If that method is invoked recursively in a chain of transforms,
- * then this method will automatically transform the given envelope to the units of the inputs of the
- * first transform in the chain. If the given domain is {@code null}, then this method does nothing.
+ * The envelope coordinates shall be in units of the inputs of the first {@link MathTransform}
+ * given to {@link #estimate(MathTransform)}. If that method is invoked recursively in a chain
+ * of transforms, callers are responsible for converting the envelope.
+ *
+ * @param domain the domain to intersect with.
+ */
+ public void intersect(final Envelope domain) {
+ ArgumentChecks.ensureNonNull("domain", domain);
+ if (limits == null) {
+ limits = domain;
+ } else {
+ if (intersection == null) {
+ limits = intersection = new GeneralEnvelope(limits);
+ }
+ intersection.intersect(domain);
+ }
+ }
+
+ /**
+ * Transforms the given envelope, then either returns it or delegates to {@link #intersect(Envelope)}.
+ * If {@code prefix} was the only transform applied, then the transformed envelope is returned.
+ * Otherwise the transformed envelope is intersected with current domain and {@code null} is returned.
+ *
+ * <p>This method behavior allows opportunistic implementation of
+ * {@link org.apache.sis.referencing.operation.transform.AbstractMathTransform.Inverse#getDomain(DomainDefinition)}.
+ * When above-cited method is invoked directly by users, they should get the transformed envelope because there is
+ * no other transform queued in {@link #stepToDomain}. But if above-cited method is invoked for a transform in the
+ * middle of a transforms chain, then the transformed envelope can not be returned because it would not be in the
+ * CRS expected by method contract. But because that situation is specific to {@link ConcatenatedTransform},
+ * it should be unnoticed by users.</p>
*
* @param domain the domain to intersect with, or {@code null} if none.
- * @throws TransformException if the envelope can not be transformed to the domain of the first step
- * in a chain of transforms.
+ * @param prefix a transform to apply on the envelope before other transforms.
+ * @return the transformed envelope if {@code prefix} was the only transform applied, or {@code null} otherwise.
+ * @throws TransformException if the envelope can not be transformed to the domain of the first transform step.
*/
- public void intersect(Envelope domain) throws TransformException {
+ final Envelope intersectOrTransform(Envelope domain, MathTransform prefix) throws TransformException {
if (domain != null) {
if (stepToDomain != null) {
- domain = Envelopes.transform(stepToDomain.concatenation(), domain);
- }
- if (limits == null) {
- limits = domain;
- } else {
- if (intersection == null) {
- limits = intersection = new GeneralEnvelope(limits);
- }
- intersection.intersect(domain);
+ prefix = MathTransforms.concatenate(prefix, stepToDomain.concatenation());
+ domain = Envelopes.transform(prefix, domain);
+ intersect(domain);
+ return null;
}
+ domain = Envelopes.transform(prefix, domain);
}
+ return domain;
}
/**
[sis] 02/03: Add `getDomain(…)` implementations for a few more map projections (only the easiest cases).
Posted by de...@apache.org.
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 29beeb73586d8a4bde5d57d3d50deb9d1b5d8f6f
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Sat Jul 2 16:57:08 2022 +0200
Add `getDomain(…)` implementations for a few more map projections (only the easiest cases).
---
.../operation/projection/LambertConicConformal.java | 21 ++++++++++++++++++++-
.../operation/projection/PolarStereographic.java | 19 ++++++++++++++++++-
.../operation/projection/ZonedGridSystem.java | 21 ++++++++++++++++++++-
3 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConicConformal.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConicConformal.java
index a20dcb8a44..0a6923d1f8 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConicConformal.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConicConformal.java
@@ -17,7 +17,9 @@
package org.apache.sis.referencing.operation.projection;
import java.util.EnumMap;
+import java.util.Optional;
import java.util.regex.Pattern;
+import org.opengis.geometry.Envelope;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.referencing.operation.MathTransform;
@@ -26,8 +28,10 @@ import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.Matrix;
import org.apache.sis.measure.Latitude;
import org.apache.sis.parameter.Parameters;
+import org.apache.sis.geometry.Envelope2D;
import org.apache.sis.referencing.operation.matrix.Matrix2;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.DomainDefinition;
import org.apache.sis.referencing.operation.transform.ContextualParameters;
import org.apache.sis.internal.referencing.provider.LambertConformal1SP;
import org.apache.sis.internal.referencing.provider.LambertConformal2SP;
@@ -62,7 +66,7 @@ import static org.apache.sis.internal.referencing.Formulas.fastHypot;
* @author André Gosselin (MPO)
* @author Rueben Schulz (UBC)
* @author Rémi Maréchal (Geomatys)
- * @version 1.2
+ * @version 1.3
* @since 0.6
* @module
*/
@@ -422,6 +426,21 @@ public class LambertConicConformal extends ConformalProjection {
return context.completeTransform(factory, kernel);
}
+ /**
+ * Returns the domain of input coordinates.
+ * The limits defined by this method are arbitrary and may change in any future implementation.
+ * Current implementation sets a longitude range of ±180° (i.e. the world) and a latitude range
+ * from pole to equator in the hemisphere of the projection.
+ *
+ * @since 1.3
+ */
+ @Override
+ public Optional<Envelope> getDomain(final DomainDefinition criteria) {
+ final double x = abs(θ_bound);
+ final double y = copySign(PI/2, -n);
+ return Optional.of(new Envelope2D(null, -x, Math.min(y, 0), 2*x, Math.abs(y)));
+ }
+
/**
* Converts the specified (θ,φ) coordinate (units in radians) and stores the result in {@code dstPts}.
* In addition, opportunistically computes the projection derivative if {@code derivate} is {@code true}.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java
index 510bbd2251..0694632c59 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/PolarStereographic.java
@@ -17,15 +17,19 @@
package org.apache.sis.referencing.operation.projection;
import java.util.EnumMap;
+import java.util.Optional;
import java.util.regex.Pattern;
+import org.opengis.geometry.Envelope;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.Matrix;
+import org.apache.sis.geometry.Envelope2D;
import org.apache.sis.referencing.operation.matrix.Matrix2;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.DomainDefinition;
import org.apache.sis.referencing.operation.transform.ContextualParameters;
import org.apache.sis.internal.referencing.provider.PolarStereographicA;
import org.apache.sis.internal.referencing.provider.PolarStereographicB;
@@ -57,7 +61,7 @@ import static org.apache.sis.internal.referencing.Formulas.fastHypot;
* @author Martin Desruisseaux (MPO, IRD, Geomatys)
* @author Rueben Schulz (UBC)
* @author Rémi Maréchal (Geomatys)
- * @version 1.2
+ * @version 1.3
*
* @see ObliqueStereographic
*
@@ -299,6 +303,19 @@ public class PolarStereographic extends ConformalProjection {
return context.completeTransform(factory, kernel);
}
+ /**
+ * Returns the domain of input coordinates.
+ * The limits defined by this method are arbitrary and may change in any future implementation.
+ * Current implementation sets a longitude range of ±180° (i.e. the world) and a latitude range
+ * from pole to equator in the hemisphere of the projection.
+ *
+ * @since 1.3
+ */
+ @Override
+ public Optional<Envelope> getDomain(final DomainDefinition criteria) {
+ return Optional.of(new Envelope2D(null, -PI, -PI/2, 2*PI, PI/2));
+ }
+
/**
* Converts the specified (θ,φ) coordinate (units in radians) and stores the result in {@code dstPts}.
* In addition, opportunistically computes the projection derivative if {@code derivate} is {@code true}.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ZonedGridSystem.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ZonedGridSystem.java
index b5b66a2a30..146f574add 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ZonedGridSystem.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ZonedGridSystem.java
@@ -17,7 +17,9 @@
package org.apache.sis.referencing.operation.projection;
import java.util.EnumMap;
+import java.util.Optional;
import java.io.Serializable;
+import org.opengis.geometry.Envelope;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterValueGroup;
@@ -30,12 +32,15 @@ import org.opengis.referencing.operation.NoninvertibleTransformException;
import org.apache.sis.referencing.operation.transform.AbstractMathTransform;
import org.apache.sis.referencing.operation.transform.AbstractMathTransform2D;
import org.apache.sis.referencing.operation.transform.ContextualParameters;
+import org.apache.sis.referencing.operation.transform.DomainDefinition;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.parameter.Parameters;
+import org.apache.sis.geometry.Envelope2D;
import org.apache.sis.measure.Longitude;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.internal.util.Numerics;
+import static java.lang.Math.PI;
import static java.lang.Math.floor;
import static org.apache.sis.internal.referencing.provider.TransverseMercator.*;
import static org.apache.sis.internal.referencing.provider.ZonedTransverseMercator.*;
@@ -59,7 +64,7 @@ import static org.apache.sis.internal.referencing.provider.ZonedTransverseMercat
* EPSG:32600 (northern hemisphere) and EPSG:32700 (southern hemisphere).</p>
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.3
* @since 0.8
* @module
*/
@@ -145,6 +150,20 @@ public class ZonedGridSystem extends AbstractMathTransform2D implements Serializ
return projection.getParameterValues();
}
+ /**
+ * Returns the domain of input coordinates.
+ * The limits defined by this method are arbitrary and may change in any future implementation.
+ * Current implementation sets a longitude range of ±180° (i.e. the world) and a latitude range
+ * from 84°S to 84°N.
+ *
+ * @since 1.3
+ */
+ @Override
+ public Optional<Envelope> getDomain(final DomainDefinition criteria) {
+ final double y = -PI/2 * (84d/90);
+ return Optional.of(new Envelope2D(null, -PI, y, 2*PI, -2*y));
+ }
+
/**
* Converts the specified (λ,φ) coordinate and stores the result in {@code dstPts}.
* In addition, opportunistically computes the projection derivative if {@code derivate} is {@code true}.