Class GridGeometry

  • All Implemented Interfaces:
    Serializable

    public class GridGeometry
    extends Object
    implements Serializable
    Valid extent of grid coordinates together with the transform from those grid coordinates to real world coordinates. Grid­Geometry 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 grid geometry know nothing about Rendered­Image, but Grid­Coverage2D does and may use that information for providing a missing grid extent. By default, any request for an undefined property will throw an Incomplete­Grid­Geometry­Exception. In order to check if a property is defined, use is­Defined(int).

    Grid­Geometry instances are immutable and thread-safe. The same instance can be shared by different Grid­Coverage instances.

    Since:
    1.0
    See Also:
    Serialized Form

    Defined in the sis-feature module

    • Constructor Detail

      • 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, grid­To­CRS or crs arguments shall be non-null. If grid­To­CRS is non-null, then anchor shall be non-null too with one of the following values:
        • Pixel­In­Cell​.CELL_CENTER if conversions of cell indices by grid­To­CRS give "real world" coordinates close to the center of each cell.
        • Pixel­In­Cell​.CELL_CORNER if conversions of cell indices by grid­To­CRS 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 Grid­Envelope interface in a future Apache SIS version. This is pending GeoAPI update. In addition, the Pixel­In­Cell 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.
        grid­To­CRS - 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:
        Null­Pointer­Exception - if extent, grid­To­CRS and crs arguments are all null.
        Mismatched­Dimension­Exception - if the math transform and the CRS do not have consistent dimensions.
        Illegal­Grid­Geometry­Exception - 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 grid­To­CRS or envelope arguments shall be non-null. If grid­To­CRS 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 get­Envelope() will be equal to the given envelope. The envelope stored in the new Grid­Geometry 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 Grid­Extent. The rules for deciding whether coordinates should be rounded toward nearest integers, to floor or to ceil values are specified by the Grid­Rounding­Mode 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 Pixel­In­Cell 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.
        grid­To­CRS - 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 Grid­Geometry will be equal to this specified envelope.
        rounding - controls behavior of rounding from floating point values to integers.
        Throws:
        Illegal­Grid­Geometry­Exception - if the math transform can not compute the grid extent or the resolution.
      • GridGeometry

        public GridGeometry​(GridExtent extent,
                            Envelope envelope)
        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 Na­N.

        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 Math­Transform 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:
        Null­Pointer­Exception - if extent and envelope arguments are both null.
    • Method Detail

      • getExtent

        public GridExtent getExtent()
        Returns the valid coordinate range of a grid coverage. The lowest valid grid coordinate is zero for Buffered­Image, but may be non-zero for arbitrary Rendered­Image. 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 Grid­Envelope interface in a future Apache SIS version. This is pending GeoAPI update.
        Returns:
        the valid extent of grid coordinates (never null).
        Throws:
        Incomplete­Grid­Geometry­Exception - if this grid geometry has no extent — i.e. is­Defined(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:
        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:
        Illegal­Argument­Exception - if the given anchor is not a known code list value.
        Incomplete­Grid­Geometry­Exception - if this grid geometry has no transform — i.e. is­Defined(GRID_TO_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:
        Incomplete­Grid­Geometry­Exception - if this grid geometry has no envelope — i.e. is­Defined(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 Incomplete­Grid­Geometry­Exception because the geographic extent may be absent even with a complete grid geometry. This is because grid geometries are not required to have an 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 is­Conversion­Linear(i) returns false), then resolution[i] is set to one of the following values:

        • Double​.Na­N if allow­Estimates is false.
        • An arbitrary representative resolution otherwise. Current implementation computes the resolution at grid center, but different implementations may use alternative algorithms.
        Parameters:
        allow­Estimates - whether to provide some values even for resolutions that are not constant factors.
        Returns:
        an estimation of the grid resolution (never null).
        Throws:
        Incomplete­Grid­Geometry­Exception - if this grid geometry has no resolution — i.e. is­Defined(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.
      • derive

        public GridDerivation derive()
        Returns an object that can be used for creating a new grid geometry derived from this grid geometry. Grid­Derivation does not change the state of this Grid­Geometry 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 Grid­Derivation instance can be used only once and should be used in a single thread. Grid­Derivation 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.
      • reduce

        public GridGeometry reduce​(int... dimensions)
        Returns a grid geometry that encompass only some dimensions of the grid geometry. The specified dimensions will be copied into a new grid geometry. 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:
        Index­Out­Of­Bounds­Exception - if an index is out of bounds.
        See Also:
        Grid­Extent​.get­Subspace­Dimensions(int), Grid­Extent​.reduce(int...), CRS​.reduce(Coordinate­Reference­System, int...)
      • 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:
        hash­Code in class Object
      • equals

        public boolean equals​(Object object)
        Compares the specified object with this grid geometry for equality.
        Overrides:
        equals in class Object
        Parameters:
        object - the object to compare with.
        Returns:
        true if the given object is equals to this grid geometry.
      • 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 to­Tree(Locale, int) with at least EXTENT, ENVELOPE and CRS flags. Whether more flags are present or not is unspecified.
        Overrides:
        to­String 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 purpose only 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.