Class CoordinateOperationFinder
- All Implemented Interfaces:
Supplier<double[]>
CRS#findOperation(…)
because of the gridded aspect of inputs.
grid geometries give more information about how referencing is applied on datasets.
With them, this class provides three additional benefits:
- Detect dimensions where target coordinates are constrained to constant values because the grid size is only one cell in those dimensions. This is an important because it makes possible to find operations normally impossible: we can still produce an operation to a target CRS even if some dimensions have no corresponding source CRS.
- Detect how to handle wraparound axes. For example if a raster spans 150° to 200° of longitude, this class understands that -170° of longitude should be translated to 190° for thar particular raster. This will work even if the minimum and maximum values declared in the longitude axis do not match that range.
- Use the area of interest and grid resolution for refining the coordinate operation between two CRS.
gridToGrid()
convenience method,
this class does not provide the complete chain of operations from grid to grid.
It provides only the operation from cell indices in source grid to coordinates in the CRS
of destination grid. Callers must add the last step (conversion from target CRS to cell indices) themselves.- Since:
- 1.1
- Version:
- 1.2
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate org.opengis.referencing.datum.PixelInCell
Whether the operation is between cell centers or cell corners.private org.opengis.referencing.operation.CoordinateOperation
The coordinate operation from source to target CRS, computed when first needed.private double[]
The target coordinate values, computed only if needed.private org.opengis.referencing.operation.MathTransform
Transform from the target CRS to the source grid, withWraparoundTransform
applied if needed.private org.opengis.referencing.operation.MathTransform
ThechangeOfCRS
transform together withWraparoundTransform
if needed.private org.opengis.referencing.operation.MathTransform
Transform from “grid coordinates of the source” to “geospatial coordinates of the target”.private org.opengis.referencing.operation.MathTransform
Inverse ofchangeOfCRS
transform together withWraparoundTransform
if needed.private boolean
WhetherWraparoundTransform
has been applied oninverseChangeOfCRS
.private boolean
Whether to disable completely all wraparounds checks.private boolean
WhetherinverseChangeOfCRS
needs to include aWraparoundTransform
step.private boolean
Whether theisWraparoundNeeded
value has been determined.private boolean
Whether thechangeOfCRS
operation has been determined.private final GridGeometry
The grid geometry which is the source/target of the coordinate operation to find.private final GridGeometry
The grid geometry which is the source/target of the coordinate operation to find. -
Constructor Summary
ConstructorsConstructorDescriptionCoordinateOperationFinder
(GridGeometry source, GridGeometry target) Creates a new finder initialized toPixelInCell.CELL_CORNER
anchor. -
Method Summary
Modifier and TypeMethodDescriptionprivate boolean
applyWraparound
(org.opengis.referencing.operation.MathTransform sourceCrsToGrid) InsertsWraparoundTransform
steps intoinverseChangeOfCRS
transform if possible.private org.opengis.referencing.operation.CoordinateOperation
Returns the coordinate operation from source CRS to target CRS.double[]
get()
Invoked when the target CRS has some dimensions that the source CRS does not have.(package private) final org.opengis.referencing.crs.CoordinateReferenceSystem
Returns the target of the "corner to CRS" transform.(package private) final org.opengis.referencing.operation.MathTransform
Computes the transform from “grid coordinates of the source” to “geospatial coordinates of the target”.(package private) final org.opengis.referencing.operation.MathTransform
Computes the transform from “grid coordinates of the source” to “grid coordinates of the target”.(package private) final org.opengis.referencing.operation.MathTransform
inverse()
Computes the transform from “geospatial coordinates of the target” to “grid coordinates of the source”.private boolean
isWraparoundNeeded
(GridExtent extent, org.opengis.referencing.operation.MathTransform extentToCRS, org.opengis.referencing.operation.MathTransform crsToGridNoWrap, org.opengis.referencing.operation.MathTransform sourceCrsToGrid) Verifies whether wraparound is needed for a "CRS to grid" transform.private static org.opengis.geometry.DirectPosition
median
(GridGeometry grid, org.opengis.referencing.operation.MathTransform changeOfCRS) Returns the point of interest converted to the Coordinate Reference System.(package private) final void
Disables completely all wraparounds operation.private static void
recoverableException
(String caller, Exception e) Invoked when an ignorable exception occurred.(package private) final void
setAccuracyOf
(ImageProcessor processor) Configures the accuracy hints on the given processor.(package private) final void
setAnchor
(org.opengis.referencing.datum.PixelInCell newValue) Sets whether operations will be between cell centers or cell corners.(package private) final void
verifyPresenceOfCRS
(boolean rs) Verifies whether the presence of a CRS considered mandatory, unless the CRS of opposite grid is also missing.
-
Field Details
-
anchor
private org.opengis.referencing.datum.PixelInCell anchorWhether the operation is between cell centers or cell corners.- See Also:
-
source
The grid geometry which is the source/target of the coordinate operation to find. -
target
The grid geometry which is the source/target of the coordinate operation to find. -
coordinates
private double[] coordinatesThe target coordinate values, computed only if needed. This is computed byget()
, which is itself invoked indirectly byCoordinateOperationFinder
. The value is cached in caseget()
is invoked many times during the same finder execution.- See Also:
-
changeOfCRS
private org.opengis.referencing.operation.CoordinateOperation changeOfCRSThe coordinate operation from source to target CRS, computed when first needed. May benull
if there is no information about the source and target CRS. Note that identity operation is not equivalent tonull
because identity operation will still be checked for wraparound axes (because the CRS is known), while null operation will have no check.- See Also:
-
knowChangeOfCRS
private boolean knowChangeOfCRSWhether thechangeOfCRS
operation has been determined. Note that result of determining that operation may benull
, which is why we need this flag. -
forwardChangeOfCRS
private org.opengis.referencing.operation.MathTransform forwardChangeOfCRSThechangeOfCRS
transform together withWraparoundTransform
if needed. The wraparound is used for handling images crossing the anti-meridian.- See Also:
-
inverseChangeOfCRS
private org.opengis.referencing.operation.MathTransform inverseChangeOfCRSInverse ofchangeOfCRS
transform together withWraparoundTransform
if needed. The wraparound is used for handling images crossing the anti-meridian.Contrarily to
forwardChangeOfCRS
, the process that determine thisinverseChangeOfCRS
transform should check if wraparound is really needed. This is becauseinverseChangeOfCRS
will be used much more extensively (for every pixels) than other transforms.- See Also:
-
gridToCRS
private org.opengis.referencing.operation.MathTransform gridToCRSTransform from “grid coordinates of the source” to “geospatial coordinates of the target”. This is the concatenation ofsource
"grid to CRS" withforwardChangeOfCRS
, possibly with wraparound handling and cached for reuse byinverse()
:- See Also:
-
crsToGrid
private org.opengis.referencing.operation.MathTransform crsToGridTransform from the target CRS to the source grid, withWraparoundTransform
applied if needed. This is the concatenation ofinverseChangeOfCRS
with inverse ofsource
"grid to CRS", possibly with wraparound handling:- See Also:
-
isWraparoundNeedVerified
private boolean isWraparoundNeedVerifiedWhether theisWraparoundNeeded
value has been determined. This flag controls whether to perform a more extensive check of wraparound occurrence. This flag should befalse
the first time thatinverse()
is invoked andtrue
the next time. -
isWraparoundNeeded
private boolean isWraparoundNeededWhetherinverseChangeOfCRS
needs to include aWraparoundTransform
step. We do this check only forinverseChangeOfCRS
because it is the transform which will be executed for every pixels. By contrast,forwardChangeOfCRS
will systematically contain aWraparoundTransform
step because we use it only for transforming envelopes and for the test that determines the value of thisisWraparoundNeeded
flag. -
isWraparoundApplied
private boolean isWraparoundAppliedWhetherWraparoundTransform
has been applied oninverseChangeOfCRS
. This field complementsisWraparoundNeeded
because a delay may exist between the time we detected that wraparound is needed and the time we applied the necessary operation steps.Note that despite this field name, a
true
value does not imply thatinverseChangeOfCRS
andcrsToGrid
transforms really contain someWraparoundTransform
steps. It only means that theWraparoundApplicator.forDomainOfUse(…)
method has been invoked. That method may have decided to not insert any wraparound steps.- See Also:
-
isWraparoundDisabled
private boolean isWraparoundDisabledWhether to disable completely all wraparounds checks. Iftrue
, then calculation done in this class should be equivalent to following code: Tip: searching usage of this field should help to identify code doing wraparound handling.- See Also:
-
-
Constructor Details
-
CoordinateOperationFinder
CoordinateOperationFinder(GridGeometry source, GridGeometry target) Creates a new finder initialized toPixelInCell.CELL_CORNER
anchor.- Parameters:
source
- the grid geometry which is the source of the coordinate operation to find.target
- the grid geometry which is the target of the coordinate operation to find.
-
-
Method Details
-
verifyPresenceOfCRS
final void verifyPresenceOfCRS(boolean rs) Verifies whether the presence of a CRS considered mandatory, unless the CRS of opposite grid is also missing.- Parameters:
rs
-true
is source CRS is mandatory,false
if target CRS is mandatory.
-
setAnchor
final void setAnchor(org.opengis.referencing.datum.PixelInCell newValue) Sets whether operations will be between cell centers or cell corners. This method must be invoked before any other method in this class. ThePixelInCell.CELL_CORNER
value should be used first in order to cache values computed relative to pixel corners.- Parameters:
newValue
- whether operations will be between cell centers or cell corners.
-
nowraparound
final void nowraparound()Disables completely all wraparounds operation.- See Also:
-
getTargetCRS
final org.opengis.referencing.crs.CoordinateReferenceSystem getTargetCRS()Returns the target of the "corner to CRS" transform. May benull
if the neither the source and target grid geometry define a CRS. -
changeOfCRS
private org.opengis.referencing.operation.CoordinateOperation changeOfCRS() throws org.opengis.util.FactoryException, org.opengis.referencing.operation.TransformExceptionReturns the coordinate operation from source CRS to target CRS. It may be the identity operation. We try to take envelopes in account because the operation choice may depend on the geographic area.- Returns:
- operation from source CRS to target CRS, or
null
if a CRS is not specified. - Throws:
org.opengis.util.FactoryException
- if no operation can be found between the source and target CRS.org.opengis.referencing.operation.TransformException
- if some coordinates cannot be transformed to the specified target.
-
gridToGrid
final org.opengis.referencing.operation.MathTransform gridToGrid() throws org.opengis.util.FactoryException, org.opengis.referencing.operation.TransformExceptionComputes the transform from “grid coordinates of the source” to “grid coordinates of the target”. This is a concatenation ofgridToCRS()
with target "CRS to grid" transform.- Returns:
- operation from source grid indices to target grid indices.
- Throws:
org.opengis.util.FactoryException
- if no operation can be found between the source and target CRS.org.opengis.referencing.operation.TransformException
- if some coordinates cannot be transformed to the specified target.IncompleteGridGeometryException
- if required CRS or a "grid to CRS" information is missing.
-
gridToCRS
final org.opengis.referencing.operation.MathTransform gridToCRS() throws org.opengis.util.FactoryException, org.opengis.referencing.operation.TransformExceptionComputes the transform from “grid coordinates of the source” to “geospatial coordinates of the target”. It may be the identity operation. We try to take envelopes in account because the operation choice may depend on the geographic area.The transform returned by this method applies wraparound checks systematically on every axes having wraparound range. This method does not verify whether those checks are needed (i.e. whether wraparound can possibly happen). This is okay because this transform is used only for transforming envelopes; it is not used for transforming pixel coordinates.
Implementation note
After invocation of this method, the following fields are valid:changeOfCRS
— cached forinverse()
usage.forwardChangeOfCRS
— cached for next invocation of thisgridToCRS()
method.
- Returns:
- operation from source grid indices to target geospatial coordinates.
- Throws:
org.opengis.util.FactoryException
- if no operation can be found between the source and target CRS.org.opengis.referencing.operation.TransformException
- if some coordinates cannot be transformed to the specified target.IncompleteGridGeometryException
- if required CRS or a "grid to CRS" information is missing.
-
inverse
final org.opengis.referencing.operation.MathTransform inverse() throws org.opengis.util.FactoryException, org.opengis.referencing.operation.TransformExceptionComputes the transform from “geospatial coordinates of the target” to “grid coordinates of the source”. This is similar to invokingMathTransform.inverse()
ongridToCRS()
, except in the way wraparounds are handled.- Returns:
- operation from target geospatial coordinates to source grid indices.
- Throws:
org.opengis.util.FactoryException
- if no operation can be found between the source and target CRS.org.opengis.referencing.operation.TransformException
- if some coordinates cannot be transformed.
-
isWraparoundNeeded
private boolean isWraparoundNeeded(GridExtent extent, org.opengis.referencing.operation.MathTransform extentToCRS, org.opengis.referencing.operation.MathTransform crsToGridNoWrap, org.opengis.referencing.operation.MathTransform sourceCrsToGrid) throws org.opengis.util.FactoryException, org.opengis.referencing.operation.TransformException Verifies whether wraparound is needed for a "CRS to grid" transform. This method converts coordinates of all corners of a grid (source or target) to the target CRS, then (potentially back) to the source grid. This method uses one transform applying wraparounds and another transform without wraparounds. By checking whether grid coordinates are equal with both transforms, we determine if wraparound is necessary or not.- Parameters:
extent
- the grid extent which is providing all corners to project.extentToCRS
- transform fromextent
to target CRS.crsToGridNoWrap
- inverse ofgridToCRS
but without handling of wraparound axes.sourceCrsToGrid
- ifextent
istarget
extent, shall benull
. Ifextent
issource
extent, shall be the transform to concatenate withinverseChangeOfCRS
for creatingcrsToGrid
.- Returns:
- whether wraparound transform seems needed.
- Throws:
org.opengis.referencing.operation.TransformException
- if an error occurred while transforming coordinates.org.opengis.util.FactoryException
-
applyWraparound
private boolean applyWraparound(org.opengis.referencing.operation.MathTransform sourceCrsToGrid) throws org.opengis.util.FactoryException, org.opengis.referencing.operation.TransformException InsertsWraparoundTransform
steps intoinverseChangeOfCRS
transform if possible. IF this method returnstrue
, then theinverseChangeOfCRS
andcrsToGrid
fields have been updated to transforms applying wraparound.- Parameters:
sourceCrsToGrid
- value ofsource.getGridToCRS(anchor).inverse()
.- Returns:
- whether at least one wraparound step has been added.
- Throws:
org.opengis.referencing.operation.TransformException
- if some coordinates cannot be transformed.org.opengis.util.FactoryException
-
median
private static org.opengis.geometry.DirectPosition median(GridGeometry grid, org.opengis.referencing.operation.MathTransform changeOfCRS) throws org.opengis.referencing.operation.TransformException Returns the point of interest converted to the Coordinate Reference System. If the grid does not define a point of interest or does not define a CRS, then this method returnsnull
.- Parameters:
grid
- the source or target grid providing the point of interest.changeOfCRS
- transform from source CRS to target CRS, ornull
if none.- Throws:
org.opengis.referencing.operation.TransformException
-
get
public double[] get()Invoked when the target CRS has some dimensions that the source CRS does not have. For example, this is invoked during the conversion from (x, y) coordinates to (x, y, t). If constant values can be given to the missing dimensions, than those values are returned. Otherwise this method returnsnull
.The returned array has a length equals to the number of dimensions in the target CRS. Only coordinates in dimensions without source (t in above example) will be used. All other coordinate values will be ignored.
-
setAccuracyOf
Configures the accuracy hints on the given processor.Prerequisite
This method assumes thatgridToCRS()
orinverse()
has already been invoked before this method. -
recoverableException
Invoked when an ignorable exception occurred.- Parameters:
caller
- the method where the exception occurred.e
- the ignorable exception.
-