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 2018/08/01 16:54:15 UTC
[sis] branch geoapi-4.0 updated: Allow to specify the
MathTransformFactory to use when computing the transfer function (i.e. the
conversion from "pixel values" to "geophysics values") of a raster.
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 430dfd6 Allow to specify the MathTransformFactory to use when computing the transfer function (i.e. the conversion from "pixel values" to "geophysics values") of a raster.
430dfd6 is described below
commit 430dfd6fbf207b6d6d29b6576e75e545d8ec54ce
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Wed Aug 1 18:53:28 2018 +0200
Allow to specify the MathTransformFactory to use when computing the transfer function (i.e. the conversion from "pixel values" to "geophysics values") of a raster.
---
.../operation/transform/TransferFunction.java | 68 +++++++++++++++++++---
.../operation/transform/TransferFunctionTest.java | 39 ++++++++++++-
2 files changed, 98 insertions(+), 9 deletions(-)
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
index 372b375..7a138eb 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/TransferFunction.java
@@ -18,12 +18,16 @@ package org.apache.sis.referencing.operation.transform;
import java.io.Serializable;
import org.opengis.metadata.content.TransferFunctionType;
+import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.Matrix;
+import org.opengis.util.FactoryException;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.StringBuilders;
import org.apache.sis.util.Characters;
+import org.apache.sis.referencing.operation.matrix.Matrix2;
/**
@@ -54,7 +58,7 @@ import org.apache.sis.util.Characters;
* same SIS version.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
* @since 0.5
* @module
*/
@@ -188,38 +192,86 @@ public class TransferFunction implements Cloneable, Serializable {
}
/**
+ * Returns a linear transform created using the given factory.
+ * This method is used only when the user specify explicitly a factory to use.
+ *
+ * @param factory the factory to use.
+ * @param withScale {@code true} for using {@link #scale}, or {@code false} for replacing the scale by zero.
+ */
+ private MathTransform createAffineTransform(final MathTransformFactory factory, final boolean withScale) throws FactoryException {
+ return factory.createAffineTransform(new Matrix2(withScale ? scale : 0, offset, 0, 1));
+ }
+
+ /**
+ * Creates a transform from sample values to geophysics values using the given factory.
+ * This method constructs a transform mathematically equivalent to the one returned by
+ * {@link #getTransform()}, but allows to specify another factory than the default one.
+ *
+ * @param factory the factory to use for creating a transform.
+ * @return the transform from sample to geophysics values.
+ * @throws FactoryException if the given factory failed to create a transform.
+ *
+ * @since 1.0
+ */
+ public MathTransform createTransform(final MathTransformFactory factory) throws FactoryException {
+ ArgumentChecks.ensureNonNull("factory", factory);
+ MathTransform mt;
+ if (TransferFunctionType.LINEAR.equals(type)) {
+ mt = createAffineTransform(factory, true);
+ } else if (TransferFunctionType.EXPONENTIAL.equals(type)) {
+ mt = ExponentialTransform1D.create(base, scale);
+ if (offset != 0) {
+ mt = factory.createConcatenatedTransform(mt, createAffineTransform(factory, false));
+ }
+ } else if (TransferFunctionType.LOGARITHMIC.equals(type)) {
+ if (scale == 1) {
+ mt = LogarithmicTransform1D.create(base, offset);
+ } else {
+ mt = factory.createConcatenatedTransform(
+ LogarithmicTransform1D.create(base, 0),
+ createAffineTransform(factory, true));
+ }
+ } else {
+ throw new IllegalStateException(Errors.format(Errors.Keys.UnknownType_1, type));
+ }
+ return mt;
+ }
+
+ /**
* Returns the transform from sample values to geophysics values, as specified by the
* current properties of this {@code TransferFunction}.
*
* @return the transform from sample to geophysics values.
*/
public MathTransform1D getTransform() {
- if (transform == null) {
+ MathTransform1D mt = transform;
+ if (mt == null) {
if (TransferFunctionType.LINEAR.equals(type)) {
- transform = LinearTransform1D.create(scale, offset);
+ mt = LinearTransform1D.create(scale, offset);
} else if (TransferFunctionType.EXPONENTIAL.equals(type)) {
- transform = ExponentialTransform1D.create(base, scale);
+ mt = ExponentialTransform1D.create(base, scale);
if (offset != 0) { // Rarely occurs in practice.
- transform = MathTransforms.concatenate(transform, LinearTransform1D.create(0, offset));
+ mt = MathTransforms.concatenate(mt, LinearTransform1D.create(0, offset));
}
} else if (TransferFunctionType.LOGARITHMIC.equals(type)) {
if (scale == 1) {
- transform = LogarithmicTransform1D.create(base, offset);
+ mt = LogarithmicTransform1D.create(base, offset);
} else {
/*
* This case rarely occurs in practice, so we do not provide optimized constructor.
* The ExponentialTransform1D.concatenate(…) method will rewrite the equation using
* mathematical identities. The result will be a function with a different base.
*/
- transform = MathTransforms.concatenate(
+ mt = MathTransforms.concatenate(
LogarithmicTransform1D.create(base, 0),
LinearTransform1D.create(scale, offset));
}
} else {
throw new IllegalStateException(Errors.format(Errors.Keys.UnknownType_1, type));
}
+ transform = mt; // Set only after all steps completed successfully.
}
- return transform;
+ return mt;
}
/**
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
index a61b9f4..af7063f 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/TransferFunctionTest.java
@@ -17,8 +17,12 @@
package org.apache.sis.referencing.operation.transform;
import org.opengis.metadata.content.TransferFunctionType;
+import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransformFactory;
+import org.opengis.util.FactoryException;
import org.apache.sis.referencing.operation.matrix.Matrix2;
+import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
@@ -31,7 +35,7 @@ import static org.opengis.test.Assert.*;
* Tests {@link TransferFunction}.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.5
+ * @version 1.0
* @since 0.5
* @module
*/
@@ -138,4 +142,37 @@ public final strictfp class TransferFunctionTest extends TestCase {
assertEquals("scale", 0.15, b.getScale(), 1E-16);
assertEquals("offset", -2, b.getOffset(), 1E-16);
}
+
+ /**
+ * Same tests than above, but using a math transform factory.
+ *
+ * @throws FactoryException if the factory failed to create a transform.
+ */
+ @Test
+ public void testCreateTransform() throws FactoryException {
+ final MathTransformFactory factory = DefaultFactories.forBuildin(MathTransformFactory.class);
+ final TransferFunction f = new TransferFunction();
+ f.setScale(0.15);
+ f.setOffset(-2);
+ MathTransform transform = f.createTransform(factory);
+ assertInstanceOf("transform", LinearTransform.class, transform);
+ assertMatrixEquals("transform.matrix", new Matrix2(0.15, -2, 0, 1),
+ ((LinearTransform) transform).getMatrix(), STRICT);
+ /*
+ * Logarithmic case.
+ */
+ f.setType(TransferFunctionType.LOGARITHMIC);
+ f.setScale(1);
+ f.setOffset(-2);
+ transform = f.getTransform();
+ assertInstanceOf("transform", LogarithmicTransform1D.class, transform);
+ /*
+ * Exponential case.
+ */
+ f.setType(TransferFunctionType.EXPONENTIAL);
+ f.setScale(0.15);
+ f.setOffset(0);
+ transform = f.getTransform();
+ assertInstanceOf("transform", ExponentialTransform1D.class, transform);
+ }
}