Class GridGeometry

java.lang.Object
org.apache.sis.coverage.grid.GridGeometry
All Implemented Interfaces:
Serializable, LenientComparable

public class GridGeometry extends Object implements LenientComparable, Serializable
Valid extent of grid coordinates together with the transform from those grid coordinates to real world coordinates. GridGeometry contains: The first three properties should be mandatory, but are allowed to be temporarily absent during grid coverage construction. Temporarily absent properties are allowed because they may be inferred from a wider context. For example, a GridGeometry knows nothing about RenderedImage, but GridCoverage2D has this information and may use it for providing a missing grid extent. By default, any request for an undefined property will throw an IncompleteGridGeometryException. In order to check if a property is defined, use isDefined(int).

Non-linear referencing

A key property is the "grid to CRS" conversion, which defines how to map pixel coordinates to "real world" coordinates such as latitudes and longitudes. This relationship is often linear (an affine transform), but not necessarily; GridGeometry accepts non-linear conversions as well. Non-linear conversions may occur with images using localization grids, but non-linear conversions should not be used for expressing map projections (projections should be specified in the Coordinate Reference System (CRS) instead).

Some applications cannot handle non-linear "grid to CRS" conversions. For example, encoding an image in a GeoTIFF file is much simpler if the "grid to CRS" conversion is linear. The DomainLinearizer class can be used for replacing non-linear conversions by linear approximations.

Multi-threading

