sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1737980 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/ test/java/org/apache/sis/referencing/operation/
Date Wed, 06 Apr 2016 13:15:00 GMT
Author: desruisseaux
Date: Wed Apr  6 13:15:00 2016
New Revision: 1737980

URL: http://svn.apache.org/viewvc?rev=1737980&view=rev
Log:
Complete support of coordinate operation between CompoundCRS and enable the test. 

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/SourceComponent.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=1737980&r1=1737979&r2=1737980&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 13:15:00 2016
@@ -745,6 +745,7 @@ public class CoordinateOperationInferenc
         final List<SingleCRS> targets = CRS.getSingleComponents(targetCRS);
         final SourceComponent[] infos = new SourceComponent[targets.size()];
         final boolean[]  sourceIsUsed = new boolean[sources.size()];
+        final CoordinateReferenceSystem[] stepComponents = new CoordinateReferenceSystem[infos.length];
         /*
          * Operations found are stored in 'infos', but are not yet wrapped in PassThroughOperations.
          * We need to know first if some ordinate values need reordering for matching the
target CRS
@@ -754,13 +755,109 @@ public class CoordinateOperationInferenc
             if ((infos[i] = SourceComponent.create(this, sourceIsUsed, sources, targets.get(i)))
== null) {
                 throw new OperationNotFoundException(notFoundMessage(sourceCRS, targetCRS));
             }
+            stepComponents[i] = infos[i].operation.getSourceCRS();
         }
         /*
-         * A coordinate operation has been found for every target component CRS.
-         * Some reordering of ordinate values may be needed, and some coordinates may need
to be dropped.
+         * At this point, a coordinate operation has been found for all components of the
target CRS.
+         * However the CoordinateOperation.getSourceCRS() values are not necessarily in the
same order
+         * than the components of the source CRS given to this method, and some dimensions
may be dropped.
+         * The matrix computed by sourceToSelected(…) gives us the rearrangement needed
for the coordinate
+         * operations that we just found.
          */
-        final Matrix select = SourceComponent.sourceToSelected(sourceCRS.getCoordinateSystem().getDimension(),
infos);
-        throw new UnsupportedOperationException();      // TODO continue work from here.
+        int remainingSourceDimensions = 0;
+        for (final SourceComponent component : infos) {
+            remainingSourceDimensions += component.endAtDimension - component.startAtDimension;
+        }
+        final Matrix select = SourceComponent.sourceToSelected(
+                sourceCRS.getCoordinateSystem().getDimension(), remainingSourceDimensions,
infos);
+        /*
+         * First, we need a CRS matching the above-cited rearrangement. That CRS will be
named 'stepSourceCRS'
+         * and its components will be named 'stepComponents'. Then we will execute a loop
in which each component
+         * is progressively (one by one) updated from a source component to a target component.
A new step CRS is
+         * recreated each time, since it will be needed for each PassThroughOperation.
+         */
+        CoordinateReferenceSystem stepSourceCRS;
+        CoordinateOperation operation;
+        if (select.isIdentity()) {
+            stepSourceCRS = sourceCRS;                // No rearrangement - we can use source
CRS as-is.
+            operation = null;
+        } else {
+            if (stepComponents.length == 1) {
+                stepSourceCRS = stepComponents[0];    // Slight optimization of the next
block (in the 'else' case).
+            } else {
+                stepSourceCRS = factorySIS.getCRSFactory().createCompoundCRS(derivedFrom(sourceCRS),
stepComponents);
+            }
+            operation = createFromAffineTransform(AXIS_CHANGES, sourceCRS, stepSourceCRS,
select);
+        }
+        /*
+         * 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.
+         */
+        int endAtDimension = 0;
+        final int startOfIdentity = SourceComponent.startOfIdentity(infos);
+        for (int i=0; i<stepComponents.length; i++) {
+            final CoordinateReferenceSystem source = stepComponents[i];
+            final CoordinateReferenceSystem target = targets.get(i);
+            CoordinateOperation subOperation = infos[i].operation;
+            final MathTransform subTransform = subOperation.getMathTransform();
+            /*
+             * In order to compute 'stepTargetCRS', replace in-place a single element in
'stepComponents'.
+             * For each step except the last one, 'stepTargetCRS' is a mix of target and
source CRS. Only
+             * after the loop finished, 'stepTargetCRS' will become the complete targetCRS
definition.
+             */
+            final CoordinateReferenceSystem stepTargetCRS;
+            stepComponents[i] = target;
+            if (i >= startOfIdentity) {
+                stepTargetCRS = targetCRS;              // If all remaining transforms are
identity, we reached the final CRS.
+            } else if (subTransform.isIdentity()) {
+                stepTargetCRS = stepSourceCRS;          // In any identity transform, the
source and target CRS are equal.
+            } else if (stepComponents.length == 1) {
+                stepTargetCRS = target;                 // Slight optimization of the next
block.
+            } else {
+                stepTargetCRS = ReferencingServices.getInstance().createCompoundCRS(
+                        factorySIS.getCRSFactory(), factorySIS.getCSFactory(), derivedFrom(target),
stepComponents);
+            }
+            int delta = source.getCoordinateSystem().getDimension();
+            final int startAtDimension = endAtDimension;
+            endAtDimension += delta;
+            /*
+             * Constructs the pass through transform only if there is at least one ordinate
to pass.
+             * Actually the code below would work inconditionally, but we perform this check
anyway
+             * for avoiding the creation of intermediate objects.
+             */
+            if (!(startAtDimension == 0 && endAtDimension == remainingSourceDimensions))
{
+                final Map<String,?> properties = IdentifiedObjects.getProperties(subOperation);
+                /*
+                 * The DefaultPassThroughOperation constuctor expect a SingleOperation.
+                 * In most case, the 'subOperation' is already of this kind. However if
+                 * it is not, try to copy it in such object.
+                 */
+                final SingleOperation op;
+                if (subOperation instanceof SingleOperation) {
+                    op = (SingleOperation) subOperation;
+                } else {
+                    op = factorySIS.createSingleOperation(properties,
+                            subOperation.getSourceCRS(), subOperation.getTargetCRS(), null,
+                            new DefaultOperationMethod(subTransform), subTransform);
+                }
+                subOperation = new DefaultPassThroughOperation(properties, stepSourceCRS,
stepTargetCRS,
+                        op, startAtDimension, remainingSourceDimensions - endAtDimension);
+            }
+            /*
+             * Concatenate the operation with the ones we have found so far, and use the
current 'stepTargetCRS'
+             * as the source CRS for the next operation step. We also need to adjust the
dimension indices,
+             * since the previous operations may have removed some dimensions. Note that
the delta may also
+             * be negative in a few occasions.
+             */
+            operation = concatenate(operation, subOperation);
+            stepSourceCRS = stepTargetCRS;
+            delta -= target.getCoordinateSystem().getDimension();
+            endAtDimension -= delta;
+            remainingSourceDimensions -= delta;
+        }
+        return operation;
     }
 
 

Modified: 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/SourceComponent.java?rev=1737980&r1=1737979&r2=1737980&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/SourceComponent.java
[UTF-8] Wed Apr  6 13:15:00 2016
@@ -78,12 +78,12 @@ final class SourceComponent {
     /**
      * Returns the first dimension (inclusive) where the source component CRS begins in the
source compound CRS.
      */
-    private final int startAtDimension;
+    final int startAtDimension;
 
     /**
      * Returns the last dimension (exclusive) where the source component CRS ends in the
source compound CRS.
      */
-    private final int endAtDimension;
+    final int endAtDimension;
 
     /**
      * Creates a new instance containing the given information.
@@ -132,7 +132,7 @@ final class SourceComponent {
                                 continue;
                             }
                             /*
-                             * Found an operation. Remove the source component from the list
because each source
+                             * Found an operation.  Exclude the source component from the
list because each source
                              * should be used at most once by SourceComponent. Note that
the same source may still
                              * be used again in another context if that source is also an
interpolation CRS.
                              *
@@ -164,17 +164,27 @@ final class SourceComponent {
     }
 
     /**
+     * Returns the dimension from which all remaining operations are identity.
+     */
+    static int startOfIdentity(final SourceComponent[] selected) {
+        int n = selected.length;
+        while (n != 0) {
+            if (!selected[--n].operation.getMathTransform().isIdentity()) {
+                break;
+            }
+        }
+        return n;
+    }
+
+    /**
      * Returns a matrix for an affine transform from all source coordinates to the coordinates
of the
      * source components selected for participating in the coordinate operation.
      *
-     * @param sourceDimensions number of dimension of the source {@code CompoundCRS}.
+     * @param sourceDimensions    number of dimension of the source {@code CompoundCRS}.
+     * @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 SourceComponent[] selected)
{
-        int selectedDimensions = 0;
-        for (final SourceComponent component : selected) {
-            selectedDimensions += component.endAtDimension - component.startAtDimension;
-        }
+    static Matrix sourceToSelected(final int sourceDimensions, final int selectedDimensions,
final SourceComponent[] selected) {
         final Matrix select = Matrices.createZero(selectedDimensions + 1, sourceDimensions
+ 1);
         select.setElement(selectedDimensions, sourceDimensions, 1);
         int j = 0;

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=1737980&r1=1737979&r2=1737980&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 13:15:00 2016
@@ -34,6 +34,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.Projection;
 import org.opengis.referencing.operation.Transformation;
 import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.ConcatenatedOperation;
 import org.opengis.referencing.operation.OperationNotFoundException;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
 import org.apache.sis.referencing.operation.matrix.Matrices;
@@ -585,6 +586,7 @@ public final strictfp class CoordinateOp
      * @throws TransformException if an error occurred while converting the test points.
      */
     @Test
+    @DependsOnMethod("testIdentityTransform")
     public void testGeographic3D_to_EllipsoidalHeight() throws FactoryException, TransformException
{
         final CoordinateReferenceSystem sourceCRS = CommonCRS.WGS84.geographic3D();
         final CoordinateReferenceSystem targetCRS = HardCodedCRS.ELLIPSOIDAL_HEIGHT_cm;
@@ -630,15 +632,16 @@ public final strictfp class CoordinateOp
      * @throws FactoryException if the operation can not be created.
      * @throws TransformException if an error occurred while converting the test points.
      */
-//  @Test
+    @Test
+    @DependsOnMethod("testTemporalConversion")
     public void testGeographic3D_to_4D() throws FactoryException, TransformException {
         final CompoundCRS sourceCRS = compound("Test3D", CommonCRS.WGS84.geographic(),  
CommonCRS.Temporal.UNIX.crs());
         final CompoundCRS targetCRS = compound("Test4D", CommonCRS.WGS84.geographic3D(),
CommonCRS.Temporal.MODIFIED_JULIAN.crs());
         final CoordinateOperation operation = factory.createOperation(sourceCRS, targetCRS);
-        assertSame      ("sourceCRS", sourceCRS,        operation.getSourceCRS());
-        assertSame      ("targetCRS", targetCRS,        operation.getTargetCRS());
-        assertEquals    ("name",      "Axis changes",   operation.getName().getCode());
-        assertInstanceOf("operation", Conversion.class, operation);
+        assertSame      ("sourceCRS", sourceCRS, operation.getSourceCRS());
+        assertSame      ("targetCRS", targetCRS, operation.getTargetCRS());
+        assertInstanceOf("operation", ConcatenatedOperation.class, operation);
+        assertEquals    ("name", "CompoundCRS[“Test3D”] → CompoundCRS[“Test4D”]",
operation.getName().getCode());
 
         transform = operation.getMathTransform();
         assertInstanceOf("transform", LinearTransform.class, transform);
@@ -651,6 +654,13 @@ public final strictfp class CoordinateOp
             0, 0, 1./(24*60*60), 40587,
             0, 0, 0, 1
         }), ((LinearTransform) transform).getMatrix(), 1E-12);
+
+        tolerance = 1E-12;
+        verifyTransform(new double[] {
+            -5, -8, CommonCRS.Temporal.DUBLIN_JULIAN.datum().getOrigin().getTime() / 1000
+        }, new double[] {
+            -5, -8, 0, 15019.5              // Same value than in testTemporalConversion().
+        });
         validate();
     }
 }



Mime
View raw message