Search in sources :

Example 1 with Line

use of org.apache.sis.math.Line in project sis by apache.

the class LinearTransformBuilder method create.

/**
 * Creates a linear transform approximation from the source positions to the target positions.
 * This method assumes that source positions are precise and that all uncertainty is in the target positions.
 *
 * @param  factory  the factory to use for creating the transform, or {@code null} for the default factory.
 *                  The {@link MathTransformFactory#createAffineTransform(Matrix)} method of that factory
 *                  shall return {@link LinearTransform} instances.
 * @return the fitted linear transform.
 * @throws FactoryException if the transform can not be created,
 *         for example because the source or target points have not be specified.
 *
 * @since 0.8
 */
@Override
@SuppressWarnings("serial")
public LinearTransform create(final MathTransformFactory factory) throws FactoryException {
    if (transform == null) {
        // Protect from changes.
        final double[][] sources = this.sources;
        final double[][] targets = this.targets;
        if (targets == null) {
            throw new InvalidGeodeticParameterException(noData());
        }
        final int sourceDim = (sources != null) ? sources.length : gridSize.length;
        final int targetDim = targets.length;
        correlation = new double[targetDim];
        final MatrixSIS matrix = Matrices.create(targetDim + 1, sourceDim + 1, ExtendedPrecisionMatrix.ZERO);
        matrix.setElement(targetDim, sourceDim, 1);
        for (int j = 0; j < targetDim; j++) {
            final double c;
            switch(sourceDim) {
                case 1:
                    {
                        final int row = j;
                        final Line line = new Line() {

                            @Override
                            public void setEquation(final Number slope, final Number y0) {
                                super.setEquation(slope, y0);
                                // Preserve the extended precision (double-double).
                                matrix.setNumber(row, 0, slope);
                                matrix.setNumber(row, 1, y0);
                            }
                        };
                        if (sources != null) {
                            c = line.fit(vector(sources[0]), vector(targets[j]));
                        } else {
                            c = line.fit(Vector.createSequence(0, 1, gridSize[0]), Vector.create(targets[j], false));
                        }
                        break;
                    }
                case 2:
                    {
                        final int row = j;
                        final Plane plan = new Plane() {

                            @Override
                            public void setEquation(final Number sx, final Number sy, final Number z0) {
                                super.setEquation(sx, sy, z0);
                                // Preserve the extended precision (double-double).
                                matrix.setNumber(row, 0, sx);
                                matrix.setNumber(row, 1, sy);
                                matrix.setNumber(row, 2, z0);
                            }
                        };
                        if (sources != null) {
                            c = plan.fit(vector(sources[0]), vector(sources[1]), vector(targets[j]));
                        } else
                            try {
                                c = plan.fit(gridSize[0], gridSize[1], Vector.create(targets[j], false));
                            } catch (IllegalArgumentException e) {
                                // This may happen if the z vector still contain some "NaN" values.
                                throw new InvalidGeodeticParameterException(noData(), e);
                            }
                        break;
                    }
                default:
                    {
                        throw new FactoryException(Errors.format(Errors.Keys.ExcessiveNumberOfDimensions_1, sourceDim));
                    }
            }
            correlation[j] = c;
        }
        transform = (LinearTransform) nonNull(factory).createAffineTransform(matrix);
    }
    return transform;
}
Also used : Line(org.apache.sis.math.Line) InvalidGeodeticParameterException(org.apache.sis.referencing.factory.InvalidGeodeticParameterException) Plane(org.apache.sis.math.Plane) FactoryException(org.opengis.util.FactoryException) MatrixSIS(org.apache.sis.referencing.operation.matrix.MatrixSIS)

Aggregations

Line (org.apache.sis.math.Line)1 Plane (org.apache.sis.math.Plane)1 InvalidGeodeticParameterException (org.apache.sis.referencing.factory.InvalidGeodeticParameterException)1 MatrixSIS (org.apache.sis.referencing.operation.matrix.MatrixSIS)1 FactoryException (org.opengis.util.FactoryException)1