All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotoolkit.referencing.operation.provider.PositionVector7Param Maven / Gradle / Ivy

/*
 *    Geotoolkit.org - An Open Source Java GIS Toolkit
 *    http://www.geotoolkit.org
 *
 *    (C) 2005-2012, Open Source Geospatial Foundation (OSGeo)
 *    (C) 2009-2012, Geomatys
 *
 *    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.geotoolkit.referencing.operation.provider;

import javax.measure.unit.SI;
import javax.measure.unit.NonSI;
import net.jcip.annotations.Immutable;

import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.parameter.ParameterNotFoundException;
import org.opengis.parameter.InvalidParameterValueException;
import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.Transformation;
import org.opengis.referencing.operation.NoninvertibleTransformException;

import org.geotoolkit.measure.Units;
import org.geotoolkit.resources.Errors;
import org.geotoolkit.parameter.Parameters;
import org.geotoolkit.parameter.DefaultParameterDescriptor;
import org.geotoolkit.metadata.iso.citation.Citations;
import org.geotoolkit.referencing.NamedIdentifier;
import org.geotoolkit.referencing.datum.BursaWolfParameters;
import org.geotoolkit.referencing.operation.MathTransforms;
import org.geotoolkit.referencing.operation.MathTransformProvider;
import org.geotoolkit.referencing.operation.transform.GeocentricTransform;
import org.geotoolkit.referencing.operation.transform.GeocentricAffineTransform;

import static java.util.Collections.singletonMap;
import static org.geotoolkit.referencing.operation.provider.UniversalParameters.createDescriptor;


/**
 * The provider for "Position Vector 7-parameters transformation" (EPSG:9606).
 * In addition to the EPSG parameters, this provider defines some OGC/Geotk-specific parameters.
 * Those parameters begin with the {@code "src_"} or {@code "tgt_"} prefix, and modify the math
 * transform as below:
 * 

*

    *
  • If a {@code "src_*"} parameter is present, then an {@link EllipsoidToGeocentric} * transform will be concatenated before the geocentric operation.
  • *
  • If a {@code "tgt_*"} parameter is present, then an {@link GeocentricToEllipsoid} * transform will be concatenated after the geocentric operation.
  • *
* * *

The following table summarizes the parameters recognized by this provider. * For a more detailed parameter list, see the {@link #PARAMETERS} constant.

*

Operation name: {@code Position Vector transformation (geog2D domain)}

* * * * * * * * * * * * * * * *
Parameter nameDefault value
{@code dx}0 metres
{@code dy}0 metres
{@code dz}0 metres
{@code ex}0 ''
{@code ey}0 ''
{@code ez}0 ''
{@code ppm}0
{@code src_semi_major}
{@code src_semi_minor}
{@code tgt_semi_major}
{@code tgt_semi_minor}
{@code src_dim}2
{@code tgt_dim}2
* * * @author Martin Desruisseaux (IRD, Geomatys) * @version 3.20 * * @see Geotk coordinate operations matrix * * @since 2.2 * @module */ @Immutable public class PositionVector7Param extends MathTransformProvider { /** * Serial number for inter-operability with different versions. */ private static final long serialVersionUID = -6398226638364450229L; /** * The default value for geographic source and target dimensions, which is 2. * * {@note If this default value is modified, then the handling of the 3D * cases in MolodenskyTransform must be adjusted too.} */ static final int DEFAULT_DIMENSION = 2; /** * The maximal value for a rotation, in arc-second. */ private static final double MAX_ROTATION = 180*60*60; /** * The operation parameter descriptor for the number of source geographic dimension (2 or 3). * This is a Geotk-specific argument. If presents, an {@code "Ellipsoid_To_Geocentric"} * transform will be concatenated before the geocentric translation. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor SRC_DIM = DefaultParameterDescriptor.create( singletonMap(NAME_KEY, new NamedIdentifier(Citations.GEOTOOLKIT, "src_dim")), DEFAULT_DIMENSION, 2, 3, false); /** * The operation parameter descriptor for the number of target geographic dimension (2 or 3). * This is a Geotk-specific argument. If presents, a {@code "Geocentric_To_Ellipsoid"} * transform will be concatenated after the geocentric translation. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor TGT_DIM = DefaultParameterDescriptor.create( singletonMap(NAME_KEY, new NamedIdentifier(Citations.GEOTOOLKIT, "tgt_dim")), DEFAULT_DIMENSION, 2, 3, false); /** * The operation parameter descriptor for the {@code "src_semi_major"} optional parameter value. * This is a Geotk-specific argument. If presents, an {@code "Ellipsoid_To_Geocentric"} * transform will be concatenated before the geocentric translation. *

* Valid values range from 0 to infinity. Units are {@linkplain SI#METRE metres}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor SRC_SEMI_MAJOR = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "src_semi_major") }, Double.NaN, 0.0, Double.POSITIVE_INFINITY, SI.METRE, false); /** * The operation parameter descriptor for the {@code "src_semi_minor"} optional parameter value. * This is a Geotk-specific argument. If presents, an {@code "Ellipsoid_To_Geocentric"} * transform will be concatenated before the geocentric translation. *

* Valid values range from 0 to infinity. Units are {@linkplain SI#METRE metres}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor SRC_SEMI_MINOR = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "src_semi_minor"), }, Double.NaN, 0.0, Double.POSITIVE_INFINITY, SI.METRE, false); /** * The operation parameter descriptor for the {@code "tgt_semi_major"} optional parameter value. * This is a Geotk-specific argument. If presents, a {@code "Geocentric_To_Ellipsoid"} * transform will be concatenated after the geocentric translation. *

* Valid values range from 0 to infinity. Units are {@linkplain SI#METRE metres}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor TGT_SEMI_MAJOR = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "tgt_semi_major") }, Double.NaN, 0.0, Double.POSITIVE_INFINITY, SI.METRE, false); /** * The operation parameter descriptor for the {@code "tgt_semi_minor"} optional parameter value. * This is a Geotk-specific argument. If presents, a {@code "Geocentric_To_Ellipsoid"} * transform will be concatenated after the geocentric translation. *

* Valid values range from 0 to infinity. Units are {@linkplain SI#METRE metres}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor TGT_SEMI_MINOR = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "tgt_semi_minor") }, Double.NaN, 0.0, Double.POSITIVE_INFINITY, SI.METRE, false); /** * The operation parameter descriptor for the X-axis translation * ({@linkplain BursaWolfParameters#dx dx}) parameter value. Valid values range * from negative to positive infinity. Units are {@linkplain SI#METRE metres}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor DX = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "dx"), new NamedIdentifier(Citations.EPSG, "X-axis translation") }, 0.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, true); /** * The operation parameter descriptor for the Y-axis translation * ({@linkplain BursaWolfParameters#dy dy}) parameter value. Valid values range * from negative to positive infinity. Units are {@linkplain SI#METRE metres}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor DY = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "dy"), new NamedIdentifier(Citations.EPSG, "Y-axis translation") }, 0.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, true); /** * The operation parameter descriptor for the Z-axis translation * ({@linkplain BursaWolfParameters#dz dz}) parameter value. Valid values range * from negative to positive infinity. Units are {@linkplain SI#METRE metres}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor DZ = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "dz"), new NamedIdentifier(Citations.EPSG, "Z-axis translation") }, 0.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, SI.METRE, true); /** * The operation parameter descriptor for the X-axis rotation * ({@linkplain BursaWolfParameters#ex ex}) parameter value. Units are * {@linkplain NonSI#SECOND_ANGLE arc-seconds}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor EX = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "ex"), new NamedIdentifier(Citations.EPSG, "X-axis rotation") }, 0.0, -MAX_ROTATION, MAX_ROTATION, NonSI.SECOND_ANGLE, true); /** * The operation parameter descriptor for the Y-axis rotation * ({@linkplain BursaWolfParameters#ey ey}) parameter value. Units are * {@linkplain NonSI#SECOND_ANGLE arc-seconds}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor EY = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "ey"), new NamedIdentifier(Citations.EPSG, "Y-axis rotation") }, 0.0, -MAX_ROTATION, MAX_ROTATION, NonSI.SECOND_ANGLE, true); /** * The operation parameter descriptor for the Z-axis rotation * ({@linkplain BursaWolfParameters#ez ez}) parameter value. Units are * {@linkplain NonSI#SECOND_ANGLE arc-seconds}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor EZ = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "ez"), new NamedIdentifier(Citations.EPSG, "Z-axis rotation") }, 0.0, -MAX_ROTATION, MAX_ROTATION, NonSI.SECOND_ANGLE, true); /** * The operation parameter descriptor for the Scale difference * ({@linkplain BursaWolfParameters#ppm ppm}) parameter value. Valid values * range from negative to positive infinity. Units are * {@linkplain Units#PPM parts per million}. * * @deprecated Invoke {@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)} instead. */ @Deprecated public static final ParameterDescriptor PPM = createDescriptor( new NamedIdentifier[] { new NamedIdentifier(Citations.OGC, "ppm"), new NamedIdentifier(Citations.EPSG, "Scale difference") }, 0.0, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Units.PPM, true); /** * The group of all parameters expected by this coordinate operation. * The following table lists the operation names and the parameters recognized by Geotk. * Note that all {@code "src_*"} and {@code "tgt_*"} parameters are OGC/Geotk-specific, * and modify the math transform as below: *

*

    *
  • If a {@code "src_*"} parameter is present, then an {@link EllipsoidToGeocentric} * transform will be concatenated before the geocentric translation.
  • *
  • If a {@code "tgt_*"} parameter is present, then an {@link GeocentricToEllipsoid} * transform will be concatenated after the geocentric translation.
  • *
*

* *

* * * * * * * * * * * * * * *
* * * * * *
Name:EPSG:Position Vector transformation (geog2D domain)
Alias:EPSG:Position Vector 7-param. transformation
EPSG:Bursa-Wolf
Identifier:EPSG:9606
*
* * * *
Name:OGC:dx
Alias:EPSG:X-axis translation
*
* * * * * *
Type:{@code Double}
Obligation:mandatory
Value range:(-∞ … ∞) metres
Default value:0 metres
*
* * * *
Name:OGC:dy
Alias:EPSG:Y-axis translation
*
* * * * * *
Type:{@code Double}
Obligation:mandatory
Value range:(-∞ … ∞) metres
Default value:0 metres
*
* * * *
Name:OGC:dz
Alias:EPSG:Z-axis translation
*
* * * * * *
Type:{@code Double}
Obligation:mandatory
Value range:(-∞ … ∞) metres
Default value:0 metres
*
* * * *
Name:OGC:ex
Alias:EPSG:X-axis rotation
*
* * * * * *
Type:{@code Double}
Obligation:mandatory
Value range:[-648000 … 648000] ''
Default value:0 ''
*
* * * *
Name:OGC:ey
Alias:EPSG:Y-axis rotation
*
* * * * * *
Type:{@code Double}
Obligation:mandatory
Value range:[-648000 … 648000] ''
Default value:0 ''
*
* * * *
Name:OGC:ez
Alias:EPSG:Z-axis rotation
*
* * * * * *
Type:{@code Double}
Obligation:mandatory
Value range:[-648000 … 648000] ''
Default value:0 ''
*
* * * *
Name:OGC:ppm
Alias:EPSG:Scale difference
*
* * * * * *
Type:{@code Double}
Obligation:mandatory
Value range:(-∞ … ∞)
Default value:0
*
* * *
Name:OGC:src_semi_major
*
* * * * *
Type:{@code Double}
Obligation:optional
Value range:[0…∞) metres
*
* * *
Name:OGC:src_semi_minor
*
* * * * *
Type:{@code Double}
Obligation:optional
Value range:[0…∞) metres
*
* * *
Name:OGC:tgt_semi_major
*
* * * * *
Type:{@code Double}
Obligation:optional
Value range:[0…∞) metres
*
* * *
Name:OGC:tgt_semi_minor
*
* * * * *
Type:{@code Double}
Obligation:optional
Value range:[0…∞) metres
*
* * *
Name:Geotk:src_dim
*
* * * * * *
Type:{@code Integer}
Obligation:optional
Value range:[2…3]
Default value:2
*
* * *
Name:Geotk:tgt_dim
*
* * * * * *
Type:{@code Integer}
Obligation:optional
Value range:[2…3]
Default value:2
*
*/ public static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(9606, "Position Vector transformation (geog2D domain)", "Position Vector 7-param. transformation"); /** * Creates a parameters group using the 7 parameters. */ static ParameterDescriptorGroup createDescriptorGroup(final int code, final String name, final String legacyName) { return UniversalParameters.createDescriptorGroup(new ReferenceIdentifier[] { new NamedIdentifier(Citations.EPSG, name), new NamedIdentifier(Citations.EPSG, legacyName), new NamedIdentifier(Citations.EPSG, "Bursa-Wolf"), new IdentifierCode (Citations.EPSG, code) }, null, new ParameterDescriptor[] { DX, DY, DZ, EX, EY, EZ, PPM, SRC_SEMI_MAJOR, SRC_SEMI_MINOR, TGT_SEMI_MAJOR, TGT_SEMI_MINOR, SRC_DIM, TGT_DIM }, 0); } /** * Constructs the provider. */ public PositionVector7Param() { this(PARAMETERS); } /** * Constructs a provider with the specified parameters. */ PositionVector7Param(final ParameterDescriptorGroup parameters) { super(3, 3, parameters); } /** * Returns the operation type, which is a transformation. */ @Override public Class getOperationType() { return Transformation.class; } /** * Creates a math transform from the specified group of parameter values. * * @param values The group of parameter values. * @return The created math transform. * @throws ParameterNotFoundException if a required parameter was not found. */ @Override protected MathTransform createMathTransform(final ParameterValueGroup values) throws ParameterNotFoundException { final BursaWolfParameters parameters = new BursaWolfParameters(null); fill(parameters, values); return concatenate(concatenate(new GeocentricAffineTransform(parameters, getParameters()), values, SRC_SEMI_MAJOR, SRC_SEMI_MINOR, SRC_DIM), values, TGT_SEMI_MAJOR, TGT_SEMI_MINOR, TGT_DIM); } /** * Fills the given Bursa-Wolf parameters according the specified values. * This method is invoked automatically by {@link #createMathTransform}. * * @param parameters The Bursa-Wold parameters to set. * @param values The parameter values to read. Those parameters will not be modified. */ void fill(final BursaWolfParameters parameters, final ParameterValueGroup values) { parameters.dx = Parameters.doubleValue(DX, values); parameters.dy = Parameters.doubleValue(DY, values); parameters.dz = Parameters.doubleValue(DZ, values); parameters.ex = Parameters.doubleValue(EX, values); parameters.ey = Parameters.doubleValue(EY, values); parameters.ez = Parameters.doubleValue(EZ, values); parameters.ppm = Parameters.doubleValue(PPM, values); } /** * Concatenates the supplied transform with an "ellipsoid to geocentric" or a * "geocentric to ellipsoid" step, if needed. */ private static MathTransform concatenate(final MathTransform transform, final ParameterValueGroup values, final ParameterDescriptor major, final ParameterDescriptor minor, final ParameterDescriptor dim) { double semiMajor = Parameters.doubleValue(major, values); double semiMinor = Parameters.doubleValue(minor, values); Integer dimension = Parameters.integerValue(dim, values); boolean hasHeight = false; if (dimension == null) { if (Double.isNaN(semiMajor) && Double.isNaN(semiMinor)) { return transform; } } else { switch (dimension) { case DEFAULT_DIMENSION: break; case 3: hasHeight = true; break; default: { final String name = dim.getName().getCode(); throw new InvalidParameterValueException(Errors.format( Errors.Keys.ILLEGAL_ARGUMENT_$2, name, dimension), name, dimension); } } } ensureValid(major, semiMajor); ensureValid(minor, semiMinor); final MathTransform step; step = GeocentricTransform.create(semiMajor, semiMinor, SI.METRE, hasHeight); // Note: dimension may be 0 if not user-provided, which is treated as 2. if (dim == SRC_DIM) { return MathTransforms.concatenate(step, transform); } else try { return MathTransforms.concatenate(transform, step.inverse()); } catch (NoninvertibleTransformException e) { throw new AssertionError(e); // Should never happen in Geotk implementation. } } /** * Ensures the the specified parameter is valid. */ private static void ensureValid(final ParameterDescriptor param, double value) { if (!(value > 0)) { throw new IllegalStateException(Errors.format( Errors.Keys.NO_PARAMETER_$1, param.getName().getCode())); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy