Author: desruisseaux
Date: Mon Mar 5 22:13:04 2018
New Revision: 1825945
URL: http://svn.apache.org/viewvc?rev=1825945&view=rev
Log:
Addition of SpecializationTransform2D and public API for making those
transforms accessible.
This complete https://issues.apache.org/jira/browse/SIS-408
Added:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform1D.txt
(with props)
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform2D.java
(with props)
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java?rev=1825945&r1=1825944&r2=1825945&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/MathTransforms.java
[UTF-8] Mon Mar 5 22:13:04 2018
@@ -16,10 +16,12 @@
*/
package org.apache.sis.referencing.operation.transform;
+import java.util.Map;
import java.util.List;
import java.util.Collections;
import java.awt.geom.AffineTransform;
import org.opengis.util.FactoryException;
+import org.opengis.geometry.Envelope;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
@@ -51,7 +53,7 @@ import org.apache.sis.util.Static;
* GeoAPI factory interfaces instead.
*
* @author Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 1.0
*
* @see MathTransformFactory
*
@@ -179,6 +181,45 @@ public final class MathTransforms extend
}
/**
+ * Creates a transform defined as one transform applied globally except in
sub-areas where more accurate
+ * transforms are available. Such constructs appear in some datum shift
files. The result of transforming
+ * a point by the returned {@code MathTransform} is as if iterating over
all given {@link Envelope}s in
+ * no particular order, find the smallest one containing the point to
transform, then use the associated
+ * {@link MathTransform} for transforming the point. If the point is not
found in any envelope,
+ * then the global transform is applied.
+ *
+ * <p>The following constraints apply:</p>
+ * <ul>
+ * <li>The global transform must be a reasonable approximation of the
specialized transforms
+ * (this is required for calculating the inverse transform).</li>
+ * <li>All transforms in the {@code specializations} map must have the
same number of source and target
+ * dimensions than the {@code global} transform.</li>
+ * <li>All envelopes in the {@code specializations} map must have the
same number of dimensions
+ * than the global transform <em>source</em> dimensions.</li>
+ * <li>In current implementation, each envelope must either be fully
included in another envelope,
+ * or not overlap any other envelope.</li>
+ * </ul>
+ *
+ * @param global the transform to use globally where there is no
suitable specialization.
+ * @param specializations more accurate transforms available in some
sub-areas.
+ * @return a transform applying the given global transform except in
sub-areas where specializations are available.
+ * @throws IllegalArgumentException if a constraint is not meet.
+ *
+ * @since 1.0
+ */
+ public static MathTransform specialize(final MathTransform global, final
Map<Envelope,MathTransform> specializations) {
+ ArgumentChecks.ensureNonNull("generic", global);
+ ArgumentChecks.ensureNonNull("specializations", specializations);
+ if (specializations.isEmpty()) {
+ return global;
+ } else if (global.getSourceDimensions() == 2 &&
global.getTargetDimensions() == 2) {
+ return new SpecializableTransform2D(global, specializations);
+ } else {
+ return new SpecializableTransform(global, specializations);
+ }
+ }
+
+ /**
* Puts together a list of independent math transforms, each of them
operating on a subset of ordinate values.
* This method is often used for defining 4-dimensional
(<var>x</var>,<var>y</var>,<var>z</var>,<var>t</var>)
* transform as an aggregation of 3 simpler transforms operating on
(<var>x</var>,<var>y</var>), (<var>z</var>)
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java?rev=1825945&r1=1825944&r2=1825945&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform.java
[UTF-8] Mon Mar 5 22:13:04 2018
@@ -22,12 +22,13 @@ import java.util.Objects;
import java.io.Serializable;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.geometry.MismatchedReferenceSystemException;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.NoninvertibleTransformException;
-import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
import org.apache.sis.internal.referencing.DirectPositionView;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.geometry.GeneralEnvelope;
@@ -40,18 +41,26 @@ import org.apache.sis.util.ArraysExt;
/**
* A transform having sub-areas where more accurate transforms can be used.
- * The general transform must be a reasonable approximation of the specialized
transforms.
+ * The global transform must be a reasonable approximation of the specialized
transforms.
*
* @author Martin Desruisseaux (Geomatys)
* @version 1.0
- * @since 1.0
+ *
+ * @see MathTransforms#specialize(MathTransform, Map)
+ *
+ * @since 1.0
* @module
*/
class SpecializableTransform extends AbstractMathTransform implements
Serializable {
/**
- * The generic transform to use if there is no suitable specialization.
+ * For cross-version compatibility.
+ */
+ private static final long serialVersionUID = -7379277748632094312L;
+
+ /**
+ * The global transform to use if there is no suitable specialization.
*/
- private final MathTransform generic;
+ private final MathTransform global;
/**
* The region where a transform is valid, together with the transform.
@@ -118,7 +127,7 @@ class SpecializableTransform extends Abs
* Sets the CRS of all given ares to a common value. An exception is
thrown if incompatible CRS are found.
* This method does not verify the number of dimensions; this check
should have been done by the caller.
*/
- static void uniformize(final SubArea[] domains) throws
InvalidGeodeticParameterException {
+ static void uniformize(final SubArea[] domains) {
CoordinateReferenceSystem common = null;
for (SubArea area : domains) {
do {
@@ -126,7 +135,7 @@ class SpecializableTransform extends Abs
if (common == null) {
common = crs;
} else if (crs != null &&
!Utilities.equalsIgnoreMetadata(common, crs)) {
- throw new
InvalidGeodeticParameterException(Errors.format(Errors.Keys.MismatchedCRS));
+ throw new
MismatchedReferenceSystemException(Errors.format(Errors.Keys.MismatchedCRS));
}
} while ((area = area.specialization) != null);
}
@@ -242,17 +251,15 @@ class SpecializableTransform extends Abs
private MathTransform inverse;
/**
- * Creates a new transform with the given generic transform and some
amount of specializations.
+ * Creates a new transform with the given global transform and some amount
of specializations.
*
- * @param generic the generic transform to use if there is no suitable
specialization.
+ * @param global the transform to use globally where there is no
suitable specialization.
* @param specializations more accurate transforms available in
sub-areas.
*/
- SpecializableTransform(final MathTransform generic, final
Map<Envelope,MathTransform> specializations)
- throws InvalidGeodeticParameterException
- {
- this.generic = generic;
- final int sourceDim = generic.getSourceDimensions();
- final int targetDim = generic.getTargetDimensions();
+ SpecializableTransform(final MathTransform global, final
Map<Envelope,MathTransform> specializations) {
+ this.global = global;
+ final int sourceDim = global.getSourceDimensions();
+ final int targetDim = global.getTargetDimensions();
int n = 0;
final SubArea[] areas = new SubArea[specializations.size()];
next: for (final Map.Entry<Envelope,MathTransform> e :
specializations.entrySet()) {
@@ -261,7 +268,7 @@ next: for (final Map.Entry<Envelope,Ma
ensureDimensionMatches(1, targetDim, tr.getTargetDimensions());
final SubArea area = new SubArea(e.getKey(), tr);
if (area.getDimension() != sourceDim) {
- throw new
InvalidGeodeticParameterException(Errors.format(Errors.Keys.MismatchedDimension_3,
+ throw new
MismatchedDimensionException(Errors.format(Errors.Keys.MismatchedDimension_3,
"envelope", sourceDim, area.getDimension()));
}
for (int i=0; i<n; i++) {
@@ -272,7 +279,7 @@ next: for (final Map.Entry<Envelope,Ma
for (int i=0; i<n; i++) {
if (area.intersects(areas[n])) {
// Pending implementation of R-Tree in Apache SIS.
- throw new InvalidGeodeticParameterException("Current
implementation does not accept overlapping envelopes.");
+ throw new IllegalArgumentException("Current implementation
does not accept overlapping envelopes.");
}
}
areas[n++] = area;
@@ -286,11 +293,9 @@ next: for (final Map.Entry<Envelope,Ma
*
* @param type 0 if verifying source dimension, or 1 if verifying target
dimension.
*/
- private static void ensureDimensionMatches(final int type, final int
expected, final int actual)
- throws InvalidGeodeticParameterException
- {
+ private static void ensureDimensionMatches(final int type, final int
expected, final int actual) {
if (expected != actual) {
- throw new InvalidGeodeticParameterException(Resources.format(
+ throw new MismatchedDimensionException(Resources.format(
Resources.Keys.MismatchedTransformDimension_3, type,
expected, actual));
}
}
@@ -300,7 +305,7 @@ next: for (final Map.Entry<Envelope,Ma
*/
@Override
public final int getSourceDimensions() {
- return generic.getSourceDimensions();
+ return global.getSourceDimensions();
}
/**
@@ -308,14 +313,14 @@ next: for (final Map.Entry<Envelope,Ma
*/
@Override
public final int getTargetDimensions() {
- return generic.getTargetDimensions();
+ return global.getTargetDimensions();
}
/**
* Returns the transform to use for the given domain.
*/
private MathTransform forDomain(final SubArea domain) {
- return (domain != null) ? domain.transform : generic;
+ return (domain != null) ? domain.transform : global;
}
/**
@@ -345,13 +350,15 @@ next: for (final Map.Entry<Envelope,Ma
final double[] dstPts, final int dstOff,
boolean derivate) throws TransformException
{
- final DirectPositionView pos = new DirectPositionView.Double(srcPts,
srcOff, generic.getSourceDimensions());
+ final DirectPositionView pos = new DirectPositionView.Double(srcPts,
srcOff, global.getSourceDimensions());
final MathTransform tr = forDomain(SubArea.find(domains, pos));
if (tr instanceof AbstractMathTransform) {
return ((AbstractMathTransform) tr).transform(srcPts, srcOff,
dstPts, dstOff, derivate);
} else {
Matrix derivative = derivate ? tr.derivative(pos) : null; //
Must be before transform(srcPts, …).
- tr.transform(srcPts, srcOff, dstPts, dstOff, 1);
+ if (dstPts != null) {
+ tr.transform(srcPts, srcOff, dstPts, dstOff, 1);
+ }
return derivative;
}
}
@@ -387,7 +394,7 @@ next: for (final Map.Entry<Envelope,Ma
int srcOff = src.offset;
final MathTransform tr;
if (domain == null) {
- tr = generic; // The transform
to apply when no specialization is found.
+ tr = global; // The transform to
apply when no specialization is found.
do { // Count how many
points will use that transform.
src.offset += srcInc;
if (--numPts <= 0) break;
@@ -520,7 +527,7 @@ next: for (final Map.Entry<Envelope,Ma
*/
@Override
protected final int computeHashCode() {
- return super.computeHashCode() + 7*generic.hashCode() ^
Arrays.hashCode(domains);
+ return super.computeHashCode() + 7*global.hashCode() ^
Arrays.hashCode(domains);
}
/**
@@ -530,7 +537,7 @@ next: for (final Map.Entry<Envelope,Ma
public final boolean equals(final Object object, final ComparisonMode
mode) {
if (super.equals(object, mode)) {
final SpecializableTransform other = (SpecializableTransform)
object;
- return Utilities.deepEquals(generic, other.generic, mode) &&
+ return Utilities.deepEquals(global, other.global, mode) &&
Utilities.deepEquals(domains, other.domains, mode);
}
return false;
@@ -548,7 +555,7 @@ next: for (final Map.Entry<Envelope,Ma
@Override
protected final String formatTo(final Formatter formatter) {
formatter.newLine();
- formatter.append(generic);
+ formatter.append(global);
for (SubArea domain : domains) {
SubArea.format(domain, formatter);
}
@@ -560,17 +567,25 @@ next: for (final Map.Entry<Envelope,Ma
* Returns the inverse of this transform.
*/
@Override
- public final synchronized MathTransform inverse() throws
NoninvertibleTransformException {
+ public synchronized MathTransform inverse() throws
NoninvertibleTransformException {
if (inverse == null) {
- inverse = new Inverse(this);
+ inverse = createInverse();
}
return inverse;
}
/**
+ * Invoked at construction time for creating the inverse transform.
+ * Overridden by {@link SpecializableTransform2D} for the two-dimensional
variant.
+ */
+ Inverse createInverse() throws NoninvertibleTransformException {
+ return new Inverse(this);
+ }
+
+ /**
* The inverse of {@link SpecializableTransform}.
*/
- private static final class Inverse extends AbstractMathTransform.Inverse
implements Serializable {
+ static class Inverse extends AbstractMathTransform.Inverse implements
Serializable {
/**
* For cross-version compatibility.
*/
@@ -582,16 +597,16 @@ next: for (final Map.Entry<Envelope,Ma
private final SpecializableTransform forward;
/**
- * The inverse of {@link SpecializableTransform#generic}.
+ * The inverse of {@link SpecializableTransform#global}.
*/
- private final MathTransform generic;
+ private final MathTransform global;
/**
* Creates the inverse of a specialized transform having the given
properties.
*/
Inverse(final SpecializableTransform forward) throws
NoninvertibleTransformException {
this.forward = forward;
- this.generic = forward.generic.inverse();
+ this.global = forward.global.inverse();
for (final SubArea domain : forward.domains) {
SubArea.createInverse(domain);
}
@@ -611,7 +626,7 @@ next: for (final Map.Entry<Envelope,Ma
@Override
public final DirectPosition transform(final DirectPosition ptSrc,
DirectPosition ptDst) throws TransformException {
final double[] source = ptSrc.getCoordinate(); // Needs to be
first in case ptDst overwrites ptSrc.
- ptDst = generic.transform(ptSrc, ptDst);
+ ptDst = global.transform(ptSrc, ptDst);
final SubArea domain = SubArea.find(forward.domains, ptDst);
if (domain != null) {
ptDst = domain.inverse.transform(new
DirectPositionView.Double(source, 0, source.length), ptDst);
@@ -636,8 +651,8 @@ next: for (final Map.Entry<Envelope,Ma
public final Matrix transform(double[] srcPts, int srcOff, double[]
dstPts, int dstOff, final boolean derivate)
throws TransformException
{
- final int srcInc = generic.getSourceDimensions();
- final int dstInc = generic.getTargetDimensions();
+ final int srcInc = global.getSourceDimensions();
+ final int dstInc = global.getTargetDimensions();
if (dstPts == null) {
dstPts = new double[dstInc]; // Needed for
checking if inside a sub-area.
dstOff = 0;
@@ -650,7 +665,7 @@ next: for (final Map.Entry<Envelope,Ma
* given in arguments overlap. We need this stability because the
source coordinates may be used
* twice, if 'secondTry' become true.
*/
- MathTransform tr = generic;
+ MathTransform tr = global;
boolean secondTry = false;
Matrix derivative;
do {
@@ -679,7 +694,7 @@ next: for (final Map.Entry<Envelope,Ma
int srcOff, int dstOff, int srcInc, int dstInc, int numPts)
throws TransformException
{
final SubArea[] domains = forward.domains;
- transform.apply(generic, srcOff, dstOff, numPts);
+ transform.apply(global, srcOff, dstOff, numPts);
final DirectPositionView dst = new
DirectPositionView.Double(dstPts, dstOff, dstInc);
while (numPts > 0) {
SubArea domain = SubArea.find(domains, dst);
@@ -718,8 +733,8 @@ next: for (final Map.Entry<Envelope,Ma
throws TransformException
{
if (numPts <= 0) return;
- final int srcInc = generic.getSourceDimensions();
- final int dstInc = generic.getTargetDimensions();
+ final int srcInc = global.getSourceDimensions();
+ final int dstInc = global.getTargetDimensions();
if (srcPts == dstPts) {
final int srcEnd = srcOff + numPts*srcInc;
if (srcEnd > dstOff || dstOff + numPts*dstInc > srcOff) {
@@ -742,8 +757,8 @@ next: for (final Map.Entry<Envelope,Ma
throws TransformException
{
if (numPts <= 0) return;
- final int srcInc = generic.getSourceDimensions();
- final int dstInc = generic.getTargetDimensions();
+ final int srcInc = global.getSourceDimensions();
+ final int dstInc = global.getTargetDimensions();
final double[] buffer = new double[numPts * dstInc];
transform((tr, src, dst, num) -> tr.transform(srcPts, src, buffer,
dst, num),
buffer, srcOff, 0, srcInc, dstInc, numPts);
@@ -763,8 +778,8 @@ next: for (final Map.Entry<Envelope,Ma
final float [] dstPts, int dstOff, int numPts)
throws TransformException
{
if (numPts <= 0) return;
- final int srcInc = generic.getSourceDimensions();
- final int dstInc = generic.getTargetDimensions();
+ final int srcInc = global.getSourceDimensions();
+ final int dstInc = global.getTargetDimensions();
final double[] buffer = new double[numPts * dstInc];
transform((tr, src, dst, num) -> tr.transform(srcPts, src, buffer,
dst, num),
buffer, srcOff, 0, srcInc, dstInc, numPts);
@@ -784,8 +799,8 @@ next: for (final Map.Entry<Envelope,Ma
final double[] dstPts, int dstOff, int numPts)
throws TransformException
{
if (numPts <= 0) return;
- final int srcInc = generic.getSourceDimensions();
- final int dstInc = generic.getTargetDimensions();
+ final int srcInc = global.getSourceDimensions();
+ final int dstInc = global.getTargetDimensions();
transform((tr, src, dst, num) -> tr.transform(srcPts, src, dstPts,
dst, num),
dstPts, srcOff, dstOff, srcInc, dstInc, numPts);
}
Added:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform1D.txt
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform1D.txt?rev=1825945&view=auto
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform1D.txt
(added)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform1D.txt
[UTF-8] Mon Mar 5 22:13:04 2018
@@ -0,0 +1,3 @@
+There is no SpecializableTransform1D implementation yet because
+a more specific implementation will be needed for grid Coverage.
+It may look like the SampleDimension class in Geotk.
Propchange:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform1D.txt
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform1D.txt
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform2D.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform2D.java?rev=1825945&view=auto
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform2D.java
(added)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform2D.java
[UTF-8] Mon Mar 5 22:13:04 2018
@@ -0,0 +1,139 @@
+/*
+ * 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.referencing.operation.transform;
+
+import java.util.Map;
+import java.awt.Shape;
+import java.awt.geom.Point2D;
+import org.opengis.geometry.Envelope;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+
+
+/**
+ * A specializable transform in the two-dimensional case.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @version 1.0
+ * @since 1.0
+ * @module
+ */
+final class SpecializableTransform2D extends SpecializableTransform implements
MathTransform2D {
+ /**
+ * Serial number for inter-operability with different versions.
+ */
+ private static final long serialVersionUID = 2924682501896480813L;
+
+ /**
+ * Creates a new transform.
+ */
+ SpecializableTransform2D(MathTransform global, Map<Envelope,MathTransform>
specializations) {
+ super(global, specializations);
+ }
+
+ /**
+ * Transforms the specified {@code ptSrc} and stores the result in {@code
ptDst}.
+ */
+ @Override
+ public Point2D transform(final Point2D ptSrc, final Point2D ptDst) throws
TransformException {
+ return AbstractMathTransform2D.transform(this, ptSrc, ptDst);
+ }
+
+ /**
+ * Transforms the specified shape.
+ */
+ @Override
+ public Shape createTransformedShape(final Shape shape) throws
TransformException {
+ return AbstractMathTransform2D.createTransformedShape(this, shape,
null, null, false);
+ }
+
+ /**
+ * Gets the derivative of this transform at a point.
+ */
+ @Override
+ public Matrix derivative(final Point2D point) throws TransformException {
+ return AbstractMathTransform2D.derivative(this, point);
+ }
+
+ /**
+ * Returns the inverse transform of this object.
+ */
+ @Override
+ public MathTransform2D inverse() throws NoninvertibleTransformException {
+ return (MathTransform2D) super.inverse();
+ }
+
+ /**
+ * Invoked at construction time for creating the two-dimensional inverse
transform.
+ */
+ @Override
+ Inverse createInverse() throws NoninvertibleTransformException {
+ return new Inverse(this);
+ }
+
+ /**
+ * The inverse of {@link SpecializableTransform2D}.
+ */
+ static final class Inverse extends SpecializableTransform.Inverse
implements MathTransform2D {
+ /**
+ * Serial number for inter-operability with different versions.
+ */
+ private static final long serialVersionUID = 366420739633368389L;
+
+ /**
+ * Creates a new inverse transform.
+ */
+ Inverse(SpecializableTransform2D forward) throws
NoninvertibleTransformException {
+ super(forward);
+ }
+
+ /**
+ * Transforms the specified {@code ptSrc} and stores the result in
{@code ptDst}.
+ */
+ @Override
+ public Point2D transform(final Point2D ptSrc, final Point2D ptDst)
throws TransformException {
+ return AbstractMathTransform2D.transform(this, ptSrc, ptDst);
+ }
+
+ /**
+ * Transforms the specified shape.
+ */
+ @Override
+ public Shape createTransformedShape(final Shape shape) throws
TransformException {
+ return AbstractMathTransform2D.createTransformedShape(this, shape,
null, null, false);
+ }
+
+ /**
+ * Gets the derivative of this transform at a point.
+ */
+ @Override
+ public Matrix derivative(final Point2D point) throws
TransformException {
+ return AbstractMathTransform2D.derivative(this, point);
+ }
+
+ /**
+ * Returns the inverse transform of this object.
+ */
+ @Override
+ public MathTransform2D inverse() {
+ return (MathTransform2D) super.inverse();
+ }
+ }
+}
Propchange:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform2D.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/SpecializableTransform2D.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java?rev=1825945&r1=1825944&r2=1825945&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/SpecializableTransformTest.java
[UTF-8] Mon Mar 5 22:13:04 2018
@@ -21,9 +21,9 @@ import java.util.HashMap;
import org.opengis.geometry.Envelope;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
-import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
import org.apache.sis.internal.referencing.j2d.AffineTransform2D;
import org.apache.sis.geometry.Envelope2D;
+import org.apache.sis.test.DependsOnMethod;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -49,13 +49,17 @@ public final strictfp class Specializabl
/**
* Creates a transform to test.
*
- * @throws InvalidGeodeticParameterException if {@link
SpecializableTransform} constructor reject a parameter.
+ * @throws IllegalArgumentException if {@link SpecializableTransform}
constructor rejects a parameter.
*/
- private static SpecializableTransform create() throws
InvalidGeodeticParameterException {
+ private static SpecializableTransform create(final boolean is2D) {
final Map<Envelope,MathTransform> specializations = new HashMap<>(4);
assertNull(specializations.put(new Envelope2D(null, -5, -4, 10, 7),
translation(0.1)));
assertNull(specializations.put(new Envelope2D(null, -3, -1, 5, 2),
translation(0.2)));
- return new SpecializableTransform(translation(0), specializations);
+ final MathTransform global = translation(0);
+ if (is2D) {
+ return new SpecializableTransform2D(global, specializations);
+ }
+ return new SpecializableTransform(global, specializations);
}
/**
@@ -76,17 +80,36 @@ public final strictfp class Specializabl
* situations where two transforms could calculate the same point (because
of the way we created
* our test transform).
*
- * @throws InvalidGeodeticParameterException if {@link
SpecializableTransform} constructor reject a parameter.
+ * @throws IllegalArgumentException if {@link SpecializableTransform}
constructor rejects a parameter.
+ * @throws TransformException if a transformation failed.
+ */
+ @Test
+ public void testTransform() throws TransformException {
+ verifyNonAmbiguousPoints(false);
+ }
+
+ /**
+ * Verifies the transformation using two-dimensional variant.
+ *
+ * @throws IllegalArgumentException if {@link SpecializableTransform}
constructor rejects a parameter.
* @throws TransformException if a transformation failed.
*/
@Test
- public void testTransform() throws InvalidGeodeticParameterException,
TransformException {
- // ┌─── generic ───┐┌───── Special. 1
──────┐┌──── Special. 2 ─────┐
- final double[] source = {8, 2, 4, 5, 3, 2, 2, -2, -2,
0, 1, 0, 8, 3};
- final double[] target = {80, 20, 40, 50, 30.1, 20.1, 20.1, -19.9,
-19.8, 0.2, 10.2, 0.2, 80, 30};
+ @DependsOnMethod("testTransform")
+ public void testTransform2D() throws TransformException {
+ verifyNonAmbiguousPoints(true);
+ }
+
+ /**
+ * Implementation of {@link #testTransform()} and {@link
#testTransform2D()}.
+ */
+ private void verifyNonAmbiguousPoints(final boolean is2D) throws
TransformException {
+ // ┌─── global ───┐┌───── Special. 1 ──────┐┌────
Special. 2 ─────┐
+ final double[] source = {8, 2, 4, 5, 3, 2, 2, -2, -2,
0, 1, 0, 8, 3};
+ final double[] target = {80, 20, 40, 50, 30.1, 20.1, 20.1, -19.9,
-19.8, 0.2, 10.2, 0.2, 80, 30};
tolerance = 1E-14;
- transform = create();
+ transform = create(is2D);
verifyTransform(source, target);
verifyDerivatives(source);
@@ -103,12 +126,12 @@ public final strictfp class Specializabl
* some target coordinates can be created from more than one source
coordinates. We need to be
* "lucky" enough for not testing a point in this case, otherwise the
result is undetermined.
*
- * @throws InvalidGeodeticParameterException if {@link
SpecializableTransform} constructor reject a parameter.
+ * @throws IllegalArgumentException if {@link SpecializableTransform}
constructor rejects a parameter.
* @throws TransformException if a transformation failed.
*/
@Test
- public void testForwardConsistency() throws
InvalidGeodeticParameterException, TransformException {
- transform = create();
+ public void testForwardConsistency() throws TransformException {
+ transform = create(false);
tolerance = 1E-14;
isDerivativeSupported = false; // Actually supported, but our
test transform has discontinuities.
verifyInDomain(CoordinateDomain.RANGE_10, -672445632505596619L);
@@ -120,12 +143,12 @@ public final strictfp class Specializabl
* used in this test is {@linkplain
org.apache.sis.math.FunctionProperty#SURJECTIVE surjective}.
* See {@link #testForwardConsistency()}.
*
- * @throws InvalidGeodeticParameterException if {@link
SpecializableTransform} constructor reject a parameter.
+ * @throws IllegalArgumentException if {@link SpecializableTransform}
constructor rejects a parameter.
* @throws TransformException if a transformation failed.
*/
@Test
- public void testInverseConsistency() throws
InvalidGeodeticParameterException, TransformException {
- transform = create().inverse();
+ public void testInverseConsistency() throws TransformException {
+ transform = create(false).inverse();
tolerance = 1E-12;
isDerivativeSupported = false; // Actually supported, but our
test transform has discontinuities.
verifyInDomain(CoordinateDomain.RANGE_100, 4308397764777385180L);
@@ -135,11 +158,11 @@ public final strictfp class Specializabl
* Tests the pseudo Well-Known Text formatting.
* The format used by this transform is non-standard and may change in any
future Apache SIS version.
*
- * @throws InvalidGeodeticParameterException if {@link
SpecializableTransform} constructor reject a parameter.
+ * @throws IllegalArgumentException if {@link SpecializableTransform}
constructor rejects a parameter.
*/
@Test
- public void testWKT() throws InvalidGeodeticParameterException {
- transform = create();
+ public void testWKT() {
+ transform = create(false);
assertWktEquals(
"SPECIALIZABLE_MT[\n" +
" PARAM_MT[“Affine”,\n" +