sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmarec...@apache.org
Subject svn commit: r1739949 - in /sis/branches/ImageDatum/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
Date Tue, 19 Apr 2016 15:58:49 GMT
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
         }
     }
 



Mime
View raw message