sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 02/03: Improve the WKT formatting of `WraparoundTransform` for easier debugging.
Date Sat, 26 Sep 2020 22:05:20 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 8f64e30a01155ffe366e010281ee0447a7a06f6d
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Sat Sep 26 18:10:37 2020 +0200

    Improve the WKT formatting of `WraparoundTransform` for easier debugging.
---
 .../internal/referencing/WraparoundTransform.java  |  96 ++++++++++++-----
 .../internal/referencing/provider/Wraparound.java  | 120 +++++++++++++++++++++
 ...g.opengis.referencing.operation.OperationMethod |   1 +
 .../referencing/provider/ProvidersTest.java        |   3 +-
 4 files changed, 192 insertions(+), 28 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundTransform.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundTransform.java
index bb22229..9b0573d 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundTransform.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WraparoundTransform.java
@@ -20,6 +20,8 @@ import java.io.Serializable;
 import java.util.List;
 import org.opengis.util.FactoryException;
 import org.opengis.geometry.DirectPosition;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptorGroup;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
 import org.opengis.referencing.operation.CoordinateOperation;
@@ -31,10 +33,12 @@ import org.opengis.referencing.operation.TransformException;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.transform.AbstractMathTransform;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.internal.referencing.provider.Wraparound;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.util.Numerics;
-import org.apache.sis.io.wkt.Formatter;
 import org.apache.sis.measure.Longitude;
+import org.apache.sis.parameter.Parameters;
+import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.collection.BackingStoreException;
@@ -96,8 +100,16 @@ public final class WraparoundTransform extends AbstractMathTransform implements
      * Returns a transform with a wraparound behavior in the given dimension.
      * Input and output values in the wraparound dimension shall be normalized in the [−p/2
… +p/2] range
      * where <var>p</var> is the period (typically 360° for longitude axis).
+     *
+     * @param  dimension            number of dimensions of the transform to create.
+     * @param  wraparoundDimension  dimension where wraparound happens.
+     * @param  period               period on wraparound axis.
+     * @return the wraparound transform (may be a cached instance).
      */
