Author: rmarechal
Date: Tue Apr 19 15:58:49 2016
New Revision: 1739949

URL: http://svn.apache.org/viewvc?rev=1739949&view=rev
Log:
LinearTransformBuilder: add tests

Modified:
    
sis/branches/ImageDatum/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
    
sis/branches/ImageDatum/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java

Modified: 
sis/branches/ImageDatum/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ImageDatum/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java?rev=1739949&r1=1739948&r2=1739949&view=diff
==============================================================================
--- 
sis/branches/ImageDatum/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
 [UTF-8] (original)
+++ 
sis/branches/ImageDatum/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
 [UTF-8] Tue Apr 19 15:58:49 2016
@@ -59,13 +59,28 @@ import org.apache.sis.util.NullArgumentE
  */
 public class LinearTransformBuilder {
 
+    /**
+     * Tolerance use to define if points coordinates are considered as regular 
or not.
+     * A coordinate is define as regular if between its value and the integer 
troncated
+     * coordinate value is lesser than tolerance.
+     */
     private static double COORDS_TOLERANCE = 1E-12;
 
-
+    /**
+     * Define grid size for each dimension.
+     */
     private int[] gridSize;
 
+    /**
+     * Define number of expected points exprimate by {@link #gridSize}.
+     * @see #getLength(int, int, int[])
+     */
     private int gridLength;
 
+    /**
+     * Define the current index of inserted source and target points.
+     * @see #addNoRegularPoints(double[], double[]) 
+     */
     private int noneRegularPointPosition = 0;
 
     /**
@@ -206,10 +221,12 @@ public class LinearTransformBuilder {
     }
 
     /**
+     * Increase the length of the array on the 2nd array dimension.<br>
+     * Stored datas from given array are copied into new array.
      *
-     * @param array
-     * @param newNumberPoints
-     * @return
+     * @param array reference array.
+     * @param newNumberPoints new array length.
+     * @return array with increased length.
      */
     private static double[][] increasePointLength(final double[][] array, 
final int newNumberPoints) {
         final double[][] result = new double[array.length][];
@@ -228,7 +245,7 @@ public class LinearTransformBuilder {
      * @param sourceCoords coordinates from sources point.
      * @return index position into source points array.
      * @throws NullArgumentException if <var>sourceCoords</var> is {@code 
null}.
-     * @throws IllegalArgumentException if <var>sourceCoords</var> do not 
contains only intergers values.
+     * @throws IllegalArgumentException if <var>sourceCoords</var> do not 
contains only integers values.
      */
     private int getRegularArrayPosition(final double... sourceCoords) {
         ArgumentChecks.ensureNonNull("sourceCoords", sourceCoords);
@@ -267,8 +284,8 @@ public class LinearTransformBuilder {
     /**
      * Add couple of points into none regular grid.
      *
-     * @param sourceCoords
-     * @param targetCoords
+     * @param sourceCoords grid point source coordinates.
+     * @param targetCoords target point coordinates.
      */
     private void addNoRegularPoints(final double[] sourceCoords, final 
double[] targetCoords) {
         assert targets != null && targets.length == targetCoords.length;
@@ -440,7 +457,70 @@ public class LinearTransformBuilder {
     }
 
 
-    //------------------------------- public --------------------------------//
+    //-------------------------- package protected 
---------------------------//
+
+    /**
+     * Returns {@code true} if this class is considered as valid.
+     * This object is valid if its attributs are consistent into regular grid
+     * mode or consistent into none regular grid mode.
+     * @return {@code true} if all attributs are consistent else {@code false}.
+     */
+    boolean isValid() {
+
+        if (sources == null
+         && targets == null
+         && gridSize == null)
+            return true;
+
+        //-- sources
+        if (sources == null) {
+            if (gridSize == null)
+                throw new AssertionError("Impossible to have null sources 
points and grid size not defined.");
+            if (noneRegularPointPosition != 0)
+                throw new AssertionError("With grid define as regular 
noneRegularPointPosition attribut should be 0. Found : 
"+noneRegularPointPosition);
+            if (gridLength == 0)
+                throw new AssertionError("With grid define as regular 
gridLength should be equals to gridsize length. "
+                        + "Expected : "+getLength(0, gridSize.length, 
gridSize)+", found : "+gridLength);
+        } else {
+            if (gridSize != null)
+                throw new AssertionError("Impossible to have defined sources 
points and grid size defined.");
+            if (gridLength != 0)
+                throw new AssertionError("With grid define as none regular 
gridLength should be equals to 0. Found : "+gridLength);
+            if (targets == null)
+                throw new AssertionError("Target points should never be null");
+            if (targets[0].length != sources[0].length)
+                throw new AssertionError("With grid defined as none regular, 
sources points and targets points "
+                        + "should own same points number. Sources points 
length : "+sources[0].length+", targets points length : "+targets[0].length);
+            if (sources[0].length != noneRegularPointPosition)
+                throw new AssertionError("With grid define as none regular 
sources points length and noneRegularPointPosition should be equals. "
+                        + "Sources points length : "+sources[0].length+", 
noneRegularPointPosition : "+noneRegularPointPosition);
+        }
+
+        //-- targets
+        if (targets != null) {
+            if (sources == null) {
+                if (gridSize != null) {
+                    if (gridLength != targets[0].length)
+                        throw new AssertionError("Target number points do not 
match with expected stipulate regular grid size."
+                                + " Grid size : 
("+Arrays.toString(gridSize)+"), expected target points numbers : "
+                                +gridLength+", target points found : 
"+targets[0].length);
+                } else {
+                    throw new AssertionError("Only targets points are defined, 
please set grid size or set source points.");
+                }
+            } else {
+                if (sources[0].length != targets[0].length)
+                    throw new AssertionError("Target number points do not 
match with expected sources number points."
+                                + " Sources points number found : 
"+sources[0].length+", target points number found : "+targets[0].length);
+                if (gridSize != null)
+                    throw new AssertionError("With grid define as none regular 
gridSize should be null. Found : "+Arrays.toString(gridSize));
+                if (gridLength != 0)
+                    throw new AssertionError("With grid define as none regular 
gridLength should be equals to 0. Found : "+gridLength);
+            }
+        }
+        return true;
+    }
+
+    //------------------------------- public 
---------------------------------//
 
     /**
      * Set all source and target points from an array which contain all of 
them.
@@ -478,8 +558,8 @@ public class LinearTransformBuilder {
                                   final int tiePointLength, final double[] 
tiePoints)
     {
         ArgumentChecks.ensurePositive("sourceOffset", sourceOffset);
-        ArgumentChecks.ensurePositive("sourceDimension", sourceDimension);
-        ArgumentChecks.ensurePositive("targetOffset", targetOffset);
+        ArgumentChecks.ensureStrictlyPositive("sourceDimension", 
sourceDimension);
+        ArgumentChecks.ensureStrictlyPositive("targetOffset", targetOffset);
         ArgumentChecks.ensureStrictlyPositive("targetdimension", 
targetdimension);
         ArgumentChecks.ensureStrictlyPositive("tiePointLength", 
tiePointLength);
         ArgumentChecks.ensureNonNull("tiePoints", tiePoints);
@@ -489,26 +569,48 @@ public class LinearTransformBuilder {
             throw new IllegalArgumentException("tiePoint array should have 
array length multiple of tiePointLenth."
                     + " Array length : "+tiePointsLen+"  One point length = 
"+tiePointLength);
 
+        //-- verify source and targets offsets
+        final int min = Math.max(sourceOffset, targetOffset);
+        final int max = Math.min(sourceOffset + sourceDimension, targetOffset 
+ targetdimension);
+
+        if (min < max)
+            throw new MismatchedDimensionException("Source offset, dimension 
indexes overlaps target offset, dimension indexes."
+                    + "Source offset : "+sourceOffset
+                    + ", Source dimension : "+sourceDimension
+                    + ", Target offset : "+targetOffset
+                    + ", Target dimension : "+targetdimension);
+
         final int nbTiePoints = tiePointsLen / tiePointLength;
-        sources = (sourceDimension > 0) ? new 
double[sourceDimension][nbTiePoints] : null;
-        targets = new double[targetdimension][nbTiePoints];
 
-        for (int pt = 0; pt < nbTiePoints; pt ++) {
+        if (gridSize == null) {
+            //-- maybe its not efficient
+            if (sources == null)
+                sources = createArray(sourceDimension, nbTiePoints);
+            else
+                sources = increasePointLength(sources, sources[0].length + 
nbTiePoints);
+
+            if (targets == null)
+                targets = createArray(targetdimension, nbTiePoints);
+            else
+                targets = increasePointLength(targets, targets[0].length + 
nbTiePoints);
+        }
 
-            final int originPt = pt * tiePointLength;
+        final double[] srcPt    = new double[sourceDimension];
+        final double[] targetPt = new double[targetdimension];
+
+        for (int pt = 0; pt < nbTiePoints; pt ++) {
 
+            final int originPt  = pt * tiePointLength;
             //-- source
             final int srcOffset = originPt + sourceOffset;
-            for (int srcDim = 0; srcDim < sourceDimension; srcDim++) {
-                sources[srcDim][pt] = tiePoints[srcOffset + srcDim];
-            }
-
+            System.arraycopy(tiePoints, srcOffset, srcPt, 0, sourceDimension);
             //-- target
             final int tarOffset = originPt + targetOffset;
-            for (int tarDim = 0; tarDim < targetdimension; tarDim++) {
-                targets[tarDim][pt] = tiePoints[tarOffset + tarDim];
-            }
+            System.arraycopy(tiePoints, tarOffset, targetPt, 0, 
targetdimension);
+
+            setPoints(srcPt, targetPt);
         }
+        assert isValid();
         notifyChanges();
     }
 
@@ -634,13 +736,18 @@ public class LinearTransformBuilder {
      * @param  points The source points, assumed precise.
      * @throws MismatchedDimensionException if at least one point does not 
have the expected number of dimensions.
      */
-    public void setSourcePoints(final DirectPosition... points) throws 
MismatchedDimensionException {
+    public void setSourcePoints(final DirectPosition... points)
+            throws MismatchedDimensionException
+    {
         ArgumentChecks.ensureNonNull("points", points);
         if (points.length != 0) {
             sources = toArrays(points, points[0].getDimension() == 1 ? 1 : 2);
         } else {
             sources = null;
         }
+        //-- when this setter is used, mandatory pass into no regular grid.
+        gridSize = null;
+        gridLength = 0;
         noneRegularPointPosition = points.length;
         transform   = null;
         correlation = null;
@@ -654,13 +761,19 @@ public class LinearTransformBuilder {
      * @param  points The target points, assumed uncertain.
      * @throws MismatchedDimensionException if not all points have the same 
number of dimensions.
      */
-    public void setTargetPoints(final DirectPosition... points) throws 
MismatchedDimensionException {
+    public void setTargetPoints(final DirectPosition... points)
+            throws MismatchedDimensionException
+    {
         ArgumentChecks.ensureNonNull("points", points);
         if (points.length != 0) {
             targets = toArrays(points, points[0].getDimension());
         } else {
             targets = null;
         }
+        //-- when this setter is used, mandatory pass into no regular grid.
+        gridSize = null;
+        gridLength = 0;
+        noneRegularPointPosition = points.length;
         transform   = null;
         correlation = null;
     }
@@ -678,6 +791,7 @@ public class LinearTransformBuilder {
      */
     public LinearTransform create() {
         if (transform == null) {
+            isValid();
             final double[][] sources = this.sources;  // Protect from changes.
             final double[][] targets = this.targets;
 
@@ -719,7 +833,6 @@ public class LinearTransformBuilder {
                             matrix.setElement(j, 2, plan.z0());
                         }
                     }
-
                     break;
                 }
                 default: throw new AssertionError(sourceDim); // Should have 
been verified by setSourcePoints(…) method.

Modified: 
sis/branches/ImageDatum/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
URL: 
http://svn.apache.org/viewvc/sis/branches/ImageDatum/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java?rev=1739949&r1=1739948&r2=1739949&view=diff
==============================================================================
--- 
sis/branches/ImageDatum/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
 [UTF-8] (original)
+++ 
sis/branches/ImageDatum/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
 [UTF-8] Tue Apr 19 15:58:49 2016
@@ -18,6 +18,7 @@ package org.apache.sis.referencing.opera
 
 import java.util.Random;
 import java.awt.geom.AffineTransform;
+import java.util.Arrays;
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.geometry.DirectPosition1D;
 import org.apache.sis.geometry.DirectPosition2D;
@@ -91,8 +92,8 @@ public final strictfp class LinearTransf
     }
 
     /**
-     * Tests a very simple case where an exact answer is expected.
-     * Tolerance threshold is set to zero because the math transform has been 
built from exactly 3 points,
+     * Tests a very simple on regular grid, case where an exact answer is 
expected.
+     * Tolerance threshold is set to zero because the math transform has been 
built from exactly 4 points,
      * in which case we expect an exact solution without rounding errors at 
the scale of the {@code double}
      * type. This is possible because SIS implementation uses double-double 
arithmetic.
      */
@@ -110,6 +111,7 @@ public final strictfp class LinearTransf
                                                                        new 
DirectPosition2D(1, 2)};
 
         builder.setPoints(sourcePoints, targetPoints);
+        assertTrue(builder.isValid());
         final Matrix m = builder.create().getMatrix();
 
         // First row (x)
@@ -126,6 +128,132 @@ public final strictfp class LinearTransf
     }
 
     /**
+     * Test different kind of insertions.
+     */
+    @Test
+    public void testValidity() {
+
+        //-- test insertion in many times
+        final LinearTransformBuilder builder  = new LinearTransformBuilder();
+        final DirectPosition2D[] sourcePoints = new DirectPosition2D[]{new 
DirectPosition2D(0, 0),
+                                                                       new 
DirectPosition2D(1, 0),
+                                                                       new 
DirectPosition2D(1, 1),
+                                                                       new 
DirectPosition2D(0, 1)};
+
+        final DirectPosition2D[] targetPoints = new DirectPosition2D[]{new 
DirectPosition2D(1, -1),
+                                                                       new 
DirectPosition2D(3, -1),
+                                                                       new 
DirectPosition2D(3, 2),
+                                                                       new 
DirectPosition2D(1, 2)};
+
+        builder.setPoints(Arrays.copyOfRange(sourcePoints, 0, 2), 
Arrays.copyOfRange(targetPoints, 0, 2));
+        assertTrue(builder.isValid());
+        builder.setPoints(Arrays.copyOfRange(sourcePoints, 2, 4), 
Arrays.copyOfRange(targetPoints, 2, 4));
+        assertTrue(builder.isValid());
+
+        final Matrix m = builder.create().getMatrix();
+
+        // First row (x)
+        assertEquals("m₀₀",  2, m.getElement(0, 0), STRICT);
+        assertEquals("m₀₁",  0, m.getElement(0, 1), STRICT);
+        assertEquals("m₀₂",  1, m.getElement(0, 2), STRICT);
+
+        // Second row (y)
+        assertEquals("m₁₀",  0, m.getElement(1, 0), STRICT);
+        assertEquals("m₁₁",  3, m.getElement(1, 1), STRICT);
+        assertEquals("m₁₂", -1, m.getElement(1, 2), STRICT);
+
+//        assertArrayEquals("correlation", new double[] {1, 1}, 
builder.correlation(), STRICT);
+
+                                //--------------//
+
+
+        //-- Test switch from regular grid to no regular
+        //-- begin insertion with integer coordinates points and switch with 
floating coordinates points.
+        final LinearTransformBuilder regBuilder  = new 
LinearTransformBuilder();
+        final DirectPosition2D[] noRegSourcePoints = new 
DirectPosition2D[]{new DirectPosition2D(1+1E-12, 1),
+                                                                       new 
DirectPosition2D(0, 1+1E-12)};
+
+        //-- set 2 pts as regular grid.
+        regBuilder.setPoints(Arrays.copyOfRange(sourcePoints, 0, 2), 
Arrays.copyOfRange(targetPoints, 0, 2));
+        assertTrue(regBuilder.isValid());
+
+        //-- set 2 no regular points and verify that switch between regular to 
none regular grid is controled
+        regBuilder.setPoints(noRegSourcePoints, 
Arrays.copyOfRange(targetPoints, 2, 4));
+        assertTrue(regBuilder.isValid());
+
+                                //--------------//
+
+
+        //-- test insert source points and targets points separately
+        LinearTransformBuilder builderTest  = new LinearTransformBuilder();
+        builderTest.setSourcePoints(sourcePoints);
+        builderTest.setTargetPoints(targetPoints);
+        assertTrue(builderTest.isValid());
+
+                                //--------------//
+
+        //-- test validity at origin
+        builderTest  = new LinearTransformBuilder();
+        assertTrue(builderTest.isValid());
+    }
+
+    /**
+     * Test method {@link LinearTransformBuilder#setModelTiePoints(int, int, 
int, int, int, double[]) .
+     */
+    @Test
+    public void setTiePointTest() {
+
+        final double[] points = new double[]{
+        //-- [Empty][x source][y source][Empty][Empty][x dest][y dest]
+        Double.NaN, 0, 0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 
1, -1,//-- pt 0
+        Double.NaN, 1, 0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 
3, -1,//-- pt 1
+        Double.NaN, 1, 1, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 
3,  2,//-- pt 2
+        Double.NaN, 0, 1, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, 
1,  2,//-- pt 3
+        };
+
+        //-- No regular
+        LinearTransformBuilder builder  = new LinearTransformBuilder();
+
+        builder.setModelTiePoints(1, 2, 5, 2, 7, points);
+        assertTrue(builder.isValid());
+
+        Matrix m = builder.create().getMatrix();
+
+        // First row (x)
+        assertEquals("m₀₀",  2, m.getElement(0, 0), STRICT);
+        assertEquals("m₀₁",  0, m.getElement(0, 1), STRICT);
+        assertEquals("m₀₂",  1, m.getElement(0, 2), STRICT);
+
+        // Second row (y)
+        assertEquals("m₁₀",  0, m.getElement(1, 0), STRICT);
+        assertEquals("m₁₁",  3, m.getElement(1, 1), STRICT);
+        assertEquals("m₁₂", -1, m.getElement(1, 2), STRICT);
+
+//        assertArrayEquals("correlation", new double[] {1, 1}, 
builder.correlation(), STRICT);
+
+        //-- regular
+        builder  = new LinearTransformBuilder(2, 2);
+
+        builder.setModelTiePoints(1, 2, 5, 2, 7, points);
+        assertTrue(builder.isValid());
+
+        m = builder.create().getMatrix();
+
+        // First row (x)
+        assertEquals("m₀₀",  2, m.getElement(0, 0), STRICT);
+        assertEquals("m₀₁",  0, m.getElement(0, 1), STRICT);
+        assertEquals("m₀₂",  1, m.getElement(0, 2), STRICT);
+
+        // Second row (y)
+        assertEquals("m₁₀",  0, m.getElement(1, 0), STRICT);
+        assertEquals("m₁₁",  3, m.getElement(1, 1), STRICT);
+        assertEquals("m₁₂", -1, m.getElement(1, 2), STRICT);
+
+//        assertArrayEquals("correlation", new double[] {1, 1}, 
builder.correlation(), STRICT);
+    }
+
+
+    /**
      * Test comportements which should fail.
      */
     @Test
@@ -157,52 +285,58 @@ public final strictfp class LinearTransf
             //-- do nothing test validate
         }
 
+        final DirectPosition2D[] sourcePoints = new DirectPosition2D[]{new 
DirectPosition2D(0, 0),
+                                                                       new 
DirectPosition2D(1, 0),
+                                                                       new 
DirectPosition2D(1, 1),
+                                                                       new 
DirectPosition2D(0, 1)};
+
+        final DirectPosition2D[] targetPoints = new DirectPosition2D[]{new 
DirectPosition2D(1, -1),
+                                                                       new 
DirectPosition2D(3, -1),
+                                                                       new 
DirectPosition2D(3, 2),
+                                                                       new 
DirectPosition2D(1, 2)};
+
+
         //-- try to build a regular grid with a missing point
         try {
             final LinearTransformBuilder builder = new 
LinearTransformBuilder(2, 2);
-            final DirectPosition2D[] sourcePoints = new DirectPosition2D[]{new 
DirectPosition2D(0, 0),
-                                                                           
//--new DirectPosition2D(1, 0), volontary miss a grid point
-                                                                           new 
DirectPosition2D(1, 1),
-                                                                           new 
DirectPosition2D(0, 1)};
-
-            final DirectPosition2D[] targetPoints = new DirectPosition2D[]{new 
DirectPosition2D(1, -1),
-                                                                           
//--new DirectPosition2D(3, -1),
-                                                                           new 
DirectPosition2D(3, 2),
-                                                                           new 
DirectPosition2D(1, 2)};
-
-            builder.setPoints(sourcePoints, targetPoints);
+            //-- missing one point
+            builder.setPoints(Arrays.copyOfRange(sourcePoints, 0, 3), 
Arrays.copyOfRange(targetPoints, 0, 3));
             final Matrix m = builder.create().getMatrix();
             Assert.fail("Test should thrown an exception it is normaly 
impossible to build a transformation with missing grid point.");
         } catch (IllegalStateException ex) {
-            //-- do nothing
+            //-- test with missing points from expected defined grid.
         }
 
-
-
         try {
+            final LinearTransformBuilder builder = new 
LinearTransformBuilder();
 
-        } catch (Exception ex) {
-
+            builder.setSourcePoints(Arrays.copyOfRange(sourcePoints, 0, 3));
+            builder.setTargetPoints(targetPoints);
+            final Matrix m = builder.create().getMatrix();
+            Assert.fail("Test should thrown an exception it is normaly 
impossible to build a transformation with missing grid point.");
+        } catch (AssertionError ex) {
+            //-- define grid with missing source points.
         }
-        try {
-
-        } catch (Exception ex) {
 
-        }
         try {
-
-        } catch (Exception ex) {
-
+            //-- test define builder as regular grid and only set targets 
points
+            final LinearTransformBuilder builderTest = new 
LinearTransformBuilder(2, 2);
+            assertTrue(builderTest.isValid());
+            builderTest.setTargetPoints(targetPoints);
+            builderTest.isValid();
+        } catch (AssertionError ex) {
+            //-- only setted target points + grid is not enought to build 
transform
         }
-        try {
 
-        } catch (Exception ex) {
 
-        }
         try {
-
-        } catch (Exception ex) {
-
+            //-- test define builder as regular grid and only set targets 
points
+            final LinearTransformBuilder builderTest = new 
LinearTransformBuilder(2, 2);
+            assertTrue(builderTest.isValid());
+            builderTest.setSourcePoints(sourcePoints);
+            builderTest.isValid();
+        } catch (AssertionError ex) {
+            //-- only setted source points + grid is not enought to build 
transform
         }
     }
 


Reply via email to