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 <[email protected]>
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;
     }
 
     /**

Reply via email to