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.PixelInCellWhether the operation is between cell centers or cell corners.private org.opengis.referencing.operation.CoordinateOperationThe 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.MathTransformTransform from the target CRS to the source grid, withWraparoundTransformapplied if needed.private org.opengis.referencing.operation.MathTransformThechangeOfCRStransform together withWraparoundTransformif needed.private org.opengis.referencing.operation.MathTransformTransform from “grid coordinates of the source” to “geospatial coordinates of the target”.private org.opengis.referencing.operation.MathTransformInverse ofchangeOfCRStransform together withWraparoundTransformif needed.private booleanWhetherWraparoundTransformhas been applied oninverseChangeOfCRS.private booleanWhether to disable completely all wraparounds checks.private booleanWhetherinverseChangeOfCRSneeds to include aWraparoundTransformstep.private booleanWhether theisWraparoundNeededvalue has been determined.private booleanWhether thechangeOfCRSoperation has been determined.private final GridGeometryThe grid geometry which is the source/target of the coordinate operation to find.private final GridGeometryThe 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_CORNERanchor. -
Method Summary
Modifier and TypeMethodDescriptionprivate booleanapplyWraparound(org.opengis.referencing.operation.MathTransform sourceCrsToGrid) InsertsWraparoundTransformsteps intoinverseChangeOfCRStransform if possible.private org.opengis.referencing.operation.CoordinateOperationReturns 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.CoordinateReferenceSystemReturns the target of the "corner to CRS" transform.(package private) final org.opengis.referencing.operation.MathTransformComputes the transform from “grid coordinates of the source” to “geospatial coordinates of the target”.(package private) final org.opengis.referencing.operation.MathTransformComputes the transform from “grid coordinates of the source” to “grid coordinates of the target”.(package private) final org.opengis.referencing.operation.MathTransforminverse()Computes the transform from “geospatial coordinates of the target” to “grid coordinates of the source”.private booleanisWraparoundNeeded(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.DirectPositionmedian(GridGeometry grid, org.opengis.referencing.operation.MathTransform changeOfCRS) Returns the point of interest converted to the Coordinate Reference System.(package private) final voidDisables completely all wraparounds operation.private static voidrecoverableException(String caller, Exception e) Invoked when an ignorable exception occurred.(package private) final voidsetAccuracyOf(ImageProcessor processor) Configures the accuracy hints on the given processor.(package private) final voidsetAnchor(org.opengis.referencing.datum.PixelInCell newValue) Sets whether operations will be between cell centers or cell corners.(package private) final voidverifyPresenceOfCRS(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 benullif there is no information about the source and target CRS. Note that identity operation is not equivalent tonullbecause 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 thechangeOfCRSoperation 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 forwardChangeOfCRSThechangeOfCRStransform together withWraparoundTransformif needed. The wraparound is used for handling images crossing the anti-meridian.- See Also:
-
inverseChangeOfCRS
private org.opengis.referencing.operation.MathTransform inverseChangeOfCRSInverse ofchangeOfCRStransform together withWraparoundTransformif needed. The wraparound is used for handling images crossing the anti-meridian.Contrarily to
forwardChangeOfCRS, the process that determine thisinverseChangeOfCRStransform should check if wraparound is really needed. This is becauseinverseChangeOfCRSwill 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, withWraparoundTransformapplied if needed. This is the concatenation ofinverseChangeOfCRSwith inverse ofsource"grid to CRS", possibly with wraparound handling:- See Also:
-
isWraparoundNeedVerified
private boolean isWraparoundNeedVerifiedWhether theisWraparoundNeededvalue has been determined. This flag controls whether to perform a more extensive check of wraparound occurrence. This flag should befalsethe first time thatinverse()is invoked andtruethe next time. -
isWraparoundNeeded
private boolean isWraparoundNeededWhetherinverseChangeOfCRSneeds to include aWraparoundTransformstep. We do this check only forinverseChangeOfCRSbecause it is the transform which will be executed for every pixels. By contrast,forwardChangeOfCRSwill systematically contain aWraparoundTransformstep because we use it only for transforming envelopes and for the test that determines the value of thisisWraparoundNeededflag. -
isWraparoundApplied
private boolean isWraparoundAppliedWhetherWraparoundTransformhas been applied oninverseChangeOfCRS. This field complementsisWraparoundNeededbecause 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
truevalue does not imply thatinverseChangeOfCRSandcrsToGridtransforms really contain someWraparoundTransformsteps. 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_CORNERanchor.- 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-trueis source CRS is mandatory,falseif 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_CORNERvalue 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 benullif 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
nullif 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 fromextentto target CRS.crsToGridNoWrap- inverse ofgridToCRSbut without handling of wraparound axes.sourceCrsToGrid- ifextentistargetextent, shall benull. Ifextentissourceextent, shall be the transform to concatenate withinverseChangeOfCRSfor 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 InsertsWraparoundTransformsteps intoinverseChangeOfCRStransform if possible. IF this method returnstrue, then theinverseChangeOfCRSandcrsToGridfields 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, ornullif 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.
-