sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1654026 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/ sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/ sis-referencing/src/test/java/org/apache/sis/test...
Date Thu, 22 Jan 2015 19:38:05 GMT
Author: desruisseaux
Date: Thu Jan 22 19:38:05 2015
New Revision: 1654026

URL: http://svn.apache.org/r1654026
Log:
Initial draft of a LinearTransformBuilder.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
  (with props)
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
  (with props)
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/CompoundDirectPositions.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java

Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java?rev=1654026&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
[UTF-8] Thu Jan 22 19:38:05 2015
@@ -0,0 +1,154 @@
+/*
+ * 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.builder;
+
+import org.opengis.geometry.DirectPosition;
+import org.opengis.geometry.MismatchedDimensionException;
+import org.apache.sis.math.Plane;
+import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.LinearTransform;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.resources.Errors;
+
+
+/**
+ * Creates a linear (usually affine) transform which will map approximatively the given source
points to
+ * the given target points. The transform coefficients are determined using a <cite>least
squares</cite>
+ * estimation method.
+ *
+ * <div class="note"><b>Implementation note:</b>
+ * The quantity that current implementation tries to minimize is not strictly the squared
Euclidian distance.
+ * The current implementation rather processes each target dimension independently, which
may not give the same
+ * result than if we tried to minimize the squared Euclidian distances by taking all dimensions
in account together.
+ * This algorithm may change in future SIS versions.
+ * </div>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5
+ * @version 0.5
+ * @module
+ */
+public class LinearTransformBuilder {
+    /**
+     * The arrays of source ordinate values, for example (x[], y[], z[]).
+     * This is {@code null} if not yet specified.
+     */
+    private double[][] sources;
+
+    /**
+     * The arrays of target ordinate values, for example (x[], y[], z[]).
+     * This is {@code null} if not yet specified.
+     */
+    private double[][] targets;
+
+    /**
+     * An estimation of the Pearson correlation coefficient for each target dimension.
+     * This is {@code null} if not yet specified.
+     */
+    private double[] correlation;
+
+    /**
+     * Creates a new linear transform builder.
+     */
+    public LinearTransformBuilder() {
+    }
+
+    /**
+     * Extracts the ordinate values of the given points into separated arrays, one for each
dimension.
+     *
+     * @param points The points from which to extract the ordinate values.
+     * @param dimension The expected number of dimensions.
+     */
+    private static double[][] toArrays(final DirectPosition[] points, final int dimension)
{
+        final int length = points.length;
+        final double[][] ordinates = new double[dimension][length];
+        for (int j=0; j<length; j++) {
+            final DirectPosition p = points[j];
+            final int d = p.getDimension();
+            if (d != dimension) {
+                throw new MismatchedDimensionException(Errors.format(
+                        Errors.Keys.MismatchedDimension_3, "points[" + j + ']', dimension,
d));
+            }
+            for (int i=0; i<dimension; i++) {
+                ordinates[i][j] = p.getOrdinate(i);
+            }
+        }
+        return ordinates;
+    }
+
+    /**
+     * Sets the source points. The number of points shall be the same than the number of
target points.
+     *
+     * <p><b>Limitation:</b> in current implementation, the source points
must be two-dimensional.
+     * But this restriction may be removed in a future SIS version.</p>
+     *
+     * @param  points The source points.
+     * @throws MismatchedDimensionException if at least one point does not have the expected
number of dimensions.
+     */
+    public void setSourcePoints(final DirectPosition... points) throws MismatchedDimensionException
{
+        ArgumentChecks.ensureNonNull("points", points);
+        sources = toArrays(points, 2);
+        correlation = null;
+    }
+
+    /**
+     * Sets the target points. The number of points shall be the same than the number of
source points.
+     * Target points can have any number of dimensions (not necessarily 2), but all points
shall have
+     * the same number of dimensions.
+     *
+     * @param  points The target points.
+     * @throws MismatchedDimensionException if not all points have the same number of dimensions.
+     */
+    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;
+        }
+        correlation = null;
+    }
+
+    /**
+     * Creates a linear transform from the source and target points.
+     *
+     * @return The fitted linear transform.
+     */
+    public LinearTransform create() {
+        final double[][] sources = this.sources;  // Protect from changes.
+        final double[][] targets = this.targets;
+        if (sources == null || targets == null) {
+            throw new IllegalStateException(Errors.format(
+                    Errors.Keys.MissingValueForProperty_1, (sources == null) ? "sources"
: "targets"));
+        }
+        final int sourceDim = sources.length;
+        final int targetDim = targets.length;
+        final MatrixSIS matrix = Matrices.createZero(targetDim + 1, sourceDim + 1);
+        final Plane plan = new Plane();
+        correlation = new double[targetDim];
+        for (int j=0; j<targets.length; j++) {
+            correlation[j] = plan.fit(sources[0], sources[1], targets[j]);
+            matrix.setElement(j, 0, plan.cx);
+            matrix.setElement(j, 1, plan.cy);
+            matrix.setElement(j, 2, plan.c);
+        }
+        matrix.setElement(targetDim, sourceDim, 1);
+        return MathTransforms.linear(matrix);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java?rev=1654026&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
[UTF-8] Thu Jan 22 19:38:05 2015
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * Helper classes for creating {@code MathTransform}s from a set of points.
+ * The builder classes require a matched set of known positions, one from a "source" data
set and another
+ * from a "target" data set. The builder will then provide a transformation positions from
the "source" CRS
+ * to the "target" CRS.
+ *
+ * <p>Algorithms in this package use a <cite>least squares</cite> estimation
method.
+ * The matching parameters are estimated by minimizing the sum of the squared distances
+ * between the given points and the fitted points (i.e. the points calculated using the
+ * transform). Note that "distance" here is not necessarily the Euclidian distance or a
+ * geodesic distance. It may be an approximation of Euclidian distance for implementation
+ * convenience.</p>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @version 0.5
+ * @since   0.5
+ * @module
+ */
+package org.apache.sis.referencing.operation.builder;

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java?rev=1654026&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
[UTF-8] Thu Jan 22 19:38:05 2015
@@ -0,0 +1,62 @@
+/*
+ * 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.builder;
+
+import org.opengis.referencing.operation.Matrix;
+import org.apache.sis.geometry.DirectPosition2D;
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests {@link LinearTransformBuilder}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5
+ * @version 0.5
+ * @module
+ */
+public final strictfp class LinearTransformBuilderTest extends TestCase {
+    /**
+     * Tests a very simple case where an exact answer is expected.
+     */
+    @Test
+    public void testExact() {
+        final LinearTransformBuilder builder = new LinearTransformBuilder();
+        builder.setSourcePoints(
+                new DirectPosition2D(1, 1),
+                new DirectPosition2D(1, 2),
+                new DirectPosition2D(2, 2));
+        builder.setTargetPoints(
+                new DirectPosition2D(3, 2),
+                new DirectPosition2D(3, 5),
+                new DirectPosition2D(5, 5));
+        final Matrix m = builder.create().getMatrix();
+
+        // First row (x)
+        assertEquals( 2, m.getElement(0, 0), 0);
+        assertEquals( 0, m.getElement(0, 1), 1E-20);
+        assertEquals( 1, m.getElement(0, 2), 0);
+
+        // Second row (y)
+        assertEquals( 0, m.getElement(1, 0), 0);
+        assertEquals( 3, m.getElement(1, 1), 0);
+        assertEquals(-1, m.getElement(1, 2), 0);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilderTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1654026&r1=1654025&r2=1654026&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] Thu Jan 22 19:38:05 2015
@@ -125,6 +125,7 @@ import org.junit.BeforeClass;
 
     org.apache.sis.distance.LatLonPointRadiusTest.class, // Pending refactoring in a geometry
package.
 
+    org.apache.sis.referencing.operation.builder.LinearTransformBuilderTest.class,
     org.apache.sis.internal.referencing.ServicesForMetadataTest.class,
     org.apache.sis.test.integration.ReferencingInMetadataTest.class,
     org.apache.sis.test.integration.DefaultMetadataTest.class

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/CompoundDirectPositions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/CompoundDirectPositions.java?rev=1654026&r1=1654025&r2=1654026&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/CompoundDirectPositions.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/CompoundDirectPositions.java
[UTF-8] Thu Jan 22 19:38:05 2015
@@ -40,7 +40,7 @@ import org.apache.sis.util.resources.Err
  */
 final class CompoundDirectPositions implements DirectPosition, Iterable<DirectPosition>,
Iterator<DirectPosition> {
     /**
-     * The array of ordinate values, for example (x[], y[], z[]).
+     * The arrays of ordinate values, for example (x[], y[], z[]).
      */
     private final double[][] ordinates;
 

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java?rev=1654026&r1=1654025&r2=1654026&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java [UTF-8]
(original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/math/Plane.java [UTF-8]
Thu Jan 22 19:38:05 2015
@@ -152,7 +152,7 @@ public class Plane implements Cloneable,
      * This method needs to iterate over the points two times:
      * one for computing the coefficients, and one for the computing the Pearson coefficient.
      */
-    private double fit(final Iterable<DirectPosition> points) {
+    private double fit(final Iterable<? extends DirectPosition> points) {
         int i = 0, n = 0;
         final DoubleDouble sum_x  = new DoubleDouble();
         final DoubleDouble sum_y  = new DoubleDouble();



Mime
View raw message