Class InterpolatedGeocentricTransform
java.lang.Object
org.apache.sis.io.wkt.FormattableObject
org.apache.sis.referencing.operation.transform.AbstractMathTransform
org.apache.sis.referencing.operation.transform.DatumShiftTransform
org.apache.sis.referencing.operation.transform.InterpolatedGeocentricTransform
- All Implemented Interfaces:
Serializable
,Parameterized
,LenientComparable
,org.opengis.referencing.operation.MathTransform
- Direct Known Subclasses:
InterpolatedGeocentricTransform.Inverse
,InterpolatedGeocentricTransform2D
Transforms between two geographic CRS by performing geocentric translations interpolated from a grid file.
This transform is used mainly for "France geocentric interpolation" (ESPG:9655) datum shifts,
but Apache SIS implementation allows the use for other regions.
Algorithm
This class transforms two- or three- dimensional coordinates from a geographic CRS to another geographic CRS. The changes between source and target coordinates are small (usually less than 400 metres), but vary for every position. Those changes are provided in a datum shift grid, usually loaded from one or two files.Many datum shift grids like NADCON and NTv2 apply the changes directly on geographic coordinates.
This relatively simple case is handled by InterpolatedTransform
.
But the InterpolatedGeocentricTransform
algorithm uses the grid in a more complex way:
- Convert input geographic coordinate (λ,φ) to geocentric coordinate (X,Y,Z).
- Ask
DatumShiftGrid
for the offset to apply for coordinate (λ,φ). But instead of returning a (Δλ, Δφ) offset, the grid shall return a (ΔX, ΔY, ΔZ) offset. - Convert the shifted geocentric coordinate (X+ΔX, Y+ΔY, Z+ΔZ) back to a geographic coordinate.
Source: IGN document
NTG_88.pdf
,
"Grille de paramètres de transformation de coordonnées"
at http://www.ign.fr.
Note however that the signs of (ΔX, ΔY, ΔZ) values expected by this class are the opposite of the
signs used in NTG_88 document. This is because NTG_88 grid defines shifts from target to source,
while this class expects shifts from source to target.
Note: this algorithm is not the same as a (theoretical) EllipsoidToCentricTransform
→
InterpolatedTransform
→ (inverse of EllipsoidToCentricTransform
) concatenation
because the DatumShiftGrid
inputs are geographic coordinates even if the interpolated
grid values are in geocentric space.
Performance consideration
InterpolatedMolodenskyTransform
performs the same calculation more efficiently at the cost of
a few centimetres error. Both classes are instantiated in the same way and expect the same inputs.- Since:
- 0.7
- Version:
- 1.0
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static class
The inverse of the enclosingInterpolatedGeocentricTransform
. -
Field Summary
FieldsModifier and TypeFieldDescription(package private) final AbstractMathTransform
The transform to apply before and after the geocentric translation.(package private) static final org.opengis.parameter.ParameterDescriptorGroup
Parameter descriptor to use with the contextual parameters for the forward transformation.(package private) final AbstractMathTransform
The transform to apply before and after the geocentric translation.private final InterpolatedGeocentricTransform
The inverse of this interpolated geocentric transform.private static final org.opengis.parameter.ParameterDescriptorGroup
Parameter descriptor to use with the contextual parameters for the inverse transformation.(package private) final double
Semi-major axis length of the source ellipsoid divided by semi-major axis length of the target ellipsoid.(package private) final double
Semi-major axis length (a) of the source ellipsoid.private static final long
Serial number for inter-operability with different versions.Fields inherited from class org.apache.sis.referencing.operation.transform.DatumShiftTransform
context, grid
Fields inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform
MAXIMUM_BUFFER_SIZE, MAXIMUM_FAILURES
-
Constructor Summary
ConstructorsModifierConstructorDescription(package private)
InterpolatedGeocentricTransform
(InterpolatedGeocentricTransform inverse, org.opengis.referencing.datum.Ellipsoid source, org.opengis.referencing.datum.Ellipsoid target) Constructs the inverse of an interpolated geocentric transform.private
InterpolatedGeocentricTransform
(org.opengis.referencing.datum.Ellipsoid source, boolean isSource3D, org.opengis.referencing.datum.Ellipsoid target, boolean isTarget3D, DatumShiftGrid<?, ?> grid, InterpolatedGeocentricTransform inverse) Constructor for the forward and inverse transformations.protected
InterpolatedGeocentricTransform
(org.opengis.referencing.datum.Ellipsoid source, boolean isSource3D, org.opengis.referencing.datum.Ellipsoid target, boolean isTarget3D, DatumShiftGrid<javax.measure.quantity.Angle, javax.measure.quantity.Length> grid) Creates a transform from the specified parameters. -
Method Summary
Modifier and TypeMethodDescriptionprivate org.opengis.referencing.operation.MathTransform
completeTransform
(org.opengis.referencing.operation.MathTransformFactory factory, boolean create) Delegates toContextualParameters.completeTransform(MathTransformFactory, MathTransform)
for this transformation and for its dependencies as well.(package private) final org.opengis.referencing.operation.Matrix
concatenate
(org.opengis.referencing.operation.Matrix m1, org.opengis.referencing.operation.Matrix m2) Computes the derivative by concatenating the "geographic to geocentric" and "geocentric to geographic" matrix, with the scale factor between them.static org.opengis.referencing.operation.MathTransform
createGeodeticTransformation
(org.opengis.referencing.operation.MathTransformFactory factory, org.opengis.referencing.datum.Ellipsoid source, boolean isSource3D, org.opengis.referencing.datum.Ellipsoid target, boolean isTarget3D, DatumShiftGrid<javax.measure.quantity.Angle, javax.measure.quantity.Length> grid) Creates a transformation between two geographic CRS.int
Gets the dimension of input points.int
Gets the dimension of output points.org.opengis.referencing.operation.MathTransform
inverse()
Returns the inverse of this interpolated geocentric transform.org.opengis.referencing.operation.Matrix
transform
(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate) Transforms the (λ,φ) or (λ,φ,h) coordinates between two geographic CRS, and optionally returns the derivative at that location.Methods inherited from class org.apache.sis.referencing.operation.transform.DatumShiftTransform
computeHashCode, ensureGeocentricTranslation, equals, getContextualParameters, getParameterValues, normalizedToGridX, normalizedToGridY, setContextParameters
Methods inherited from class org.apache.sis.referencing.operation.transform.AbstractMathTransform
beforeFormat, derivative, equals, formatTo, getDomain, getParameterDescriptors, hashCode, isIdentity, isInverseEquals, mismatchedDimension, transform, transform, transform, transform, transform, tryConcatenate
Methods inherited from class org.apache.sis.io.wkt.FormattableObject
print, toString, toString, toWKT
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface org.opengis.referencing.operation.MathTransform
toWKT
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDSerial number for inter-operability with different versions.- See Also:
-
DESCRIPTOR
static final org.opengis.parameter.ParameterDescriptorGroup DESCRIPTORParameter descriptor to use with the contextual parameters for the forward transformation. We do not use the "France geocentric interpolation" (ESPG:9655) descriptor because their "forward" transformation is our "inverse" transformation, and conversely. TheDESCRIPTOR
defined here is non-standard, but allows this class to be used for other geographic areas than France. -
INVERSE
private static final org.opengis.parameter.ParameterDescriptorGroup INVERSEParameter descriptor to use with the contextual parameters for the inverse transformation. We do not use the "France geocentric interpolation" (ESPG:9655) descriptor because it is specific to a single country, has hard-coded parameters and uses a sign convention for (ΔX,ΔY,ΔZ) translations different than the one used in this class. TheINVERSE
descriptor defined here is non-standard, but allows this class to be used for other geographic areas than France. -
semiMajor
final double semiMajorSemi-major axis length (a) of the source ellipsoid. -
scale
final double scaleSemi-major axis length of the source ellipsoid divided by semi-major axis length of the target ellipsoid. Used for converting normalized coordinates between the two geocentric coordinate reference systems.This is a dimensionless quantity: the ellipsoid axis lengths must have been converted to the same unit before to compute this ratio.
-
ellipsoidToCentric
The transform to apply before and after the geocentric translation. Shall be instance ofEllipsoidToCentricTransform
andEllipsoidToCentricTransform.Inverse
respectively. -
centricToEllipsoid
The transform to apply before and after the geocentric translation. Shall be instance ofEllipsoidToCentricTransform
andEllipsoidToCentricTransform.Inverse
respectively. -
inverse
The inverse of this interpolated geocentric transform.- See Also:
-
-
Constructor Details
-
InterpolatedGeocentricTransform
InterpolatedGeocentricTransform(InterpolatedGeocentricTransform inverse, org.opengis.referencing.datum.Ellipsoid source, org.opengis.referencing.datum.Ellipsoid target) Constructs the inverse of an interpolated geocentric transform.- Parameters:
inverse
- the transform for which to create the inverse.source
- the source ellipsoid of the giveninverse
transform.target
- the target ellipsoid of the giveninverse
transform.
-
InterpolatedGeocentricTransform
protected InterpolatedGeocentricTransform(org.opengis.referencing.datum.Ellipsoid source, boolean isSource3D, org.opengis.referencing.datum.Ellipsoid target, boolean isTarget3D, DatumShiftGrid<javax.measure.quantity.Angle, javax.measure.quantity.Length> grid) Creates a transform from the specified parameters. ThisInterpolatedGeocentricTransform
class expects coordinate values in the following order and units:- longitudes in radians relative to the prime meridian (usually Greenwich),
- latitudes in radians,
- optionally heights above the ellipsoid, in same units than the source ellipsoid axes.
InterpolatedGeocentricTransform
instances need to be concatenated with the following affine transforms:- Normalization before
InterpolatedGeocentricTransform
:- Conversion of (λ,φ) from degrees to radians.
- Denormalization after
InterpolatedGeocentricTransform
:- Conversion of (λ,φ) from radians to degrees.
InterpolatedGeocentricTransform
construction, the full conversion chain including the above affine transforms can be created byDatumShiftTransform.getContextualParameters().completeTransform(factory, this)}
.- Parameters:
source
- the source ellipsoid.isSource3D
-true
if the source coordinates have a height.target
- the target ellipsoid.isTarget3D
-true
if the target coordinates have a height.grid
- the grid of datum shifts from source to target datum. TheDatumShiftGrid.interpolateInCell(…)
method shall compute (ΔX, ΔY, ΔZ) translations from source to target in the unit of source ellipsoid axes.- See Also:
-
InterpolatedGeocentricTransform
private InterpolatedGeocentricTransform(org.opengis.referencing.datum.Ellipsoid source, boolean isSource3D, org.opengis.referencing.datum.Ellipsoid target, boolean isTarget3D, DatumShiftGrid<?, ?> grid, InterpolatedGeocentricTransform inverse) Constructor for the forward and inverse transformations. Ifinverse
isnull
, then this constructor creates the forward transformation. Otherwise this constructor creates the inverse of the giveninverse
transformation.
-
-
Method Details
-
completeTransform
private org.opengis.referencing.operation.MathTransform completeTransform(org.opengis.referencing.operation.MathTransformFactory factory, boolean create) throws org.opengis.util.FactoryException Delegates toContextualParameters.completeTransform(MathTransformFactory, MathTransform)
for this transformation and for its dependencies as well.- Throws:
org.opengis.util.FactoryException
-
createGeodeticTransformation
public static org.opengis.referencing.operation.MathTransform createGeodeticTransformation(org.opengis.referencing.operation.MathTransformFactory factory, org.opengis.referencing.datum.Ellipsoid source, boolean isSource3D, org.opengis.referencing.datum.Ellipsoid target, boolean isTarget3D, DatumShiftGrid<javax.measure.quantity.Angle, javax.measure.quantity.Length> grid) throws org.opengis.util.FactoryExceptionCreates a transformation between two geographic CRS. This factory method combines theInterpolatedGeocentricTransform
instance with the steps needed for converting values between degrees to radians. The transform works with input and output coordinates in the following units:- longitudes in degrees relative to the prime meridian (usually Greenwich),
- latitudes in degrees,
- optionally heights above the ellipsoid, in same units than the source ellipsoids axes.
grid
instance shall expect geographic coordinates (λ,φ) in radians.- Parameters:
factory
- the factory to use for creating the transform.source
- the source ellipsoid.isSource3D
-true
if the source coordinates have a height.target
- the target ellipsoid.isTarget3D
-true
if the target coordinates have a height.grid
- the grid of datum shifts from source to target datum. TheDatumShiftGrid.interpolateInCell(…)
method shall compute (ΔX, ΔY, ΔZ) translations from source to target in the unit of source ellipsoid axes.- Returns:
- the transformation between geographic coordinates in degrees.
- Throws:
org.opengis.util.FactoryException
- if an error occurred while creating a transform.
-
getSourceDimensions
public int getSourceDimensions()Gets the dimension of input points.- Specified by:
getSourceDimensions
in interfaceorg.opengis.referencing.operation.MathTransform
- Specified by:
getSourceDimensions
in classAbstractMathTransform
- Returns:
- the input dimension, which is 2 or 3.
- See Also:
-
getTargetDimensions
public int getTargetDimensions()Gets the dimension of output points.- Specified by:
getTargetDimensions
in interfaceorg.opengis.referencing.operation.MathTransform
- Specified by:
getTargetDimensions
in classAbstractMathTransform
- Returns:
- the output dimension, which is 2 or 3.
- See Also:
-
transform
public org.opengis.referencing.operation.Matrix transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, boolean derivate) throws org.opengis.referencing.operation.TransformException Transforms the (λ,φ) or (λ,φ,h) coordinates between two geographic CRS, and optionally returns the derivative at that location.- Specified by:
transform
in classAbstractMathTransform
- Parameters:
srcPts
- the array containing the source coordinates (cannot benull
).srcOff
- the offset to the point to be transformed in the source array.dstPts
- the array into which the transformed coordinates is returned. May be the same thansrcPts
. May benull
if only the derivative matrix is desired.dstOff
- the offset to the location of the transformed point that is stored in the destination array.derivate
-true
for computing the derivative, orfalse
if not needed.- Returns:
- the matrix of the transform derivative at the given source position,
or
null
if thederivate
argument isfalse
. - Throws:
org.opengis.referencing.operation.TransformException
- if the point cannot be transformed or if a problem occurred while calculating the derivative.- See Also:
-
concatenate
final org.opengis.referencing.operation.Matrix concatenate(org.opengis.referencing.operation.Matrix m1, org.opengis.referencing.operation.Matrix m2) Computes the derivative by concatenating the "geographic to geocentric" and "geocentric to geographic" matrix, with the scale factor between them.Note: we could improve a little bit the precision by computing the derivative in the interpolation grid: But this is a little bit complicated (need to convert to normalized units and divide by the grid cell size) for a very small difference. For now we neglect that part.- Parameters:
m1
- the derivative computed by the "geographic to geocentric" conversion.m2
- the derivative computed by the "geocentric to geographic" conversion.- Returns:
- the derivative for the "interpolated geocentric" transformation.
-
inverse
public org.opengis.referencing.operation.MathTransform inverse()Returns the inverse of this interpolated geocentric transform. The source ellipsoid of the returned transform will be the target ellipsoid of this transform, and conversely.- Specified by:
inverse
in interfaceorg.opengis.referencing.operation.MathTransform
- Overrides:
inverse
in classAbstractMathTransform
- Returns:
- a transform from the target ellipsoid to the source ellipsoid of this transform.
-