-    static WraparoundTransform create(final int dimension, final int wraparoundDimension,
final double period) {
+    public static WraparoundTransform create(final int dimension, final int wraparoundDimension,
final double period) {
+        ArgumentChecks.ensureStrictlyPositive("dimension", dimension);
+        ArgumentChecks.ensureBetween("wraparoundDimension", 0, dimension - 1, wraparoundDimension);
+        ArgumentChecks.ensureStrictlyPositive("period", period);
         if (period == (Longitude.MAX_VALUE - Longitude.MIN_VALUE) && (wraparoundDimension
& ~1) == 0) {
             final int i = ((dimension - FIRST_CACHED_DIMENSION) << 1) | wraparoundDimension;
             if (i >= 0 && i < CACHE.length) {
@@ -267,6 +279,30 @@ public final class WraparoundTransform extends AbstractMathTransform
implements
     }
 
     /**
+     * Returns the parameter descriptors for this math transform.
+     *
+     * @return the parameter descriptors for this math transform.
+     */
+    @Override
+    public ParameterDescriptorGroup getParameterDescriptors() {
+        return Wraparound.PARAMETERS;
+    }
+
+    /**
+     * Returns the parameter values for this math transform.
+     *
+     * @return the parameter values for this math transform.
+     */
+    @Override
+    public ParameterValueGroup getParameterValues() {
+        final Parameters pg = Parameters.castOrWrap(getParameterDescriptors().createValue());
+        pg.getOrCreate(Wraparound.DIMENSION).setValue(dimension);
+        pg.getOrCreate(Wraparound.WRAPAROUND_DIMENSION).setValue(wraparoundDimension);
+        pg.getOrCreate(Wraparound.PERIOD).setValue(period);
+        return pg;
+    }
+
+    /**
      * Gets the dimension of input points.
      *
      * @return the dimension of input points.
@@ -450,21 +486,42 @@ public final class WraparoundTransform extends AbstractMathTransform
implements
                 }
                 /*
                  * Done moving the linear operations that we can move. Put everything together.
+                 * The `middle` transform should become simpler, ideally the identity transform.
+                 *
+                 * As an heuristic rule, we assume that it was worth simplifying if the implementation
class changed.
+                 * For example a `ProjectiveTransform` middle transform may be replaced by
`IdentityTransform` (ideal
+                 * case, but replacement by `TranslationTransform` is still good). But if
we got the same class, then
+                 * even if the matrix is a little bit simpler it is probably not simpler
enough; we will probably get
+                 * no performance benefit. In such case abandon this `tryConcatenate(…)`
attempt for reducing risk of
+                 * confusing WKT representation. It may happen in particular if `other` is
a `NormalizedProjection`
+                 * with normalization/denormalization matrices. "Simplifying" a (de)normalization
matrix may actually
+                 * complexify the map projection WKT representation.
+                 *
+                 * NOTE 1: the decision to apply simplification or not has no incidence on
the numerical values
+                 *         of transformation results; the transform chains should be equivalent
in either cases.
+                 *         It is only an attempt to avoid unnecessary changes (from a performance
point of view)
+                 *         in order to produce less surprising WKT representations during
debugging.
+                 *
+                 * NOTE 2: we assume that changes of implementation class can only be simplifications
(not more
+                 *         costly classes) because changes applied on the `middle` matrix
by above code makes
+                 *         that matrix closer to an identity matrix.
                  */
                 if (modified) {
                     MathTransform tr = mf.linear(middle);
-                    tr = mf.concatenate(applyOtherFirst, tr, step2);
-                    tr = mf.concatenate(applyOtherFirst, step1, tr);
-                    if (applyOtherFirst) {
-                        for (int i = count-2; --i >= 0;) {
-                            tr = mf.concatenate(steps.get(i), tr);
-                        }
-                    } else {
-                        for (int i = 2; i < count; i++) {
-                            tr = mf.concatenate(tr, steps.get(i));
+                    if (tr.getClass() != middleTr.getClass()) {               // See above
comment for rational.
+                        tr = mf.concatenate(applyOtherFirst, tr, step2);
+                        tr = mf.concatenate(applyOtherFirst, step1, tr);
+                        if (applyOtherFirst) {
+                            for (int i = count-2; --i >= 0;) {
+                                tr = mf.concatenate(steps.get(i), tr);
+                            }
+                        } else {
+                            for (int i = 2; i < count; i++) {
+                                tr = mf.concatenate(tr, steps.get(i));
+                            }
                         }
+                        return tr;
                     }
-                    return tr;
                 }
             } catch (NoninvertibleTransformException e) {
                 // Should not happen. But if it is the case, just abandon the optimization
effort.
@@ -549,21 +606,6 @@ public final class WraparoundTransform extends AbstractMathTransform
implements
     }
 
     /**
-     * Formats this transform as a pseudo-WKT element.
-     *
-     * @param  formatter  the formatter to use.
-     * @return the WKT element name, which is {@code "Wraparound_MT"}.
-     */
-    @Override
-    protected String formatTo(final Formatter formatter) {
-        formatter.append(dimension);
-        formatter.append(wraparoundDimension);
-        formatter.append(period);
-        formatter.setInvalidWKT(WraparoundTransform.class, null);
-        return "Wraparound_MT";
-    }
-
-    /**
      * Compares this transform with the given object for equality.
      *
      * @param  object  the object to compare with this transform.
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Wraparound.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Wraparound.java
new file mode 100644
index 0000000..26f36a3
--- /dev/null
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Wraparound.java
@@ -0,0 +1,120 @@
+/*
+ * 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.internal.referencing.provider;
+
+import javax.xml.bind.annotation.XmlTransient;
+import org.opengis.util.FactoryException;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.apache.sis.parameter.Parameters;
+import org.apache.sis.parameter.ParameterBuilder;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.internal.referencing.WraparoundTransform;
+
+
+/**
+ * Provider for {@link WraparoundTransform} (SIS-specific operation).
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 1.1
+ * @since   1.1
+ * @module
+ */
+@XmlTransient
+public final class Wraparound extends AbstractProvider {
+    /**
+     * Serial number for inter-operability with different versions.
+     */
+    private static final long serialVersionUID = -7464255385789611569L;
+
+    /**
+     * The operation parameter descriptor for the number of source and target dimensions.
+     *
+     * <!-- Generated by ParameterNameTableGenerator -->
+     * <table class="sis">
+     *   <caption>Parameter names</caption>
+     *   <tr><td> OGC:    </td><td> dim </td></tr>
+     * </table>
+     */
+    public static final ParameterDescriptor<Integer> DIMENSION;
+
+    /**
+     * The operation parameter descriptor for the dimension where wraparound is applied.
+     *
+     * <!-- Generated by ParameterNameTableGenerator -->
+     * <table class="sis">
+     *   <caption>Parameter names</caption>
+     *   <tr><td> SIS:    </td><td> wraparound_dim </td></tr>
+     * </table>
+     */
+    public static final ParameterDescriptor<Integer> WRAPAROUND_DIMENSION;
+
+    /**
+     * The operation parameter descriptor for for the period.
+     *
+     * <!-- Generated by ParameterNameTableGenerator -->
+     * <table class="sis">
+     *   <caption>Parameter names</caption>
+     *   <tr><td> SIS:    </td><td> period </td></tr>
+     * </table>
+     */
+    public static final ParameterDescriptor<Double> PERIOD;
+
+    /**
+     * The group of all parameters expected by this coordinate operation.
+     */
+    public static final ParameterDescriptorGroup PARAMETERS;
+    static {
+        final ParameterBuilder builder = builder().setCodeSpace(Citations.SIS, "SIS");
+        DIMENSION = builder.addName(Molodensky.DIMENSION.getName()).createBounded(Integer.class,
1, null, null);
+        WRAPAROUND_DIMENSION = builder.addName("wraparound_dim").createBounded(Integer.class,
0, null, null);
+        PERIOD = builder.addName("period").createStrictlyPositive(Double.NaN, null);
+        PARAMETERS = builder.addName("Wraparound")
+                .createGroup(DIMENSION,
+                             WRAPAROUND_DIMENSION,
+                             PERIOD);
+    }
+
+    /**
+     * Constructs a new provider.
+     */
+    public Wraparound() {
+        super(2, 2, PARAMETERS);
+    }
+
+    /**
+     * Creates a wraparound transform from the specified group of parameter values.
+     *
+     * @param  factory  the factory to use for creating concatenated transforms.
+     * @param  values   the group of parameter values.
+     * @return the created wraparound transform.
+     * @throws FactoryException if a transform can not be created.
+     */
+    @Override
+    public MathTransform createMathTransform(final MathTransformFactory factory, final ParameterValueGroup
values)
+            throws FactoryException
+    {
+        final Parameters pg = Parameters.castOrWrap(values);
+        return WraparoundTransform.create(
+                pg.intValue(DIMENSION),
+                pg.intValue(WRAPAROUND_DIMENSION),
+                pg.doubleValue(PERIOD));
+    }
+}
diff --git a/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
b/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
index c5dd229..429a260 100644
--- a/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
+++ b/core/sis-referencing/src/main/resources/META-INF/services/org.opengis.referencing.operation.OperationMethod
@@ -69,3 +69,4 @@ org.apache.sis.internal.referencing.provider.NADCON
 org.apache.sis.internal.referencing.provider.FranceGeocentricInterpolation
 org.apache.sis.internal.referencing.provider.Interpolation1D
 org.apache.sis.internal.referencing.provider.SatelliteTracking
+org.apache.sis.internal.referencing.provider.Wraparound
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
index 157953d..e3b4513 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/ProvidersTest.java
@@ -118,7 +118,8 @@ public final strictfp class ProvidersTest extends TestCase {
             NADCON.class,
             FranceGeocentricInterpolation.class,
             MolodenskyInterpolation.class,
-            Interpolation1D.class
+            Interpolation1D.class,
+            Wraparound.class
         };
     }
 


Mime
View raw message