Package org.geotools.referencing.operation.transform

Source Code of org.geotools.referencing.operation.transform.SimilarityTransformProvider

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2002-2012, Open Source Geospatial Foundation (OSGeo)
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation;
*    version 2.1 of the License.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*/
package org.geotools.referencing.operation.transform;

import javax.measure.quantity.Dimensionless;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;

import org.geotools.metadata.iso.citation.Citations;
import org.geotools.referencing.NamedIdentifier;
import org.geotools.referencing.operation.MathTransformProvider;
import org.geotools.referencing.operation.transform.AffineTransform2D;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.ParameterNotFoundException;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.operation.MathTransform;

/**
* The provider for the "<cite>Similarity transformation</cite>" (EPSG 9621).
* <p>
* Note that similarity transform is a special case of an Affine transform 2D.
*
* @source $URL$
* @version $Id$
* @author Oscar Fonts
*/
public class SimilarityTransformProvider extends MathTransformProvider {

    private static final long serialVersionUID = -7413519919588731455L;

    // TODO: TRANSLATION_1 and TRANSLATION_2 should be expressed in "target CRS units", not necessarily SI.METER.
   
    /**
     * "Ordinate 1 of evaluation point in target CRS" EPSG::8621
     */
    public static final ParameterDescriptor<Double> TRANSLATION_1 = createDescriptor(
        new NamedIdentifier[] {
            new NamedIdentifier(Citations.EPSG, "Ordinate 1 of evaluation point in target CRS"),
            new NamedIdentifier(Citations.EPSG, "8621")
        },
        0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METER);

    /**
     * "Ordinate 2 of evaluation point in target CRS" EPSG::8622
     */
    public static final ParameterDescriptor<Double> TRANSLATION_2 = createDescriptor(
        new NamedIdentifier[] {
            new NamedIdentifier(Citations.EPSG, "Ordinate 2 of evaluation point in target CRS"),
            new NamedIdentifier(Citations.EPSG, "8622")
        },
        0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METER);
   
    /**
     * "Scale difference" EPSG::8611
     */
    public static final ParameterDescriptor<Double> SCALE = createDescriptor(
        new NamedIdentifier[] {
            new NamedIdentifier(Citations.EPSG, "Scale difference"),
            new NamedIdentifier(Citations.EPSG, "8611")
        },
        1, Double.MIN_NORMAL, Double.POSITIVE_INFINITY, Dimensionless.UNIT);
   
    /**
     * "Rotation angle of source coordinate reference system axes" EPSG::8614
     */
    public static final ParameterDescriptor<Double> ROTATION = createDescriptor(
        new NamedIdentifier[] {
            new NamedIdentifier(Citations.EPSG, "Rotation angle of source coordinate reference system axes"),
            new NamedIdentifier(Citations.EPSG, "8614")
        },
        0, 0, 360 * 60 * 60, NonSI.SECOND_ANGLE);

    /**
     * The parameter group for "Similarity transformation" EPSG::9621.
     *
     * Includes {@link #TRANSLATION_1}, {@link #TRANSLATION_2}, {@link #SCALE}, {@link #ROTATION}.
     */
    static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(
        new NamedIdentifier[] {
            new NamedIdentifier(Citations.EPSG, "Similarity transformation"),
            new NamedIdentifier(Citations.EPSG, "9621")
        },
        new ParameterDescriptor[] {
            TRANSLATION_1,
            TRANSLATION_2,
            SCALE,
            ROTATION
        }
    );
   
    /**
     * Creates a two-dimensional similarity transform.
     *
     * EPSG defines explicitly this transform as 2D.
     */
    public SimilarityTransformProvider() {
        super(2, 2, PARAMETERS);
    }

    /**
     * Constructs an {@link AffineTransform2D} math transform from the specified group of parameter values.
     *
     * The similarity transform is a particular case of Affine Transform 2D where:
     *
     * <blockquote><pre>
     * m00 = SCALE * cos(ROTATION)
     * m01 = SCALE * sin(ROTATION)
     * m02 = TRANSLATION_1
     * m10 = -m01
     * m11 = m00
     * m12 = TRANSLATION_2
     * </pre></blockquote>
     *
     * @param  values The group of parameter values {@link #PARAMETERS}.
     * @return an {@link AffineTransform2D}.
     * @throws ParameterNotFoundException if a required parameter was not found.
     */
    protected MathTransform createMathTransform(ParameterValueGroup values)
            throws ParameterNotFoundException {
       
        // The four parameters
        double t1 = doubleValue(TRANSLATION_1, values);
        double t2 = doubleValue(TRANSLATION_2, values);
        double scale = doubleValue(SCALE, values);
        double rotation = doubleValue(ROTATION, values);
       
        // Calculate affine transform coefficients
        double theta = Math.PI * rotation / 648000; // arcsec to rad
        double p1 = scale * Math.cos(theta);
        double p2 = scale * Math.sin(theta);
       
        return new AffineTransform2D(p1, -p2, p2, p1, t1, t2);
    }

}
TOP

Related Classes of org.geotools.referencing.operation.transform.SimilarityTransformProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.