GridGeometry instances are immutable and thread-safe. The same instance can be shared by different GridCoverage instances.
Since:
1.0
Version:
1.3
See Also:
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private final class 
    Helper class for formatting a GridGeometry instance.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) final org.opengis.referencing.operation.MathTransform
    Same conversion than gridToCRS but from cell corner instead of center.
    static final int
    A bitmask to specify the validity of the Coordinate Reference System property.
    protected final ImmutableEnvelope
    The geodetic envelope, or null if unknown.
    static final int
    A bitmask to specify the validity of the geodetic envelope property.
    protected final GridExtent
    The valid domain of a grid coverage, or null if unknown.
    static final int
    A bitmask to specify the validity of the grid extent property.
    static final int
    A bitmask to specify the validity of the geographic bounding box.
    private org.opengis.metadata.extent.GeographicBoundingBox
    The geographic bounding box as an unmodifiable metadata instance, or null if not yet computed.
    static final int
    A bitmask to specify the validity of the "grid to CRS" transform.
    protected final org.opengis.referencing.operation.MathTransform
    The conversion from grid indices to "real world" coordinates, or null if unknown.
    (package private) final long
    Whether the conversions from grid coordinates to the CRS are linear, for each target axis.
    protected final double[]
    An estimation of the grid resolution, in units of the CRS axes.
    static final int
    A bitmask to specify the validity of the grid resolution.
    private static final long
    Serial number for inter-operability with different versions.
    static final int
    A bitmask to specify the validity of the temporal period.
    private Instant[]
    The start time and end time, or null if not yet computed.
    static final GridGeometry
    An "empty" grid geometry with no value defined.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Constructor for UNDEFINED singleton only.
     
    GridGeometry(GridExtent extent, org.opengis.geometry.Envelope envelope, GridOrientation orientation)
    Creates an axis-aligned grid geometry with an extent and an envelope.
     
    GridGeometry(GridExtent extent, org.opengis.referencing.datum.PixelInCell anchor, org.opengis.referencing.operation.MathTransform gridToCRS, org.opengis.referencing.crs.CoordinateReferenceSystem crs)
    Creates a new grid geometry from a grid extent and a mapping from cell coordinates to "real world" coordinates.
    (package private)
    GridGeometry(GridExtent extent, org.opengis.referencing.operation.MathTransform gridToCRS, org.opengis.referencing.operation.MathTransform cornerToCRS, ImmutableEnvelope envelope, double[] resolution, long nonLinears)
    Creates a new grid geometry from the given components.
    protected
    Creates a new grid geometry with the same values than the given grid geometry.
     
    GridGeometry(GridGeometry other, GridExtent extent, org.opengis.referencing.operation.MathTransform toOther)
    Creates a new grid geometry derived from the given grid geometry with a new extent and a modified transform.
     
    GridGeometry(org.opengis.referencing.datum.PixelInCell anchor, org.opengis.referencing.operation.MathTransform gridToCRS, org.opengis.geometry.Envelope envelope, GridRoundingMode rounding)
    Creates a new grid geometry from a geospatial envelope and a mapping from cell coordinates to "real world" coordinates.
  • Method Summary

    Modifier and Type
    Method
    Description
    computeEnvelope(org.opengis.referencing.operation.MathTransform specified, org.opengis.referencing.crs.CoordinateReferenceSystem crs, org.opengis.geometry.Envelope limits)
    Computes the envelope with the given coordinate reference system.
    private static org.opengis.referencing.operation.MathTransform
    cornerToCenter(org.opengis.referencing.operation.MathTransform gridToCRS)
    Converts a "grid to CRS" transform from "cell corner" convention to "cell center" convention.
    org.opengis.referencing.crs.DerivedCRS
    createImageCRS(String name, org.opengis.referencing.datum.PixelInCell anchor)
    Creates a one-, two- or three-dimensional coordinate reference system for cell indices in the grid.
    org.opengis.referencing.operation.MathTransform
    createTransformTo(GridGeometry target, org.opengis.referencing.datum.PixelInCell anchor)
    Creates a transform from cell coordinates in this grid to cell coordinates in the given grid.
    (package private) final int
    Returns the default set of flags to use for toString() implementations.
    Returns an object that can be used for creating a new grid geometry derived from this grid geometry.
    private static void
    ensureDimensionMatches(int expected, GridExtent extent)
    Ensures that the given dimension is equal to the expected value.
    boolean
    equals(Object object)
    Compares the specified object with this grid geometry for equality.
    boolean
    equals(Object object, ComparisonMode mode)
    Compares the specified object with this grid geometry for equality.
    (package private) final boolean
    Returns whether the given envelope is equal to this grid geometry envelope with a tolerance threshold computed from grid resolution.
    (package private) static ArithmeticException
    excessiveDimension(org.opengis.referencing.operation.MathTransform gridToCRS)
    Invoked when the number of non-linear dimensions exceeds the GridGeometry capacity.
    private static long
    findNonLinearTargets(org.opengis.referencing.operation.MathTransform gridToCRS)
    Guesses which target dimensions may be non-linear.
    (package private) final void
    formatTo(Locale locale, Vocabulary vocabulary, int bitmask, TreeTable.Node root)
    Formats a string representation of this grid geometry in the specified tree.
    (package private) final org.opengis.metadata.extent.GeographicBoundingBox
    Returns the geographicBBox value or null if none.
    org.opengis.referencing.crs.CoordinateReferenceSystem
    Returns the "real world" coordinate reference system.
    private static org.opengis.referencing.crs.CoordinateReferenceSystem
    getCoordinateReferenceSystem(org.opengis.geometry.Envelope envelope)
    Returns the coordinate reference system of the given envelope if defined, or null if none.
    final int
    Returns the number of dimensions of the grid.
    org.opengis.geometry.Envelope
    Returns the bounding box of "real world" coordinates for this grid geometry.
    org.opengis.geometry.Envelope
    getEnvelope(org.opengis.referencing.crs.CoordinateReferenceSystem crs)
    Returns the "real world" bounding box of this grid geometry transformed to the given CRS.
    Returns the valid coordinate range of a grid coverage.
    Optional<org.opengis.metadata.extent.GeographicBoundingBox>
    Returns the approximate latitude and longitude coordinates of the grid.
    org.opengis.referencing.operation.MathTransform
    getGridToCRS(org.opengis.referencing.datum.PixelInCell anchor)
    Returns the conversion from grid coordinates to "real world" coordinates.
    getLinearGridToCRS(org.opengis.referencing.datum.PixelInCell anchor)
    Returns a linear approximation of the conversion from grid coordinates to "real world" coordinates.
    double[]
    getResolution(boolean allowEstimates)
    Returns an estimation of the grid resolution, in units of the coordinate reference system axes.
    (package private) final int
    Returns the number of dimensions of the CRS.
    Returns the start time and end time of coordinates of the grid.
    int
    Returns a hash value for this grid geometry.
    incomplete(int bitmask, short errorKey)
    Invoked when a property has been requested for which we have for information.
    boolean
    isConversionLinear(int... targets)
    Indicates whether the grid to CRS conversion is linear for all the specified CRS axes.
    boolean
    isDefined(int bitmask)
    Returns true if all the properties specified by the argument are set.
    (package private) final boolean
    Returns true if this grid geometry contains only an envelope and no other information.
    (package private) final boolean
    Returns true if this grid geometry contains only a grid extent and no other information.
    (package private) static void
    recoverableException(String caller, org.opengis.referencing.operation.TransformException exception)
    Invoked when a recoverable exception occurred.
    reduce(int... dimensions)
    Deprecated.
    Renamed selectDimensions(int...) for clarity and consistency with GridExtent.
    relocate(GridExtent newExtent)
    Returns a grid geometry with the given grid extent, which implies a new "real world" computation.
    (package private) final org.opengis.referencing.operation.MathTransform
    requireGridToCRS(boolean center)
    Verifies that this grid geometry defines an extent and a cornerToCRS transform.
    (package private) static double[]
    resolution(org.opengis.referencing.operation.MathTransform gridToCRS, GridExtent domain, org.opengis.referencing.datum.PixelInCell anchor)
    Computes the resolution for the given grid extent and transform, or returns null if unknown.
    private static double[]
    resolution(org.opengis.referencing.operation.Matrix gridToCRS, int numToIgnore)
    Computes the resolutions from the given matrix.
    selectDimensions(int... dimensions)
    Returns a grid geometry that encompass only some dimensions of this grid geometry.
    shiftGrid(long... translation)
    Translates grid coordinates by the given amount of cells without changing "real world" coordinates.
    private Instant[]
    Returns the timeRange value without cloning.
    Returns a string representation of this grid geometry.
    toTree(Locale locale, int bitmask)
    Returns a tree representation of some elements of this grid geometry.
    translate(long... translation)
    Deprecated.
    Renamed shiftGrid(long...) for making clearer that this method changes grid coordinates without changing "real world" coordinates.
    upsample(int... periods)
    Creates a new grid geometry upsampled by the given amount of cells along each grid dimensions.

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, notify, notifyAll, wait, wait, wait
  • Field Details

    • serialVersionUID

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

      public static final int CRS
      A bitmask to specify the validity of the Coordinate Reference System property.
      See Also:
    • ENVELOPE

      public static final int ENVELOPE
      A bitmask to specify the validity of the geodetic envelope property.
      See Also:
    • EXTENT

      public static final int EXTENT
      A bitmask to specify the validity of the grid extent property.
      See Also:
    • GRID_TO_CRS

      public static final int GRID_TO_CRS
      A bitmask to specify the validity of the "grid to CRS" transform.
      See Also:
    • RESOLUTION

      public static final int RESOLUTION
      A bitmask to specify the validity of the grid resolution.
      See Also:
    • GEOGRAPHIC_EXTENT

      public static final int GEOGRAPHIC_EXTENT
      A bitmask to specify the validity of the geographic bounding box. This information can sometimes be derived from the envelope and the CRS. It is an optional element even with a complete grid geometry since the coordinate reference system is not required to have an horizontal component.
      See Also:
    • TEMPORAL_EXTENT

      public static final int TEMPORAL_EXTENT
      A bitmask to specify the validity of the temporal period. This information can sometimes be derived from the envelope and the CRS. It is an optional element even with a complete grid geometry since the coordinate reference system is not required to have a temporal component.
      See Also:
    • extent

      protected final GridExtent extent
      The valid domain of a grid coverage, or null if unknown. The lowest valid grid coordinate is zero for BufferedImage, but may be non-zero for arbitrary RenderedImage. A grid with 512 cells can have a minimum coordinate of 0 and maximum of 511.
      See Also:
    • envelope

      protected final ImmutableEnvelope envelope
      The geodetic envelope, or null if unknown. If non-null, this envelope is usually the grid extent transformed to real world coordinates. The Coordinate Reference System} (CRS) of this envelope defines the "real world" CRS of this grid geometry.
      See Also:
    • gridToCRS

      protected final org.opengis.referencing.operation.MathTransform gridToCRS
      The conversion from grid indices to "real world" coordinates, or null if unknown. If non-null, the conversion shall map cell center. This conversion is usually, but not necessarily, affine.
      See Also:
    • cornerToCRS

      final org.opengis.referencing.operation.MathTransform cornerToCRS
      Same conversion than gridToCRS but from cell corner instead of center. This transform is preferable to gridToCRS for transforming envelopes.
    • resolution

      protected final double[] resolution
      An estimation of the grid resolution, in units of the CRS axes. Computed from gridToCRS, eventually together with extent. May be null if unknown. If non-null, the array length is equal to the number of CRS dimensions.
      See Also:
    • nonLinears

      final long nonLinears
      Whether the conversions from grid coordinates to the CRS are linear, for each target axis. The bit located at 1L << dimension is set to 1 when the conversion at that dimension is non-linear. The dimension indices are those of the CRS, not the grid. The use of long type limits the capacity to 64 dimensions. But actually GridGeometry can contain more dimensions provided that index of the last non-linear dimension is not greater than 64.
      See Also:
    • geographicBBox

      private transient volatile org.opengis.metadata.extent.GeographicBoundingBox geographicBBox
      The geographic bounding box as an unmodifiable metadata instance, or null if not yet computed. If no geographic extent can be computed for the envelope, then this is set to NilObject.
      See Also:
    • timeRange

      private transient volatile Instant[] timeRange
      The start time and end time, or null if not yet computed. If there is no time range, then the array is empty. If there is only a start time or an end time, then the array length is 1. Otherwise the array length is 2.
      See Also:
    • UNDEFINED

      public static final GridGeometry UNDEFINED
      An "empty" grid geometry with no value defined. All getter methods invoked on this instance will cause IncompleteGridGeometryException to be thrown. This instance can be used as a place-holder when the grid geometry cannot be obtained.
  • Constructor Details

    • GridGeometry

      private GridGeometry()
      Constructor for UNDEFINED singleton only.
    • GridGeometry

      protected GridGeometry(GridGeometry other)
      Creates a new grid geometry with the same values than the given grid geometry. This is a copy constructor for subclasses.
      Parameters:
      other - the other grid geometry to copy.
    • GridGeometry

      public GridGeometry(GridGeometry other, GridExtent extent, org.opengis.referencing.operation.MathTransform toOther) throws org.opengis.referencing.operation.TransformException
      Creates a new grid geometry derived from the given grid geometry with a new extent and a modified transform. This constructor is used for creating a grid geometry over a subregion (for example with the grid extent computed by GridDerivation.subgrid(Envelope, double...)) or grid geometry for a subsampled raster.

      Conversion between old and new grid geometry

      If toOther is non-null, it defines the conversion from grid coordinates of given extent to grid coordinates of other. That transform should be a scale and a translation only, but more complex transforms are accepted. The cornerToCRS transform of the new grid geometry will be set to the following concatenation:
      this.cornerToCRS = toOtherother.cornerToCRS
      The new grid geometry envelope will be computed from the new extent and transform, then clipped to the envelope of the other grid geometry. This clip is for preventing the envelope to become larger under the effect of subsampling because each cell become larger. The clip is not applied when toOther is null because in such case, we presume that the grid extent has been changed for another reason than subsampling (e.g. application of a margin, in which case we want the envelope to be expanded).
      Parameters:
      other - the other grid geometry to copy.
      extent - the new extent for the grid geometry to construct, or null if none.
      toOther - transform from this grid coordinates to other grid coordinates, or null if none.
      Throws:
      NullPointerException - if extent is null and the other grid geometry contains no other information.
      org.opengis.referencing.operation.TransformException - if the math transform cannot compute the geospatial envelope from the grid extent.
      Since:
      1.2
      See Also:
    • GridGeometry

      public GridGeometry(GridExtent extent, org.opengis.referencing.datum.PixelInCell anchor, org.opengis.referencing.operation.MathTransform gridToCRS, org.opengis.referencing.crs.CoordinateReferenceSystem crs)
      Creates a new grid geometry from a grid extent and a mapping from cell coordinates to "real world" coordinates. At least one of extent, gridToCRS or crs arguments shall be non-null. If gridToCRS is non-null, then anchor shall be non-null too with one of the following values:
      • PixelInCell.CELL_CENTER if conversions of cell indices by gridToCRS give "real world" coordinates close to the center of each cell.
      • PixelInCell.CELL_CORNER if conversions of cell indices by gridToCRS give "real world" coordinates at the corner of each cell. The cell corner is the one for which all grid indices have the smallest values (closest to negative infinity).
      API note: there is no default value for anchor because experience shows that images shifted by ½ pixel (with pixels that may be tens of kilometres large) is a recurrent problem. We want to encourage developers to always think about wether their grid to CRS transform is mapping pixel corner or center.
      Upcoming API generalization: the extent type of this method may be changed to GridEnvelope interface in a future Apache SIS version. This is pending GeoAPI update. In addition, the PixelInCell code list currently defined in the org.opengis.referencing.datum package may move in another package in a future GeoAPI version because this type is no longer defined by the ISO 19111 standard after the 2018 revision.
      Parameters:
      extent - the valid extent of grid coordinates, or null if unknown.
      anchor - Cell center for OGC conventions or cell corner for Java2D/JAI conventions.
      gridToCRS - the mapping from grid coordinates to "real world" coordinates, or null if unknown.
      crs - the coordinate reference system of the "real world" coordinates, or null if unknown.
      Throws:
      NullPointerException - if extent, gridToCRS and crs arguments are all null.
      org.opengis.geometry.MismatchedDimensionException - if the math transform and the CRS do not have consistent dimensions.
      IllegalGridGeometryException - if the math transform cannot compute the geospatial envelope or resolution from the grid extent.
    • GridGeometry

      public GridGeometry(org.opengis.referencing.datum.PixelInCell anchor, org.opengis.referencing.operation.MathTransform gridToCRS, org.opengis.geometry.Envelope envelope, GridRoundingMode rounding)
      Creates a new grid geometry from a geospatial envelope and a mapping from cell coordinates to "real world" coordinates. At least one of gridToCRS or envelope arguments shall be non-null. If gridToCRS is non-null, then anchor shall be non-null too with one of the values documented in the constructor expecting a grid extent.

      The given envelope shall encompass all cell surfaces, from the left border of leftmost cell to the right border of the rightmost cell and similarly along other axes. This constructor tries to store a geospatial envelope close to the specified envelope, but there is no guarantee that the envelope returned by getEnvelope() will be equal to the given envelope. The envelope stored in the new GridGeometry may be slightly smaller, larger or shifted because the floating point values used in geospatial envelope cannot always be mapped to the integer coordinates used in GridExtent. The rules for deciding whether coordinates should be rounded toward nearest integers, to floor or to ceil values are specified by the GridRoundingMode argument.

      Because of the uncertainties explained in above paragraph, this constructor should be used only in last resort, when the grid extent is unknown. For determinist results, developers should prefer the constructor using grid extent as much as possible. In particular, this constructor is not suitable for computing grid geometry of tiles in a tiled image, because the above-cited uncertainties may result in apparently random black lines between tiles.

      Upcoming API change: The PixelInCell code list currently defined in the org.opengis.referencing.datum package may move in another package in a future GeoAPI version because this type is no longer defined by the ISO 19111 standard after the 2018 revision. This code list may be taken by ISO 19123 in a future revision.
      Parameters:
      anchor - Cell center for OGC conventions or cell corner for Java2D/JAI conventions.
      gridToCRS - the mapping from grid coordinates to "real world" coordinates, or null if unknown.
      envelope - the geospatial envelope, including its coordinate reference system if available. There is no guarantee that the envelope actually stored in the GridGeometry will be equal to this specified envelope.
      rounding - controls behavior of rounding from floating point values to integers.
      Throws:
      IllegalGridGeometryException - if the math transform cannot compute the grid extent or the resolution.
    • GridGeometry

      public GridGeometry(GridExtent extent, org.opengis.geometry.Envelope envelope, GridOrientation orientation)
      Creates an axis-aligned grid geometry with an extent and an envelope. This constructor can be used when the grid to CRS transform is unknown. If only the coordinate reference system is known, then the envelope coordinates can be all NaN.

      The main purpose of this constructor is to create "desired" grid geometries, for example for use in read or resample operations. For grid geometries describing preexisting data, it is safer and more flexible to use one of the constructors expecting a MathTransform argument.

      Dimension order

      The given envelope shall always declare dimensions in same order than the given extent. This constructor may reorder axes if orientation is (for example) GridOrientation.DISPLAY, but in such case this constructor will derive itself an envelope and a CRS with reordered axes.
      Parameters:
      extent - the valid extent of grid coordinates, or null if unknown.
      envelope - the envelope together with CRS of the "real world" coordinates, or null if unknown.
      orientation - high-level description of desired characteristics of the gridToCRS transform. Ignored (can be null) if envelope is null.
      Throws:
      NullPointerException - if extent and envelope arguments are both null, or if envelope is non-null but orientation is null.
      Since:
      1.1
      See Also:
    • GridGeometry

      GridGeometry(GridExtent extent, org.opengis.referencing.operation.MathTransform gridToCRS, org.opengis.referencing.operation.MathTransform cornerToCRS, ImmutableEnvelope envelope, double[] resolution, long nonLinears)
      Creates a new grid geometry from the given components. This constructor performs no verification (unless assertions are enabled).
  • Method Details

    • computeEnvelope

      private ImmutableEnvelope computeEnvelope(org.opengis.referencing.operation.MathTransform specified, org.opengis.referencing.crs.CoordinateReferenceSystem crs, org.opengis.geometry.Envelope limits) throws org.opengis.referencing.operation.TransformException
      Computes the envelope with the given coordinate reference system. This method is invoked from constructors. The extent, gridToCRS and cornerToCRS fields must be set before this method is invoked.
      Parameters:
      specified - the transform specified by the user. This is not necessarily gridToCRS.
      crs - the coordinate reference system to declare in the envelope. May be null.
      limits - if non-null, intersect with that envelope. The CRS must be the same than crs.
      Throws:
      org.opengis.referencing.operation.TransformException
    • ensureDimensionMatches

      private static void ensureDimensionMatches(int expected, GridExtent extent) throws org.opengis.geometry.MismatchedDimensionException
      Ensures that the given dimension is equal to the expected value. If not, throws an exception. This method assumes that the argument name is "extent".
      Parameters:
      extent - the extent to validate, or null if none.
      expected - the expected number of dimension.
      Throws:
      org.opengis.geometry.MismatchedDimensionException
    • recoverableException

      static void recoverableException(String caller, org.opengis.referencing.operation.TransformException exception)
      Invoked when a recoverable exception occurred. Those exceptions must be minor enough that they can be silently ignored in most cases.
      Parameters:
      caller - the method where exception occurred.
      exception - the exception that occurred.
    • cornerToCenter

      private static org.opengis.referencing.operation.MathTransform cornerToCenter(org.opengis.referencing.operation.MathTransform gridToCRS)
      Converts a "grid to CRS" transform from "cell corner" convention to "cell center" convention. This is a helper method for use of GridGeometry(GridExtent, MathTransform, MathTransform, ImmutableEnvelope, double[], long) constructor.
      Parameters:
      gridToCRS - the transform to convert, or null if none.
      Returns:
      the converted transform, or null if the given transform was null.
    • getDimension

      public final int getDimension()
      Returns the number of dimensions of the grid. This is typically the same than the number of envelope dimensions or the number of coordinate reference system dimensions, but not necessarily.
      Returns:
      the number of grid dimensions.
      See Also:
    • getTargetDimension

      final int getTargetDimension()
      Returns the number of dimensions of the CRS. This is typically the same than the number of grid dimensions, but not necessarily.
    • getExtent

      public GridExtent getExtent()
      Returns the valid coordinate range of a grid coverage. The lowest valid grid coordinate is zero for BufferedImage, but may be non-zero for arbitrary RenderedImage. A grid with 512 cells can have a minimum coordinate of 0 and maximum of 511.
      Upcoming API generalization: the return type of this method may be changed to GridEnvelope interface in a future Apache SIS version. This is pending GeoAPI update.
      Returns:
      the valid extent of grid coordinates (never null).
      Throws:
      IncompleteGridGeometryException - if this grid geometry has no extent — i.e. isDefined(EXTENT) returned false.
    • getGridToCRS

      public org.opengis.referencing.operation.MathTransform getGridToCRS(org.opengis.referencing.datum.PixelInCell anchor)
      Returns the conversion from grid coordinates to "real world" coordinates. The conversion is often an affine transform, but not necessarily. Conversions from cell indices to geospatial coordinates can be performed for example as below: Callers must specify whether they want the "real world" coordinates of cell center or cell corner. The cell corner is the one for which all grid indices have the smallest values (closest to negative infinity). As a rule of thumb:
      • Use PixelInCell.CELL_CENTER for transforming points.
      • Use PixelInCell.CELL_CORNER for transforming envelopes with inclusive lower coordinates and exclusive upper coordinates.
      API note: there is no default value for anchor because experience shows that images shifted by ½ pixel (with pixels that may be tens of kilometres large) is a recurrent problem. We want to encourage developers to always think about wether the desired grid to CRS transform shall map pixel corner or center.
      Parameters:
      anchor - the cell part to map (center or corner).
      Returns:
      the conversion from grid coordinates to "real world" coordinates (never null).
      Throws:
      IllegalArgumentException - if the given anchor is not a known code list value.
      IncompleteGridGeometryException - if this grid geometry has no transform — i.e. isDefined(GRID_TO_CRS) returned false.
    • getLinearGridToCRS

      public LinearTransform getLinearGridToCRS(org.opengis.referencing.datum.PixelInCell anchor) throws org.opengis.referencing.operation.TransformException
      Returns a linear approximation of the conversion from grid coordinates to "real world" coordinates. If the value returned by getGridToCRS(PixelInCell) is already an instance of LinearTransform, then it is returned as is. Otherwise this method computes the tangent of the transform at the grid extent point of interest (usually the center of the grid).
      Parameters:
      anchor - the cell part to map (center or corner).
      Returns:
      linear approximation of the conversion from grid coordinates to "real world" coordinates.
      Throws:
      IllegalArgumentException - if the given anchor is not a known code list value.
      IncompleteGridGeometryException - if this grid geometry has no transform, or if the transform is non-linear but this grid geometry has no extent.
      org.opengis.referencing.operation.TransformException - if an error occurred while computing the tangent.
      Since:
      1.3
    • getCoordinateReferenceSystem

      private static org.opengis.referencing.crs.CoordinateReferenceSystem getCoordinateReferenceSystem(org.opengis.geometry.Envelope envelope)
      Returns the coordinate reference system of the given envelope if defined, or null if none. Contrarily to getCoordinateReferenceSystem(), this method does not throw exception.
    • getCoordinateReferenceSystem

      public org.opengis.referencing.crs.CoordinateReferenceSystem getCoordinateReferenceSystem()
      Returns the "real world" coordinate reference system.
      Returns:
      the coordinate reference system (never null).
      Throws:
      IncompleteGridGeometryException - if this grid geometry has no CRS — i.e. isDefined(CRS) returned false.
    • getEnvelope

      public org.opengis.geometry.Envelope getEnvelope()
      Returns the bounding box of "real world" coordinates for this grid geometry. This envelope is computed from the grid extent, which is transformed to the "real world" coordinate system. The initial envelope encompasses all cell surfaces, from the left border of leftmost cell to the right border of the rightmost cell and similarly along other axes. If this grid geometry is a subgrid, then the envelope is also clipped to the envelope of the original (non subsampled) grid geometry.
      Returns:
      the bounding box in "real world" coordinates (never null).
      Throws:
      IncompleteGridGeometryException - if this grid geometry has no envelope — i.e. isDefined(ENVELOPE) returned false.
    • getEnvelope

      public org.opengis.geometry.Envelope getEnvelope(org.opengis.referencing.crs.CoordinateReferenceSystem crs) throws org.opengis.referencing.operation.TransformException
      Returns the "real world" bounding box of this grid geometry transformed to the given CRS. This envelope is computed from the grid extent if available, or from the envelope otherwise.
      Parameters:
      crs - the desired coordinate reference system for the returned envelope.
      Returns:
      the bounding box in "real world" coordinates (never null).
      Throws:
      IncompleteGridGeometryException - if this grid geometry has no extent and no envelope.
      org.opengis.referencing.operation.TransformException - if the envelope cannot be transformed to the specified CRS.
      Since:
      1.2
    • getGeographicExtent

      public Optional<org.opengis.metadata.extent.GeographicBoundingBox> getGeographicExtent()
      Returns the approximate latitude and longitude coordinates of the grid. The prime meridian is Greenwich, but the geodetic reference frame is not necessarily WGS 84. This is computed from the envelope if the coordinate reference system contains an horizontal component such as a geographic or projected CRS.
      API note: this method does not throw IncompleteGridGeometryException because the geographic extent may be absent even with a complete grid geometry. Grid geometries are not required to have a spatial component on Earth surface; a raster could be a vertical profile for example.
      Returns:
      the geographic bounding box in "real world" coordinates.
    • geographicBBox

      final org.opengis.metadata.extent.GeographicBoundingBox geographicBBox()
      Returns the geographicBBox value or null if none. This method computes the box when first needed.
    • getTemporalExtent

      public Instant[] getTemporalExtent()
      Returns the start time and end time of coordinates of the grid. If the grid has no temporal dimension, then this method returns an empty array. If only the start time or end time is defined, then returns an array of length 1. Otherwise this method returns an array of length 2 with the start time in the first element and the end time in the last element.
      Returns:
      time range as an array of length 0 (if none), 1 or 2.
    • timeRange

      private Instant[] timeRange()
      Returns the timeRange value without cloning. This method computes the time range when first needed.
    • getResolution

      public double[] getResolution(boolean allowEstimates)
      Returns an estimation of the grid resolution, in units of the coordinate reference system axes. The length of the returned array is the number of CRS dimensions, with resolution[0] being the resolution along the first CRS axis, resolution[1] the resolution along the second CRS axis, etc. Note that this axis order is not necessarily the same than grid axis order.

      If the resolution at CRS dimension i is not a constant factor (i.e. the isConversionLinear(i) returns false), then resolution[i] is set to one of the following values:

      • Double.NaN if allowEstimates is false.
      • An arbitrary representative resolution otherwise. Current implementation computes the resolution at grid center, but different implementations may use alternative algorithms.
      Parameters:
      allowEstimates - whether to provide some values even for resolutions that are not constant factors.
      Returns:
      an estimation of the grid resolution (never null).
      Throws:
      IncompleteGridGeometryException - if this grid geometry has no resolution — i.e. isDefined(RESOLUTION) returned false.
    • resolution

      static double[] resolution(org.opengis.referencing.operation.MathTransform gridToCRS, GridExtent domain, org.opengis.referencing.datum.PixelInCell anchor)
      Computes the resolution for the given grid extent and transform, or returns null if unknown. Resolutions are given in order of target axes and give a scale factor from source to target coordinates. If the gridToCRS transform is linear, we do not even need to check the grid extent; it can be null. Otherwise (if the transform is non-linear) the extent is necessary. The easiest way to estimate a resolution is then to ask for the derivative at some arbitrary point (the point of interest).

      Note that for this computation, it does not matter if gridToCRS is the user-specified transform or the this.gridToCRS field value; both should produce equivalent results.

      Parameters:
      gridToCRS - a transform for which to compute the resolution, or null if none.
      domain - the domain for which to get a resolution, or null if none. If non-null, must be the source of gridToCRS.
      anchor - the pixel corner versus pixel center convention to use.
      Returns:
      the resolutions as positive numbers. May contain NaN values.
    • resolution

      private static double[] resolution(org.opengis.referencing.operation.Matrix gridToCRS, int numToIgnore)
      Computes the resolutions from the given matrix. This is the magnitude of each row vector. Resolutions are given in order of target axes.
      Parameters:
      gridToCRS - Jacobian matrix or affine transform for which to compute the resolution.
      numToIgnore - number of rows and columns to ignore at the end of the matrix. This is 0 if the matrix is a derivative (i.e. we ignore nothing), or 1 if the matrix is an affine transform (i.e. we ignore the translation column and the [0 0 … 1] row).
      Returns:
      the resolutions as positive numbers. May contain NaN values.
    • isConversionLinear

      public boolean isConversionLinear(int... targets)
      Indicates whether the grid to CRS conversion is linear for all the specified CRS axes. The conversion from grid coordinates to real world coordinates is often linear for some dimensions, typically the horizontal ones at indices 0 and 1. But the vertical dimension (usually at index 2) is often non-linear, for example with data at 0, 5, 10, 100 and 1000 metres.
      Parameters:
      targets - indices of CRS axes. This is not necessarily the same than indices of grid axes.
      Returns:
      true if the conversion from grid coordinates to "real world" coordinates is linear for all the given CRS dimension.
    • findNonLinearTargets

      private static long findNonLinearTargets(org.opengis.referencing.operation.MathTransform gridToCRS)
      Guesses which target dimensions may be non-linear. We currently don't have an API for finding the non-linear dimensions. Current implementation assumes that everything else than LinearTransform and pass-through dimensions are non-linear. This is not always true (e.g. in a Mercator projection, the "longitude → easting" part is linear too), but should be okay for GridGeometry purposes.

      We keep trace of non-linear dimensions in a bitmask, with bits of non-linear dimensions set to 1. This limit us to 64 dimensions, which is assumed more than enough. Note that GridGeometry can contain more dimensions provided that index of the last non-linear dimension is not greater than 64.

      Parameters:
      gridToCRS - the transform to "real world" coordinates, or null if unknown.
      Returns:
      a bitmask of dimensions, or 0 (i.e. conversion assumed fully linear) if the given transform was null.
    • excessiveDimension

      static ArithmeticException excessiveDimension(org.opengis.referencing.operation.MathTransform gridToCRS)
      Invoked when the number of non-linear dimensions exceeds the GridGeometry capacity.
    • incomplete

      private IncompleteGridGeometryException incomplete(int bitmask, short errorKey)
      Invoked when a property has been requested for which we have for information.
      Parameters:
      bitmask - the requested property, for assertion purpose.
      errorKey - the resource key to use in error message.
      Returns:
      the exception to be thrown by the caller.
    • requireGridToCRS

      final org.opengis.referencing.operation.MathTransform requireGridToCRS(boolean center) throws IncompleteGridGeometryException
      Verifies that this grid geometry defines an extent and a cornerToCRS transform. They are the information required for mapping the grid to a spatiotemporal envelope or position. Note that this implies that envelope is non-null (but not necessarily that its CRS is non-null).
      Parameters:
      center - true for "center to CRS" transform, false for "corner to CRS" transform.
      Returns:
      gridToCRS or cornerToCRS.
      Throws:
      IncompleteGridGeometryException
    • isDefined

      public boolean isDefined(int bitmask)
      Returns true if all the properties specified by the argument are set. If this method returns true, then invoking the corresponding getter methods will not throw IncompleteGridGeometryException.
      Parameters:
      bitmask - any combination of CRS, ENVELOPE, EXTENT, GRID_TO_CRS and RESOLUTION.
      Returns:
      true if all specified properties are defined (i.e. invoking the corresponding getter methods will not throw IncompleteGridGeometryException).
      Throws:
      IllegalArgumentException - if the specified bitmask is not a combination of known masks.
      See Also:
    • isExtentOnly

      final boolean isExtentOnly()
      Returns true if this grid geometry contains only a grid extent and no other information. Note: if gridToCRS is null, then cornerToCRS and resolution should be null as well.
    • isEnvelopeOnly

      final boolean isEnvelopeOnly()
      Returns true if this grid geometry contains only an envelope and no other information. Note: if gridToCRS is null, then cornerToCRS and resolution should be null as well.
    • derive

      public GridDerivation derive()
      Returns an object that can be used for creating a new grid geometry derived from this grid geometry. GridDerivation does not change the state of this GridGeometry but instead creates new instances as needed. Examples of modifications include clipping to a sub-area or applying a sub-sampling.
      Example: for clipping this grid geometry to a sub-area, one can use:
      Each GridDerivation instance can be used only once and should be used in a single thread. GridDerivation preserves the number of dimensions. For example, slicing sets the grid size to 1 in all dimensions specified by a slice point, but does not remove those dimensions from the grid geometry. For dimensionality reduction, see selectDimensions(int[]).
      Returns:
      an object for deriving a grid geometry from this.
    • upsample

      public GridGeometry upsample(int... periods)
      Creates a new grid geometry upsampled by the given amount of cells along each grid dimensions. This method multiplies low and high coordinates by the given periods, then scales the grid to CRS transform for compensating the grid change. The grid geometry envelope is preserved after upsampling.

      Number of arguments

      The periods array length should be equal to the number of grid dimensions. If the array is shorter, missing values default to 1 (i.e. samplings in unspecified dimensions are unchanged). If the array is longer, extraneous values are ignored.
      Parameters:
      periods - the upsampling. Length shall be equal to the number of dimension and all values shall be greater than zero.
      Returns:
      the upsampled grid geometry, or this is upsampling results in the same extent.
      Throws:
      IllegalArgumentException - if a period is not greater than zero.
      Since:
      1.3
      See Also:
    • shiftGrid

      public GridGeometry shiftGrid(long... translation)
      Translates grid coordinates by the given amount of cells without changing "real world" coordinates. The returned grid has the same size than this grid, i.e. both low and high grid coordinates are displaced by the same amount of cells. The "grid to CRS" transforms are adjusted accordingly in order to map to the same "real world" coordinates.

      Number of arguments

      The translation array length should be equal to the number of dimensions. If the array is shorter, missing values default to 0 (i.e. no translation in unspecified dimensions). If the array is longer, extraneous values are ignored.
      Parameters:
      translation - translation to apply on each grid axis in order.
      Returns:
      a grid geometry whose coordinates (both low and high ones) and the "grid to CRS" transforms have been translated by given amounts. If the given translation is a no-op (no value or only 0 ones), then this grid is returned as is.
      Throws:
      ArithmeticException - if the translation results in coordinates that overflow 64-bits integer.
      Since:
      1.3
      See Also:
    • translate

      @Deprecated public GridGeometry translate(long... translation)
      Deprecated.
      Renamed shiftGrid(long...) for making clearer that this method changes grid coordinates without changing "real world" coordinates.
      Returns a grid geometry translated by the given amount of cells compared to this grid.
      Parameters:
      translation - translation to apply on each grid axis in order.
      Returns:
      a grid geometry whose coordinates and the "grid to CRS" transforms have been translated by given amounts.
      Since:
      1.1
    • relocate

      public GridGeometry relocate(GridExtent newExtent) throws org.opengis.referencing.operation.TransformException
      Returns a grid geometry with the given grid extent, which implies a new "real world" computation. The "grid to CRS" transforms and the resolution stay the same than this GridGeometry. The "real world" envelope is recomputed for the new grid extent using the "grid to CRS" transforms.

      The given extent is taken verbatim; this method does no clipping. The given extent does not need to intersect the extent of this grid geometry.

      Parameters:
      newExtent - extent of the grid geometry to return.
      Returns:
      grid geometry with the given extent. May be this if there is no change.
      Throws:
      org.opengis.referencing.operation.TransformException - if the geospatial envelope cannot be recomputed with the new grid extent.
      Since:
      1.3
    • selectDimensions

      public GridGeometry selectDimensions(int... dimensions)
      Returns a grid geometry that encompass only some dimensions of this grid geometry. The specified dimensions will be copied into a new grid geometry if necessary. The selection is applied on grid extent dimensions; they are not necessarily the same than the envelope dimensions. The given dimensions must be in strictly ascending order without duplicated values. The number of dimensions of the sub grid geometry will be dimensions.length.

      This method performs a dimensionality reduction. This method cannot be used for changing dimension order.

      Parameters:
      dimensions - the grid (not CRS) dimensions to select, in strictly increasing order.
      Returns:
      the sub-grid geometry, or this if the given array contains all dimensions of this grid geometry.
      Throws:
      IndexOutOfBoundsException - if an index is out of bounds.
      Since:
      1.3
      See Also:
    • reduce

      @Deprecated public GridGeometry reduce(int... dimensions)
      Deprecated.
      Renamed selectDimensions(int...) for clarity and consistency with GridExtent.
      Returns a grid geometry that encompass only some dimensions of this grid geometry.
      Parameters:
      dimensions - the grid (not CRS) dimensions to select, in strictly increasing order.
      Returns:
      the sub-grid geometry, or this if the given array contains all dimensions of this grid geometry.
    • createImageCRS

      public org.opengis.referencing.crs.DerivedCRS createImageCRS(String name, org.opengis.referencing.datum.PixelInCell anchor)
      Creates a one-, two- or three-dimensional coordinate reference system for cell indices in the grid. This method returns a CRS which is derived from the "real world" CRS or a subset of it. If the "real world" CRS is an instance of SingleCRS, then the derived CRS has the following properties: Otherwise if the "real world" CRS is an instance of CompoundCRS, then only the first SingleCRS (the head) is used. This is usually (but not necessarily) the horizontal component of the spatial CRS. The result is usually two-dimensional, but 1 and 3 dimensions are also possible.

      Because of above relationship, it is possible to use the derived CRS in a chain of operations with (for example) CRS.findOperation(…).

      Parameters:
      name - name of the CRS to create.
      anchor - the cell part to map (center or corner).
      Returns:
      a derived CRS for coordinates (cell indices) associated to the grid extent.
      Throws:
      IncompleteGridGeometryException - if the CRS, grid extent or "grid to CRS" transform is missing.
      Since:
      1.3
    • createTransformTo

      public org.opengis.referencing.operation.MathTransform createTransformTo(GridGeometry target, org.opengis.referencing.datum.PixelInCell anchor) throws org.opengis.referencing.operation.TransformException
      Creates a transform from cell coordinates in this grid to cell coordinates in the given grid. The returned transform handles change of Coordinate Reference System and wraparound axes (e.g. longitude axis crossing the ±180° meridian) if applicable.

      Note: the transform created by this method may be non-invertible.

      Parameters:
      target - the grid which will be the target of returned transform.
      anchor - Cell center for OGC conventions or cell corner for Java2D/JAI conventions.
      Returns:
      transform from cell coordinates in this grid to cell coordinates in the given grid.
      Throws:
      org.opengis.referencing.operation.TransformException - if the math transform cannot be created.
      Since:
      1.1
    • hashCode

      public int hashCode()
      Returns a hash value for this grid geometry. This value needs not to remain consistent between different implementations of the same class.
      Overrides:
      hashCode in class Object
    • equals

      public boolean equals(Object object)
      Compares the specified object with this grid geometry for equality. This method delegates to equals(object, ComparisonMode.STRICT).
      Specified by:
      equals in interface LenientComparable
      Overrides:
      equals in class Object
      Parameters:
      object - the object to compare with.
      Returns:
      true if the given object is equal to this grid geometry.
      See Also:
    • equals

      public boolean equals(Object object, ComparisonMode mode)
      Compares the specified object with this grid geometry for equality. If the mode is ComparisonMode.IGNORE_METADATA or more flexible, then the axis types are ignored.
      Specified by:
      equals in interface LenientComparable
      Parameters:
      object - the object to compare with this grid geometry for equality.
      mode - the strictness level of the comparison.
      Returns:
      true if the given object is equal to this grid geometry.
      Since:
      1.1
      See Also:
    • equalsApproximately

      final boolean equalsApproximately(ImmutableEnvelope othenv)
      Returns whether the given envelope is equal to this grid geometry envelope with a tolerance threshold computed from grid resolution. If this grid geometry has no envelope, then this method arbitrarily returns true (this unusual behavior is required by equals(Object, ComparisonMode)).
    • defaultFlags

      final int defaultFlags()
      Returns the default set of flags to use for toString() implementations. Current implementation returns all core properties, augmented with only derived properties that are defined.
    • toString

      public String toString()
      Returns a string representation of this grid geometry. The returned string is implementation dependent and may change in any future version. Current implementation is equivalent to a call to toTree(Locale, int) with at least EXTENT, ENVELOPE and CRS flags. Whether more flags are present or not is unspecified.
      Overrides:
      toString in class Object
    • toTree

      @Debug public TreeTable toTree(Locale locale, int bitmask)
      Returns a tree representation of some elements of this grid geometry. The tree representation is for debugging or logging purposes and may change in any future SIS version.
      Parameters:
      locale - the locale to use for textual labels.
      bitmask - combination of EXTENT, ENVELOPE, CRS, GRID_TO_CRS, RESOLUTION, GEOGRAPHIC_EXTENT and TEMPORAL_EXTENT.
      Returns:
      a tree representation of the specified elements.
    • formatTo

      final void formatTo(Locale locale, Vocabulary vocabulary, int bitmask, TreeTable.Node root)
      Formats a string representation of this grid geometry in the specified tree.