Package org.apache.sis.coverage.grid

# Class GridGeometry

Object
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:

- A grid extent (a.k.a. grid envelope), often inferred from the `RenderedImage` size.
- A grid to CRS transform, which may be inferred from the grid extent and the georeferenced envelope.
- A georeferenced envelope, which can be inferred from the grid extent and the grid to CRS transform.
- An optional Coordinate Reference System (CRS) specified as part of the georeferenced envelope. This CRS is the target of the grid to CRS transform.
- An estimation of `grid resolution` along each CRS axes, computed from the grid to CRS transform and eventually from the grid extent.
- An indication of whether conversion for some axes is linear or not.

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 can not 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
See Also:
  - Serialized Form

Defined in the `sis-feature` module

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final int`
  `CRS`
  A bitmask to specify the validity of the Coordinate Reference System property.
  `protected final ImmutableEnvelope`
  `envelope`
  The geodetic envelope, or `null` if unknown.
  `static final int`
  `ENVELOPE`
  A bitmask to specify the validity of the geodetic envelope property.
  `protected final GridExtent`
  `extent`
  The valid domain of a grid coverage, or `null` if unknown.
  `static final int`
  `EXTENT`
  A bitmask to specify the validity of the grid extent property.
  `static final int`
  `GEOGRAPHIC_EXTENT`
  A bitmask to specify the validity of the geographic bounding box.
  `static final int`
  `GRID_TO_CRS`
  A bitmask to specify the validity of the "grid to CRS" transform.
  `protected final MathTransform`
  `gridToCRS`
  The conversion from grid indices to "real world" coordinates, or `null` if unknown.
  `protected final double[]`
  `resolution`
  An estimation of the grid resolution, in units of the CRS axes.
  `static final int`
  `RESOLUTION`
  A bitmask to specify the validity of the grid resolution.
  `static final int`
  `TEMPORAL_EXTENT`
  A bitmask to specify the validity of the temporal period.
  `static final GridGeometry`
  `UNDEFINED`
  An "empty" grid geometry with no value defined.

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  ``
  `GridGeometry(GridExtent extent, Envelope envelope)`
  Deprecated.
  Replaced by `GridGeometry(GridExtent, Envelope, GridOrientation)`.
  ``
  `GridGeometry(GridExtent extent, Envelope envelope, GridOrientation orientation)`
  Creates an axis-aligned grid geometry with an extent and an envelope.
  ``
  `GridGeometry(GridExtent extent, PixelInCell anchor, MathTransform gridToCRS, CoordinateReferenceSystem crs)`
  Creates a new grid geometry from a grid extent and a mapping from cell coordinates to "real world" coordinates.
  `protected`
  `GridGeometry(GridGeometry other)`
  Creates a new grid geometry with the same values than the given grid geometry.
  ``
  `GridGeometry(PixelInCell anchor, MathTransform gridToCRS, 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
  `MathTransform`
  `createTransformTo(GridGeometry target, PixelInCell anchor)`
  Creates a transform from cell coordinates in this grid to cell coordinates in the given grid.
  `GridDerivation`
  `derive()`
  Returns an object that can be used for creating a new grid geometry derived from this grid geometry.
  `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.
  `CoordinateReferenceSystem`
  `getCoordinateReferenceSystem()`
  Returns the "real world" coordinate reference system.
  `final int`
  `getDimension()`
  Returns the number of dimensions of the grid.
  `Envelope`
  `getEnvelope()`
  Returns the bounding box of "real world" coordinates for this grid geometry.
  `GridExtent`
  `getExtent()`
  Returns the valid coordinate range of a grid coverage.
  `Optional<GeographicBoundingBox>`
  `getGeographicExtent()`
  Returns the approximate latitude and longitude coordinates of the grid.
  `MathTransform`
  `getGridToCRS(PixelInCell anchor)`
  Returns 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.
  `Instant[]`
  `getTemporalExtent()`
  Returns the start time and end time of coordinates of the grid.
  `int`
  `hashCode()`
  Returns a hash value for this grid geometry.
  `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 parameters specified by the argument are set.
  `GridGeometry`
  `reduce(int... dimensions)`
  Returns a grid geometry that encompass only some dimensions of this grid geometry.
  `String`
  `toString()`
  Returns a string representation of this grid geometry.
  `TreeTable`
  `toTree(Locale locale, int bitmask)`
  Returns a tree representation of some elements of this grid geometry.
  `GridGeometry`
  `translate(long... translation)`
  Returns a grid geometry translated by the given amount of cells compared to this grid.

  ### Methods inherited from class Object

  `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### CRS

    public static final int CRS
    A bitmask to specify the validity of the Coordinate Reference System property.
    See Also:
      - `isDefined(int)`
      - `getCoordinateReferenceSystem()`
      - Constant Field Values

  - ### ENVELOPE

    public static final int ENVELOPE
    A bitmask to specify the validity of the geodetic envelope property.
    See Also:
      - `isDefined(int)`
      - `getEnvelope()`
      - Constant Field Values

  - ### EXTENT

    public static final int EXTENT
    A bitmask to specify the validity of the grid extent property.
    See Also:
      - `isDefined(int)`
      - `getExtent()`
      - Constant Field Values

  - ### GRID_TO_CRS

    public static final int GRID_TO_CRS
    A bitmask to specify the validity of the "grid to CRS" transform.
    See Also:
      - `isDefined(int)`
      - `getGridToCRS(PixelInCell)`
      - Constant Field Values

  - ### RESOLUTION

    public static final int RESOLUTION
    A bitmask to specify the validity of the grid resolution.
    See Also:
      - `isDefined(int)`
      - `getResolution(boolean)`
      - Constant Field Values

  - ### GEOGRAPHIC_EXTENT

    public static final int GEOGRAPHIC_EXTENT
    A bitmask to specify the validity of the geographic bounding box. This information can sometime 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:
      - `getGeographicExtent()`
      - Constant Field Values

  - ### TEMPORAL_EXTENT

    public static final int TEMPORAL_EXTENT
    A bitmask to specify the validity of the temporal period. This information can sometime 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:
      - `getTemporalExtent()`
      - Constant Field Values

  - ### 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:
      - `EXTENT`
      - `getExtent()`

  - ### 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:
      - `ENVELOPE`
      - `getEnvelope()`

  - ### gridToCRS

    protected final 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:
      - `CRS`
      - `getGridToCRS(PixelInCell)`
      - `PixelInCell​.CELL_CENTER`

  - ### 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 equals to the number of CRS dimensions.
    See Also:
      - `RESOLUTION`
      - `getResolution(boolean)`

  - ### 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 can not be obtained.

- ## Constructor Details

  - ### 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(GridExtent extent, PixelInCell anchor, MathTransform gridToCRS, 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.
      `MismatchedDimensionException` - if the math transform and the CRS do not have consistent dimensions.
      `IllegalGridGeometryException` - if the math transform can not compute the geospatial envelope or resolution from the grid extent.

  - ### GridGeometry

    public GridGeometry(PixelInCell anchor, MathTransform gridToCRS, 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 guarantees 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 can not 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 guarantees 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 can not compute the grid extent or the resolution.

  - ### GridGeometry

    @Deprecated public GridGeometry(GridExtent extent, Envelope envelope)
    Deprecated.
    Replaced by `GridGeometry(GridExtent, Envelope, GridOrientation)`.
    Creates a 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 `NaN`.

    This constructor is generally not recommended since creating a grid to CRS from an envelope requires assumption on axis order and axis directions. This constructor assumes that all grid axes are in the same order than CRS axes and no axis is flipped. This straightforward approach often results in the y axis to be oriented toward up, not down as expected in rendered images. Those assumptions are often not suitable. For better control, use one of the constructors expecting a `MathTransform` argument instead. This constructor is provided mostly as a convenience for testing purposes, or when only the extent is known.

    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.
    Throws:
      `NullPointerException` - if `extent` and `envelope` arguments are both null.

  - ### GridGeometry

    public GridGeometry(GridExtent extent, 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:
      - Axis-aligned object on Wikipedia

- ## Method Details

  - ### 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:
      - `reduce(int...)`
      - `GridExtent​.getDimension()`

  - ### 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 MathTransform getGridToCRS(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:

    >     MathTransform  gridToCRS     = gridGeometry.getGridToCRS(PixelInCell.CELL_CENTER);
    >     DirectPosition indicesOfCell = new GeneralDirectPosition(2, 3, 4):
    >     DirectPosition aPixelCenter  = gridToCRS.transform(indicesOfCell, null);

    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`.

  - ### getCoordinateReferenceSystem

    public 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 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`.

  - ### getGeographicExtent

    public Optional<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.

  - ### 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.

  - ### 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`.

  - ### 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.

  - ### isDefined

    public boolean isDefined(int bitmask)
    Returns `true` if all the parameters 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 attributes are defined (i.e. invoking the corresponding method will not thrown an `IncompleteGridGeometryException`).
    Throws:
      `IllegalArgumentException` - if the specified bitmask is not a combination of known masks.
    See Also:
      - `getCoordinateReferenceSystem()`
      - `getEnvelope()`
      - `getExtent()`
      - `getResolution(boolean)`
      - `getGridToCRS(PixelInCell)`

  - ### 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:

    >     GridGeometry gg = ...;
    >     Envelope areaOfInterest = ...;
    >     gg = gg.derive().rounding(GridRoundingMode.ENCLOSING)
    >                     .subgrid(areaOfInterest).build();

    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 `reduce(int...)`.
    Returns:
      an object for deriving a grid geometry from `this`.

  - ### translate

    public GridGeometry translate(long... translation)
    Returns a grid geometry translated by the given amount of cells compared to this grid. 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.1
    See Also:
      - `GridExtent​.translate(long...)`

  - ### reduce

    public GridGeometry reduce(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 can not 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.
    See Also:
      - `GridExtent​.getSubspaceDimensions(int)`
      - `GridExtent​.reduceDimension(int[])`
      - `CRS​.reduce(CoordinateReferenceSystem, int...)`

  - ### createTransformTo

    public MathTransform createTransformTo(GridGeometry target, PixelInCell anchor) throws 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:
      `TransformException` - if the math transform can not 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 equals to this grid geometry.
    See Also:
      - `ComparisonMode​.STRICT`

  - ### 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:
      - `Utilities​.deepEquals(Object, Object, ComparisonMode)`

  - ### 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.