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
The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
new aca9be6 The non-linear transform concatenated by
LocalizationGridBuilder needs to take in account axis swapping.
aca9be6 is described below
commit aca9be685b338e5dc9e1d4cb065074e78ee75780
Author: Martin Desruisseaux <[email protected]>
AuthorDate: Mon Mar 11 20:29:42 2019 +0100
The non-linear transform concatenated by LocalizationGridBuilder needs to
take in account axis swapping.
---
.../operation/builder/LinearTransformBuilder.java | 16 ++++++-------
.../operation/builder/LocalizationGridBuilder.java | 18 ++++++++++++--
.../operation/builder/ProjectedTransformTry.java | 28 ++++++++++++++++------
.../builder/LinearTransformBuilderTest.java | 10 ++++----
4 files changed, 50 insertions(+), 22 deletions(-)
diff --git
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
index c1492e2..df447ae 100644
---
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
+++
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
@@ -1121,8 +1121,9 @@ search: for (int j=domain(); --j >= 0;) {
* {@linkplain #correlation() correlation} coefficients. It may be none.
*
* <p>The linearizers are specified as {@link MathTransform}s from current
target coordinates to other spaces
- * where <cite>sources to new targets</cite> transforms may be more
linear. The keys in the map are arbitrary
- * identifiers used in {@link #toString()} for debugging purpose.
+ * where <cite>sources to new targets</cite> transforms may be more linear.
+ * Keys in the map are arbitrary identifiers used in {@link #toString()}
for debugging purpose.
+ * Values in the map are non-{@link LinearTransform} (linear transforms
are not forbidden, but are useless for this process).
* The {@code dimensions} argument specifies which target dimensions to
project and can be null or omitted
* if the projections shall be applied on all target coordinates. It is
possible to invoke this method many
* times with different {@code dimensions} argument values.</p>
@@ -1148,10 +1149,7 @@ search: for (int j=domain(); --j >= 0;) {
linearizers = new ArrayList<>();
}
for (final Map.Entry<String,MathTransform> entry :
projections.entrySet()) {
- ProjectedTransformTry t = new
ProjectedTransformTry(entry.getKey(), entry.getValue(), dimensions, tgtDim);
- if (!t.projection.isIdentity()) {
- linearizers.add(t);
- }
+ linearizers.add(new ProjectedTransformTry(entry.getKey(),
entry.getValue(), dimensions, tgtDim));
}
}
@@ -1328,7 +1326,7 @@ search: for (int j=domain(); --j >= 0;) {
}
/**
- * If all target coordinates have been projected to another space, returns
the projection applied.
+ * If target coordinates have been projected to another space, returns
that projection.
* This method returns a non-empty value only if all the following
conditions are met:
*
* <ol>
@@ -1340,13 +1338,15 @@ search: for (int j=domain(); --j >= 0;) {
*
* If this method returns a non-empty value, then the envelope returned by
{@link #getTargetEnvelope()}
* and all control points returned by {@link #getControlPoint(int[])} are
projected by this transform.
+ * The returned transform includes axes swapping specified by the {@code
dimensions} argument given to
+ * <code>{@linkplain #addLinearizers(Map, int...) addLinearizers}(…,
dimensions)</code>.
*
* @return the projection applied on target coordinates before to compute
a linear transform.
*
* @since 1.0
*/
public Optional<MathTransform> linearizer() {
- return (appliedLinearizer != null) ?
Optional.of(appliedLinearizer.projection) : Optional.empty();
+ return (appliedLinearizer != null) ?
Optional.of(appliedLinearizer.projection()) : Optional.empty();
}
/**
diff --git
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
index 6a919d0..86a9304 100644
---
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
+++
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LocalizationGridBuilder.java
@@ -664,7 +664,21 @@ public class LocalizationGridBuilder extends
TransformBuilder {
/**
* Returns statistics of differences between values calculated by the
given transform and actual values.
* The given math transform is typically the transform computed by {@link
#create(MathTransformFactory)},
- * but not necessarily.
+ * but not necessarily. The returned statistics are:
+ *
+ * <ol class="verbose">
+ * <li>One {@code Statistics} instance for each target dimension,
containing statistics about the differences between
+ * coordinates computed by the given transform and expected
coordinates. For each (<var>i</var>,<var>j</var>) indices
+ * in this grid, the indices are transformed by a call to {@code
mt.transform(…)} and the result is compared with the
+ * coordinates given by <code>{@linkplain #getControlPoint(int, int)
getControlPoint}(i,j)</code>.
+ * Those statistics are identified by labels like “P → x” and “P → y”
where <var>P</var> stands for pixel coordinates.</li>
+ * <li>One {@code Statistics} instance for each source dimension,
containing statistics about the differences between
+ * coordinates computed by the <em>inverse</em> of the transform and
expected coordinates.
+ * For each (<var>x</var>,<var>y</var>) control point in this grid,
the points are transformed by a call
+ * to {@code mt.inverse().transform(…)} and the result is compared
with the pixel indices of that point.
+ * Those statistics are identified by labels like “i ← P′” and “j ←
P′” where <var>P′</var> stands for
+ * the control point.</li>
+ * </ol>
*
* @param mt the transform to test.
* @return statistics of difference between computed values and expected
values for each target dimension.
@@ -741,7 +755,7 @@ public class LocalizationGridBuilder extends
TransformBuilder {
* <li>Number of points.</li>
* <li>Linearizers and their correlation coefficients (if
available).</li>
* <li>The linear component of the transform.</li>
- * <li>Error statistics.</li>
+ * <li>Error statistics, as documented in the {@link
#error(MathTransform)} method.</li>
* </ul>
*
* The string representation may change in any future version.
diff --git
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ProjectedTransformTry.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ProjectedTransformTry.java
index 92f01ba..4be4ecd 100644
---
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ProjectedTransformTry.java
+++
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ProjectedTransformTry.java
@@ -28,7 +28,10 @@ import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.io.TableAppender;
import org.apache.sis.util.ArraysExt;
import org.apache.sis.util.Exceptions;
+import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Vocabulary;
+import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
/**
@@ -66,15 +69,17 @@ final class ProjectedTransformTry implements
Comparable<ProjectedTransformTry> {
private static final int BUFFER_CAPACITY = 512;
/**
- * A name by witch this projection attempt is identified.
+ * A name by witch this projection attempt is identified, or {@code null}
for the identity transform.
*/
private String name;
/**
* A conversion from a non-linear grid (typically with longitude and
latitude values) to
* something that may be more linear (typically, but not necessarily, a
map projection).
+ *
+ * @see #projection()
*/
- final MathTransform projection;
+ private final MathTransform projection;
/**
* Maps {@link #projection} dimensions to {@link LinearTransformBuilder}
target dimensions.
@@ -123,6 +128,8 @@ final class ProjectedTransformTry implements
Comparable<ProjectedTransformTry> {
* @param expectedDimension number of {@link LinearTransformBuilder}
target dimensions.
*/
ProjectedTransformTry(final String name, final MathTransform projection,
final int[] dimensions, int expectedDimension) {
+ ArgumentChecks.ensureNonNull("name", name);
+ ArgumentChecks.ensureNonNull("projection", projection);
this.name = name;
this.projection = projection;
this.dimensions = dimensions;
@@ -143,14 +150,22 @@ final class ProjectedTransformTry implements
Comparable<ProjectedTransformTry> {
}
/**
- * Returns the name of this object, or {@code null} if unspecified.
- * This is used only for formatting error messages.
+ * Returns the name of this object, or {@code null} if this is the
identity transform created by
+ * {@link #ProjectedTransformTry(float)}. Should never be {@code null} for
name returned to user.
*/
final String name() {
return name;
}
/**
+ * Returns the projection, taking in account axis swapping if {@link
#dimensions} is not an arithmetic progression.
+ */
+ final MathTransform projection() {
+ MathTransform mt =
MathTransforms.linear(Matrices.createDimensionSelect(dimensions.length,
dimensions));
+ return MathTransforms.concatenate(mt, projection);
+ }
+
+ /**
* Transforms target coordinates of a localization grid. The {@code
coordinates} argument is the value
* of {@link LinearTransformBuilder#targets}, without clone (this method
will only read those arrays).
* Only arrays at indices given by {@link #dimensions} will be read; the
other arrays will be ignored.
@@ -306,13 +321,12 @@ final class ProjectedTransformTry implements
Comparable<ProjectedTransformTry> {
*
* @param table the table where to write a row.
* @param nf format to use for writing coefficients, or {@code null}
if not yet created.
- * @param locale the locale to use if a number format must be created.
+ * @param locale the locale to use for messages or if a number format
must be created.
* @return format used for writing coefficients, or {@code null}.
*/
final NumberFormat summarize(final TableAppender table, NumberFormat nf,
final Locale locale) {
if (name == null) {
- final short key = (projection == null) ? Vocabulary.Keys.Identity
: Vocabulary.Keys.Unnamed;
- name = Vocabulary.getResources(locale).getString(key);
+ name =
Vocabulary.getResources(locale).getString(Vocabulary.Keys.Identity);
}
table.append(name).nextColumn();
String message = "";
diff --git
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
index 582eaa1..868ce37 100644
---
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
+++
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
@@ -430,12 +430,12 @@ public final strictfp class LinearTransformBuilderTest
extends TestCase {
builder.setControlPoint(source, target);
}
}
- final NonLinearTransform x2y3 = new NonLinearTransform();
- final NonLinearTransform x3y2 = new NonLinearTransform();
- builder.addLinearizers(Collections.singletonMap("x² y³", x2y3));
- builder.addLinearizers(Collections.singletonMap("x³ y²", x3y2), 1, 0);
+ final NonLinearTransform tr = new NonLinearTransform();
+ builder.addLinearizers(Collections.singletonMap("x² y³", tr));
+ builder.addLinearizers(Collections.singletonMap("x³ y²", tr), 1, 0);
final Matrix m = builder.create(null).getMatrix();
- assertSame("linearizer", x3y2, builder.linearizer().get());
+ assertEquals("linearizer", "x³ y²", builder.linearizerID());
+ assertNotSame("linearizer", tr, builder.linearizer().get()); // Not
same because axes should have been swapped.
assertMatrixEquals("linear",
new Matrix3(2, 0, 3,
0, 1, 1,