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
};
}
|