Class DatumShiftGridFile<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>

java.lang.Object
org.apache.sis.referencing.datum.DatumShiftGrid<C,T>
org.apache.sis.internal.referencing.provider.DatumShiftGridFile<C,T>
Type Parameters:
C - dimension of the coordinate unit (usually Angle).
T - dimension of the translation unit. Usually Angle, but can also be Length.
All Implemented Interfaces:
Serializable
Direct Known Subclasses:
DatumShiftGridCompressed, DatumShiftGridFile.Double, DatumShiftGridFile.Float, DatumShiftGridGroup

abstract class DatumShiftGridFile<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>> extends DatumShiftGrid<C,T>
A datum shift grid loaded from a file. The filename is usually a parameter defined in the EPSG database. This class should not be in public API because it requires implementation to expose internal mechanic: Subclasses need to give an access to their internal data (not a copy) through the getData() and setData(Object[]) methods. We use that for managing the cache, reducing memory usage by sharing data and for equals(Object) and hashCode() implementations.
Since:
0.7
Version:
1.1
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      Serial number for inter-operability with different versions.
      See Also:
    • CACHE

      static final Cache<Object,DatumShiftGridFile<?,?>> CACHE
      Cache of grids loaded so far. The keys are typically Paths or a tuple of paths. Values are grids stored by hard references until the amount of data exceed 32768 (about 128 kilobytes if the values use the float type), in which case the oldest grids will be replaced by soft references.

      Memory consumption

      The use of soft references instead of weak references is on the assumption that users typically use the same few Coordinate Reference Systems for their work. Consequently, we presume that users will not load a lot of grids and are likely to reuse the already loaded grids.
    • descriptor

      private final org.opengis.parameter.ParameterDescriptorGroup descriptor
      The parameter descriptor of the provider that created this grid.
    • files

      private final Path[] files
      The files from which the grid has been loaded. This is not used directly by this class (except for equals(Object) and hashCode()), but can be used by math transform for setting the parameter values. Shall never be null and never empty.
    • scanlineStride

      protected final int scanlineStride
      Number of cells between the start of adjacent rows in the grid. This is usually getGridSize(0), stored as a field for performance reasons. Value could be greater than getGridSize(0) if there is some elements to ignore at the end of each row.
    • periodX

      private final double periodX
      Number of cells that the grid would have if it was spanning 360° of longitude, or 0 if no wraparound should be applied. Current implementation rounds to nearest integer on the assumption that we expect an integer number of cells in 360°. This value is used for longitude values that are on the other side of the ±180° meridian compared to the region where the grid is defined.
      See Also:
    • accuracy

      double accuracy
      The best translation accuracy that we can expect from this file. The unit of measurement depends on DatumShiftGrid.isCellValueRatio().

      This field is initialized to zero. It is loader responsibility to assign a value to this field after DatumShiftGridFile construction.

      See Also:
    • subgrids

      protected DatumShiftGridFile<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>[] subgrids
      The sub-grids, or null if none. The domain of validity of each sub-grid should be contained in the domain of validity of this grid. Children do not change the way this DatumShiftGrid performs its calculation; this list is used only at the time of building MathTransform tree.
      Design note: we do not provide sub-grids functionality in the DatumShiftGrid parent class because the MathTransform tree will depend on assumptions about DatumShiftGrid.getCoordinateToGrid(), in particular that it contains only translations and scales (no rotation, no shear). Those assumptions are enforced by the DatumShiftGridFile constructor.
      This field has protected access for usage by DatumShiftGridGroup subclass only. No access to this field should be done except by subclasses.
      See Also:
  • Constructor Details

    • DatumShiftGridFile

      DatumShiftGridFile(javax.measure.Unit<C> coordinateUnit, javax.measure.Unit<T> translationUnit, boolean isCellValueRatio, double x0, double y0, double Δx, double Δy, int nx, int ny, org.opengis.parameter.ParameterDescriptorGroup descriptor, Path... files) throws org.opengis.referencing.operation.NoninvertibleTransformException
      Creates a new datum shift grid for the given grid geometry. The actual offset values need to be provided by subclasses.
      Parameters:
      coordinateUnit - the unit of measurement of input values, before conversion to grid indices by coordinateToGrid.
      translationUnit - the unit of measurement of output values.
      isCellValueRatio - true if results of interpolateInCell(…) are divided by grid cell size.
      x0 - longitude in degrees of the center of the cell at grid index (0,0), positive east.
      y0 - latitude in degrees of the center of the cell at grid index (0,0), positive north.
      Δx - increment in x value between cells at index gridX and gridX + 1.
      Δy - increment in y value between cells at index gridY and gridY + 1.
      nx - number of cells along the x axis in the grid.
      ny - number of cells along the y axis in the grid.
      descriptor - the parameter descriptor of the provider that created this grid.
      files - the file(s) from which the grid has been loaded. This array is not cloned.
      Throws:
      org.opengis.referencing.operation.NoninvertibleTransformException
    • DatumShiftGridFile

      protected DatumShiftGridFile(DatumShiftGridFile<C,T> other)
      Creates a new datum shift grid with the same grid geometry than the given grid. This is used by DatumShiftGridCompressed for replacing a grid by another one.
      Parameters:
      other - the other datum shift grid from which to copy the grid geometry.
    • DatumShiftGridFile

      DatumShiftGridFile(DatumShiftGridFile<C,T> other, AffineTransform2D gridToCRS, int nx, int ny) throws org.opengis.referencing.operation.NoninvertibleTransformException
      Creates a new datum shift grid with the same configuration than the given grid, except the size and transform which are set to the given values. This is used for creating a DatumShiftGridGroup containing many grids, using one grid as a template for setting parameter values. The accuracy is initialized to zero and should be updated by the caller.
      Parameters:
      other - the other datum shift grid from which to copy parameters.
      gridToCRS - conversion from grid indices to "real world" coordinates.
      nx - number of cells along the x axis in the grid.
      ny - number of cells along the y axis in the grid.
      Throws:
      org.opengis.referencing.operation.NoninvertibleTransformException
  • Method Details

    • setSubGrids

      final void setSubGrids(Collection<DatumShiftGridFile<C,T>> children)
      Sets the sub-grids that are direct children of this grid. This method can be invoked only once.
    • getGridCount

      private int getGridCount()
      Returns the number of grids, including this grid and all sub-grids counted recursively. This is used for information purpose only.
      See Also:
    • toString

      public final String toString()
      Returns a string representation of this grid for debugging purpose. If this grid has children, then it will be formatted as a tree.
      Overrides:
      toString in class DatumShiftGrid<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>
      Returns:
      a string representation of this datum shift grid.
    • toTree

      private void toTree(TreeTable.Node branch)
      Formats this grid as a tree with its children.
    • castTo

      final <NC extends javax.measure.Quantity<NC>, NT extends javax.measure.Quantity<NT>> DatumShiftGridFile<NC,NT> castTo(Class<NC> coordinateType, Class<NT> translationType)
      Returns this casted to the given type, after verification that those types are valid. This method is invoked after NADCON, NTv2 or other providers got an existing DatumShiftGridFile instance from the CACHE.
    • useSharedData

      protected final DatumShiftGridFile<C,T> useSharedData()
      If a grid exists in the cache for the same data, returns a new grid sharing the same data arrays. Otherwise returns this.
      Returns:
      a grid using the same data than this grid, or this.
      See Also:
    • setData

      protected abstract DatumShiftGridFile<C,T> setData(Object[] other)
      Returns a new grid with the same geometry than this grid but different data arrays. This method is invoked by useSharedData() when it detected that a newly created grid uses the same data than an existing grid. The typical use case is when a filename is different but still reference the same grid (e.g. symbolic link, lower case versus upper case in a case-insensitive file system).
      Parameters:
      other - data from another DatumShiftGridFile that we can share.
      Returns:
      a new DatumShiftGridFile using the given data reference.
    • getData

      protected abstract Object[] getData()
      Returns the data for each shift dimensions. This method is for cache management, equals(Object) and hashCode() implementations only and should not be invoked in other context.
      Returns:
      a direct (not cloned) reference to the internal data array.
    • equals

      public boolean equals(Object other)
      Returns true if the given object is a grid containing the same data than this grid. This method compares the data provided by getData().
      Overrides:
      equals in class DatumShiftGrid<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>
      Parameters:
      other - the other object to compare with this datum shift grid.
      Returns:
      true if the given object is non-null, of the same class than this DatumShiftGrid and contains the same data.
    • hashCode

      public int hashCode()
      Returns a hash code value for this datum shift grid. The hash code is based on metadata such as filename, but not on getData() for performance reason.
      Overrides:
      hashCode in class DatumShiftGrid<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>
      Returns:
      a hash code based on metadata.
    • getCellPrecision

      public double getCellPrecision()
      Suggests a precision for the translation values in this grid. This information is used for deciding when to stop iterations in inverse transformations. The default implementation returns the accuracy divided by an arbitrary value.
      Specified by:
      getCellPrecision in class DatumShiftGrid<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>
      Returns:
      a precision for the translation values in this grid.
    • replaceOutsideGridCoordinates

      protected void replaceOutsideGridCoordinates(double[] gridCoordinates)
      Invoked when a gridX or gridY coordinate is outside the range of valid grid coordinates. If the coordinate outside the range is a longitude value and if we handle those values as cyclic, brings that coordinate inside the range.
      Overrides:
      replaceOutsideGridCoordinates in class DatumShiftGrid<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>
      Parameters:
      gridCoordinates - on input, the cell indices of the point which is outside the grid. On output, the cell indices of an equivalent point inside the grid if possible. Coordinate values are modified in-place.
      See Also:
    • getParameterDescriptors

      public final org.opengis.parameter.ParameterDescriptorGroup getParameterDescriptors()
      Returns the descriptor specified at construction time.
      Specified by:
      getParameterDescriptors in class DatumShiftGrid<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>
      Returns:
      a description of the values in this grid.
    • getParameterValues

      public final void getParameterValues(Parameters parameters)
      Sets all parameters for a value of type Path to the values given to the constructor. Subclasses may override for defining other kinds of parameters too.
      Specified by:
      getParameterValues in class DatumShiftGrid<C extends javax.measure.Quantity<C>,T extends javax.measure.Quantity<T>>
      Parameters:
      parameters - the parameter group where to set the values.
    • createGeodeticTransformation

      public static org.opengis.referencing.operation.MathTransform createGeodeticTransformation(Class<? extends AbstractProvider> provider, org.opengis.referencing.operation.MathTransformFactory factory, DatumShiftGridFile<javax.measure.quantity.Angle,javax.measure.quantity.Angle> grid) throws org.opengis.util.FactoryException
      Creates a transformation between two geodetic CRS, including the sub-grid transforms. If the given grid has no sub-grid, then this method is equivalent to a direct call to InterpolatedTransform.createGeodeticTransformation(MathTransformFactory, DatumShiftGrid).
      Parameters:
      provider - the provider which is creating a transform.
      factory - the factory to use for creating the transform.
      grid - the grid of datum shifts from source to target datum.
      Returns:
      the transformation between geodetic coordinates.
      Throws:
      org.opengis.util.FactoryException - if an error occurred while creating a transform.
      See Also: