Author: desruisseaux
Date: Wed Apr 6 14:39:32 2016
New Revision: 1737990
URL: http://svn.apache.org/viewvc?rev=1737990&view=rev
Log:
Fix operation between CompoundCRS having a ProjectedCRS, and add corresponding
test.
Added:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubOperationInfo.java
- copied, changed from r1737989,
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SourceComponent.java
Removed:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SourceComponent.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java?rev=1737990&r1=1737989&r2=1737990&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
[UTF-8] Wed Apr 6 14:39:32 2016
@@ -314,7 +314,8 @@ public class CoordinateOperationInferenc
////
////
////////////////////////////////////////////////////////////////////////////////
if (sourceCRS instanceof CompoundCRS || targetCRS instanceof
CompoundCRS) {
- return decompose(sourceCRS, targetCRS);
+ return createOperationStep(sourceCRS,
CRS.getSingleComponents(sourceCRS),
+ targetCRS,
CRS.getSingleComponents(targetCRS));
}
throw new OperationNotFoundException(notFoundMessage(sourceCRS,
targetCRS));
}
@@ -732,19 +733,20 @@ public class CoordinateOperationInferenc
* various combinations of source and target components. A preference is
given for components of the same
* type (e.g. source {@link GeodeticCRS} with target {@code GeodeticCRS},
<i>etc.</i>).
*
- * @param sourceCRS input coordinate reference system.
- * @param targetCRS output coordinate reference system.
+ * @param sourceCRS input coordinate reference system.
+ * @param sourceComponents components of the source CRS.
+ * @param targetCRS output coordinate reference system.
+ * @param targetComponents components of the target CRS.
* @return a coordinate operation from {@code sourceCRS} to {@code
targetCRS}.
* @throws FactoryException if the operation can not be constructed.
*/
- private CoordinateOperation decompose(final CoordinateReferenceSystem
sourceCRS,
- final CoordinateReferenceSystem
targetCRS)
+ protected CoordinateOperation createOperationStep(
+ final CoordinateReferenceSystem sourceCRS, final List<? extends
SingleCRS> sourceComponents,
+ final CoordinateReferenceSystem targetCRS, final List<? extends
SingleCRS> targetComponents)
throws FactoryException
{
- final List<SingleCRS> sources = CRS.getSingleComponents(sourceCRS);
- final List<SingleCRS> targets = CRS.getSingleComponents(targetCRS);
- final SourceComponent[] infos = new SourceComponent[targets.size()];
- final boolean[] sourceIsUsed = new boolean[sources.size()];
+ final SubOperationInfo[] infos = new
SubOperationInfo[targetComponents.size()];
+ final boolean[] sourceIsUsed = new boolean[sourceComponents.size()];
final CoordinateReferenceSystem[] stepComponents = new
CoordinateReferenceSystem[infos.length];
/*
* Operations found are stored in 'infos', but are not yet wrapped in
PassThroughOperations.
@@ -752,7 +754,7 @@ public class CoordinateOperationInferenc
* order. We also need to know if any source ordinates should be
dropped.
*/
for (int i=0; i<infos.length; i++) {
- if ((infos[i] = SourceComponent.create(this, sourceIsUsed,
sources, targets.get(i))) == null) {
+ if ((infos[i] = SubOperationInfo.create(this, sourceIsUsed,
sourceComponents, targetComponents.get(i))) == null) {
throw new
OperationNotFoundException(notFoundMessage(sourceCRS, targetCRS));
}
stepComponents[i] = infos[i].operation.getSourceCRS();
@@ -765,10 +767,10 @@ public class CoordinateOperationInferenc
* operations that we just found.
*/
int remainingSourceDimensions = 0;
- for (final SourceComponent component : infos) {
+ for (final SubOperationInfo component : infos) {
remainingSourceDimensions += component.endAtDimension -
component.startAtDimension;
}
- final Matrix select = SourceComponent.sourceToSelected(
+ final Matrix select = SubOperationInfo.sourceToSelected(
sourceCRS.getCoordinateSystem().getDimension(),
remainingSourceDimensions, infos);
/*
* First, we need a CRS matching the above-cited rearrangement. That
CRS will be named 'stepSourceCRS'
@@ -793,13 +795,13 @@ public class CoordinateOperationInferenc
* For each sub-operation, create a PassThroughOperation for the
(stepSourceCRS → stepTargetCRS) operation.
* Each source CRS inside this loop will be for dimensions at indices
[startAtDimension … endAtDimension-1].
* Note that those indices are not necessarily the same than the
indices in the fields of the same name in
- * SourceComponent, because those indices are not relative to the same
CompoundCRS.
+ * SubOperationInfo, because those indices are not relative to the
same CompoundCRS.
*/
int endAtDimension = 0;
- final int startOfIdentity = SourceComponent.startOfIdentity(infos);
+ final int startOfIdentity = SubOperationInfo.startOfIdentity(infos);
for (int i=0; i<stepComponents.length; i++) {
final CoordinateReferenceSystem source = stepComponents[i];
- final CoordinateReferenceSystem target = targets.get(i);
+ final CoordinateReferenceSystem target = targetComponents.get(i);
CoordinateOperation subOperation = infos[i].operation;
final MathTransform subTransform = subOperation.getMathTransform();
/*
Copied:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubOperationInfo.java
(from r1737989,
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SourceComponent.java)
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubOperationInfo.java?p2=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubOperationInfo.java&p1=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SourceComponent.java&r1=1737989&r2=1737990&rev=1737990&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SourceComponent.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SubOperationInfo.java
[UTF-8] Wed Apr 6 14:39:32 2016
@@ -36,7 +36,7 @@ import org.apache.sis.referencing.operat
* @version 0.7
* @module
*/
-final class SourceComponent {
+final class SubOperationInfo {
/**
* Types of target CRS, together with the type of CRS that may be used as
the source for that target.
* For each array {@code COMPATIBLE_TYPES[i]}, the first element (i.e.
{@code COMPATIBLE_TYPES[i][0]})
@@ -88,7 +88,7 @@ final class SourceComponent {
/**
* Creates a new instance containing the given information.
*/
- private SourceComponent(final CoordinateOperation operation, final int
startAtDimension, final int endAtDimension) {
+ private SubOperationInfo(final CoordinateOperation operation, final int
startAtDimension, final int endAtDimension) {
this.operation = operation;
this.startAtDimension = startAtDimension;
this.endAtDimension = endAtDimension;
@@ -105,8 +105,8 @@ final class SourceComponent {
* @return information about a coordinate operation from a source CRS to
the given target CRS, or {@code null}.
* @throws FactoryException if an error occurred while grabbing a
coordinate operation.
*/
- static SourceComponent create(final CoordinateOperationInference caller,
final boolean[] sourceIsUsed,
- final List<SingleCRS> sources, final SingleCRS target) throws
FactoryException
+ static SubOperationInfo create(final CoordinateOperationInference caller,
final boolean[] sourceIsUsed,
+ final List<? extends SingleCRS> sources, final SingleCRS target)
throws FactoryException
{
OperationNotFoundException failure = null;
final Class<?> targetType = type(target);
@@ -119,7 +119,7 @@ final class SourceComponent {
final SingleCRS source = sources.get(i);
startAtDimension = endAtDimension;
endAtDimension +=
source.getCoordinateSystem().getDimension();
- if (!sourceIsUsed[i] && sourceType.isInstance(source))
{
+ if (!sourceIsUsed[i] &&
sourceType.isAssignableFrom(type(source))) {
final CoordinateOperation operation;
try {
operation = caller.createOperation(source,
target);
@@ -151,7 +151,7 @@ final class SourceComponent {
Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
CoordinateOperationInference.class,
"decompose", failure);
}
- return new SourceComponent(operation,
startAtDimension, endAtDimension);
+ return new SubOperationInfo(operation,
startAtDimension, endAtDimension);
}
}
}
@@ -166,7 +166,7 @@ final class SourceComponent {
/**
* Returns the dimension from which all remaining operations are identity.
*/
- static int startOfIdentity(final SourceComponent[] selected) {
+ static int startOfIdentity(final SubOperationInfo[] selected) {
int n = selected.length;
while (n != 0) {
if (!selected[--n].operation.getMathTransform().isIdentity()) {
@@ -184,11 +184,11 @@ final class SourceComponent {
* @param selectedDimensions number of source dimensions needed by the
coordinate operations.
* @param selected all {@code SourceComponent} instances needed for the
target {@code CompoundCRS}.
*/
- static Matrix sourceToSelected(final int sourceDimensions, final int
selectedDimensions, final SourceComponent[] selected) {
+ static Matrix sourceToSelected(final int sourceDimensions, final int
selectedDimensions, final SubOperationInfo[] selected) {
final Matrix select = Matrices.createZero(selectedDimensions + 1,
sourceDimensions + 1);
select.setElement(selectedDimensions, sourceDimensions, 1);
int j = 0;
- for (final SourceComponent component : selected) {
+ for (final SubOperationInfo component : selected) {
for (int i=component.startAtDimension; i<component.endAtDimension;
i++) {
select.setElement(j++, i, 1);
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java?rev=1737990&r1=1737989&r2=1737990&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationInferenceTest.java
[UTF-8] Wed Apr 6 14:39:32 2016
@@ -21,7 +21,6 @@ import java.util.Collections;
import java.text.ParseException;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.referencing.crs.SingleCRS;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.crs.GeocentricCRS;
import org.opengis.referencing.crs.VerticalCRS;
@@ -621,12 +620,62 @@ public final strictfp class CoordinateOp
/**
* Convenience method for creating a compound CRS.
*/
- private static CompoundCRS compound(final String name, final SingleCRS...
components) {
+ private static CompoundCRS compound(final String name, final
CoordinateReferenceSystem... components) {
return new
DefaultCompoundCRS(Collections.singletonMap(CompoundCRS.NAME_KEY, name),
components);
}
/**
- * Tests transformation from three-dimensional geographic CRS to
four-dimensional compound CRS
+ * Tests conversion from four-dimensional compound CRS to two-dimensional
projected CRS.
+ *
+ * @throws ParseException if a CRS used in this test can not be parsed.
+ * @throws FactoryException if the operation can not be created.
+ * @throws TransformException if an error occurred while converting the
test points.
+ */
+ @Test
+ @DependsOnMethod("testTemporalConversion")
+ public void testProjected4D_to_2D() throws ParseException,
FactoryException, TransformException {
+ final CoordinateReferenceSystem targetCRS = parse(
+ "ProjectedCRS[“WGS 84 / World Mercator”,\n" +
+ " BaseGeodCRS[“WGS 84”,\n" +
+ " Datum[“World Geodetic System 1984”,\n" +
+ " Ellipsoid[“WGS 84”, 6378137.0, 298.257223563]]],\n" +
+ " Conversion[“WGS 84 / World Mercator”,\n" +
+ " Method[“Mercator (1SP)”]],\n" +
+ " CS[Cartesian, 2],\n" +
+ " Axis[“Easting”, EAST],\n" +
+ " Axis[“Northing”, NORTH],\n" +
+ " Unit[“m”, 1],\n" +
+ " Id[“EPSG”, “3395”]]");
+
+ CoordinateReferenceSystem sourceCRS = targetCRS;
+ sourceCRS = compound("Mercator 3D", sourceCRS,
CommonCRS.Vertical.ELLIPSOIDAL.crs());
+ sourceCRS = compound("Mercator 4D", sourceCRS,
CommonCRS.Temporal.MODIFIED_JULIAN.crs());
+
+ final CoordinateOperation operation =
factory.createOperation(sourceCRS, targetCRS);
+ assertSame("sourceCRS", sourceCRS, operation.getSourceCRS());
+ assertSame("targetCRS", targetCRS, operation.getTargetCRS());
+
+ transform = operation.getMathTransform();
+ assertFalse("transform.isIdentity", transform.isIdentity());
+ assertInstanceOf("The somewhat complex MathTransform chain should have
been simplified " +
+ "to a single affine transform.",
LinearTransform.class, transform);
+ assertInstanceOf("The operation should be a simple axis change, not a
complex" +
+ "chain of ConcatenatedOperations.", Conversion.class,
operation);
+
+ tolerance = 1E-12;
+ isInverseTransformSupported = false;
+ verifyTransform(new double[] {
+ 0, 0, 0, 0,
+ 1000, -2000, 20, 4000
+ }, new double[] {
+ 0, 0,
+ 1000, -2000
+ });
+ validate();
+ }
+
+ /**
+ * Tests conversion from three-dimensional geographic CRS to
four-dimensional compound CRS
* where the last dimension is time.
*
* @throws FactoryException if the operation can not be created.