java.lang.Object
org.apache.sis.internal.referencing.j2d.Tile
All Implemented Interfaces:
Serializable

public class Tile extends Object implements Serializable
A tile identified by a location, a dimension and a subsampling. This class can be used for constructing a mosaic or a pyramid of images. While the Javadoc discusses image I/O operations, this Tile class is not restricted to imagery. This class is also used for managing tiles in a datum shift file encoded in NTv2 format.

Each tile contains the following:

  • A format name or a provider of ImageReader (optional). The same format is typically used for every tiles, but this is not mandatory. An image reader can be instantiated before a tile is read.
  • An image input (optional), typically a Path or URL. The input is often different for every tile to be read, but this is not mandatory. For example, tiles could be stored at different image index in the same file.
  • An image index to be given to ImageReader.read(int) for reading the tile. This index is often 0.
  • The upper-left corner in the destination image as a Point, or the upper-left corner together with the image size as a Rectangle. If the upper-left corner has been given as a point, then the width and height may be obtained from the image reader when first needed, which may have a slight performance cost. If the upper-left corner has been given as a rectangle instead, then this performance cost is avoided but the user is responsible for the accuracy of the information provided.
    NOTE: the upper-left corner is the location of this tile in the destination image when no destination offset are specified. If the user specified a destination offset, then the tile location will be translated accordingly for the image being read.
  • The subsampling relative to the tile having the best resolution. This is not the subsampling to apply when reading this tile, but rather the subsampling that we would need to apply on the tile having the finest resolution in order to produce an image equivalent to this tile. The subsampling is (1,1) for the tile having the finest resolution, (2,3) for an overview having half the width and third of the height for the same geographic extent, etc. (note that overviews are not required to have the same geographic extent - the above is just an example).
    NOTE 1: the semantic assumes that overviews are produced by subsampling, not by interpolation or pixel averaging. The latter are not prohibited, but doing so introduce some subsampling-dependent variations in images read, which would not be what we would expect from a strictly compliant ImageReader.
    NOTE 2: tile location and region coordinates should be specified in the overview pixel units - they should not be pre-multiplied by subsampling. This multiplication should be performed automatically by a TileManager when comparing regions from tiles at different subsampling levels.
The tiles are not required to be arranged on a regular grid, but performances may be better if they are. TileOrganizer is responsible for analyzing the layout of a collection of tiles.

Multi-threading

This class is thread-safe. In addition Tile instances can be considered as immutable after construction. However, some properties may be available only after the tiles have been processed by a TileOrganizer, or only after fetchSize() has been invoked.
Since:
1.1
Version:
1.1
See Also:
  • Field Details

    • serialVersionUID

      private static final long serialVersionUID
      For cross-version compatibility during serialization.
      See Also:
    • x

      private int x
      The upper-left corner in the mosaic (destination image). Should be considered as final, since this class is supposed to be mostly immutable. However, the value can be changed by translate(int, int) before the Tile instance is made public.
      See Also:
    • y

      private int y
      The upper-left corner in the mosaic (destination image). Should be considered as final, since this class is supposed to be mostly immutable. However, the value can be changed by translate(int, int) before the Tile instance is made public.
      See Also:
    • width

      private int width
      The size of the tile, or 0 if not yet computed.
      See Also:
    • height

      private int height
      The size of the tile, or 0 if not yet computed.
      See Also:
    • xSubsampling

      private int xSubsampling
      The subsampling relative to the tile having the finest resolution. If this tile is the one with finest resolution, then the value shall be 1. Should never be 0 or negative, except if the value has not yet been computed.

      This field should be considered as final. It is not final only because TileOrganizer may compute this value automatically.

      See Also:
    • ySubsampling

      private int ySubsampling
      The subsampling relative to the tile having the finest resolution. If this tile is the one with finest resolution, then the value shall be 1. Should never be 0 or negative, except if the value has not yet been computed.

      This field should be considered as final. It is not final only because TileOrganizer may compute this value automatically.

      See Also:
    • gridToCRS

      private AffineTransform gridToCRS
      The "grid to real world" transform, used by TileOrganizer in order to compute the region for this tile. This field is set to null when TileOrganizer's work is in progress, and set to a new value on completion.

      Note: TileOrganizer really needs a new instance for each tile. No caching allowed before TileOrganizer processing. Caching is allowed after TileOrganizer processing is completed.

  • Constructor Details

    • Tile

      public Tile(Point location, Dimension subsampling)
      Creates a tile for the given tile location. This constructor can be used when the size of the tile is unknown. This tile size will be fetched automatically by fetchSize() when getSize() or getRegion() is invoked for the first time.
      Parameters:
      location - the upper-left corner in the mosaic (destination image).
      subsampling - the subsampling relative to the tile having the finest resolution, or null if none. If non-null, width and height shall be strictly positive. This argument can be understood as pixel size relative to finest resolution.
    • Tile

      public Tile(Rectangle region, Dimension subsampling)
      Creates a tile for the given region. This constructor should be used when the size of the tile is known. This information avoid the cost of fetching the size when getSize() or getRegion() is first invoked.
      Parameters:
      region - the region (location and size) in the mosaic (destination image).
      subsampling - the subsampling relative to the tile having the finest resolution, or null if none. If non-null, width and height shall be strictly positive. This argument can be understood as pixel size relative to finest resolution.
      Throws:
      IllegalArgumentException - if the given region is empty.
    • Tile

      public Tile(Rectangle region, AffineTransform gridToCRS)
      Creates a tile for the given region and "grid to real world" transform. This constructor can be used when the location of the tile is unknown. The location and subsampling will be computed automatically when this tile will be processed by a TileOrganizer.

      When using this constructor, the getLocation(), getRegion() and getSubsampling() methods will throw an IllegalStateException until this tile has been processed by a TileOrganizer, which will compute those values automatically.

      Parameters:
      region - the tile region, or null if unknown. The (x,y location of this region is typically (0,0). The final location will be computed when this tile will be given to a TileOrganizer.
      gridToCRS - the "grid to real world" transform mapping pixel upper left corner.
    • Tile

      Tile(AffineTransform gridToCRS, Rectangle region)
      Creates a new tile for the given final transform. This is used for storing TileOrganizer results.
  • Method Details

    • ensureDefined

      private void ensureDefined() throws IllegalStateException
      Checks if the location, region, and subsampling can be returned. Throws an exception if this tile has been created without location and not yet processed by TileOrganizer.
      Throws:
      IllegalStateException
    • getLocation

      public Point getLocation() throws IllegalStateException
      Returns the tile upper-left corner coordinates in the mosaic.
      Returns:
      the tile upper-left corner.
      Throws:
      IllegalStateException - if this tile has been created without location and has not yet been processed by TileOrganizer.
      See Also:
    • getSize

      public Dimension getSize() throws IOException
      Returns the image size. If this tile has been created with the constructor expecting a rectangle, then the dimension of that rectangle is returned. Otherwise fetchSize() is invoked and the result is cached for future usage.

      At the difference of getLocation() and getRegion(), this method never throw IllegalStateException because the tile size does not depend on the processing performed by TileOrganizer.

      Returns:
      the tile size.
      Throws:
      IOException - if an I/O operation was required for fetching the tile size and that operation failed.
      IllegalStateException - if this class does not have sufficient information for providing a tile size.
    • fetchSize

      protected Dimension fetchSize() throws IOException
      Invoked when the tile size need to be read or computed. The default implementation throws IllegalStateException since this base class has no information for computing a tile size. Subclasses can override and, for example, get the size with ImageReader.getWidth(int) and ImageReader.getHeight(int).
      Returns:
      the tile size.
      Throws:
      IOException - if an I/O operation was required for fetching the tile size and that operation failed.
      IllegalStateException - if this class does not have sufficient information for providing a tile size.
    • getRegion

      public Rectangle getRegion() throws IllegalStateException, IOException
      Returns the upper-left corner location in the mosaic together with the tile size. If this tile has been created with the constructor expecting a rectangle, a copy of the specified rectangle is returned. Otherwise fetchSize() is invoked and the result is cached for future usage.
      Returns:
      the region in the mosaic (destination image).
      Throws:
      IOException - if an I/O operation was required for fetching the tile size and that operation failed.
      IllegalStateException - if this tile has been created without location and has not yet been processed by TileOrganizer, of if this tile does not have enough information for providing a tile size.
      See Also:
    • getRegionOnFinestLevel

      public Rectangle getRegionOnFinestLevel() throws IOException
      Returns the region multiplied by the subsampling. This is this tile coordinates in the units of the tile having the finest resolution, as opposed to other methods which are always in units relative to this tile.
      Returns:
      the region in units relative to the tile having the finest resolution.
      Throws:
      IOException - if an I/O operation was required for fetching the tile size and that operation failed.
      ArithmeticException - if the region exceeded the capacity of 32-bits integer type.
      IllegalStateException - if this tile has been created without location and has not yet been processed by TileOrganizer, of if this tile does not have enough information for providing a tile size.
    • setRegionOnFinestLevel

      final void setRegionOnFinestLevel(Rectangle region) throws ArithmeticException
      Invoked by TileOrganizer only. No other caller allowed. setSubsampling(Dimension) must be invoked prior this method.

      Note that invoking this method usually invalidate gridToCRS. Calls to this method should be followed by translate(int, int) for fixing the "gridToCRS" value.

      Parameters:
      region - the region to assign to this tile in units of tile having finest resolution.
      Throws:
      ArithmeticException - if setSubsampling(Dimension) method has not be invoked.
    • getSubsampling

      public Dimension getSubsampling() throws IllegalStateException
      Returns the subsampling relative to the tile having the finest resolution. The return value can be interpreted as "pixel size" relative to tiles having the finest resolution. This method never return null, and the width and height shall never be smaller than 1.
      Returns:
      the subsampling along x and y axes.
      Throws:
      IllegalStateException - if this tile has been created without location and has not yet been processed by TileOrganizer.
      See Also:
    • setSubsampling

      final void setSubsampling(Dimension subsampling) throws IllegalStateException
      Sets the subsampling to the given dimension. Invoked by constructors and TileOrganizer only.
      Throws:
      IllegalStateException
    • getPendingGridToCRS

      final AffineTransform getPendingGridToCRS()
      If the user supplied transform is waiting for processing by TileOrganizer, returns it. Otherwise returns null. This method is for internal usage by TileOrganizer only.

      This method clears the gridToCRS field before to return. This is a way to tell that processing is in progress, and also a safety against transform usage while it may become invalid.

      Returns:
      the transform, or null if none. This method does not clone the returned value - TileOrganizer will reference and modify directly that transform.
    • getGridToCRS

      public AffineTransform2D getGridToCRS() throws IllegalStateException
      Returns the "grid to real world" transform, or null if unknown. This transform is derived from the value given to the constructor, but may not be identical since it may have been translated in order to get a uniform grid geometry for every tiles.
      Tip: the World File coefficients of this tile (i.e. the grid to CRS transform that we would have if the pixel in the upper-left corner always had indices (0,0)) can be computed as below:
      Returns:
      the "grid to real world" transform mapping pixel upper left corner, or null if undefined.
      Throws:
      IllegalStateException - if this tile has been created without location and has not yet been processed by TileOrganizer.
    • setGridToCRS

      final void setGridToCRS(AffineTransform at) throws IllegalStateException
      Sets the new "grid to real world" transform to use after the translation performed by translate(int, int), if any. The given instance should be immutable; it will not be cloned.
      Parameters:
      at - the "grid to real world" transform mapping pixel upper left corner.
      Throws:
      IllegalStateException - if another transform was already assigned to this tile.
    • translate

      final void translate(int dx, int dy)
      Translates this tile. For internal usage by TileOrganizer only.

      Reminder: setGridToCRS(AffineTransform) should be invoked after this method.

      Parameters:
      dx - the translation to apply on x values (often 0).
      dy - the translation to apply on y values (often 0).
    • getName

      public Optional<String> getName(boolean input)
      Returns a name for the tile format or tile input, or an empty value if none. The format name can be inferred for example from an ImageReaderSpi. The input name is typically (but not necessarily) a file name or URL.
      Parameters:
      input - false for the file format name, or true for the file input name.
      Returns:
      the format or input name.
    • getImageIndex

      public int getImageIndex()
      Returns the image index to be given to the image reader for reading this tile. The default implementation returns 0.
      Returns:
      the image index, numbered from 0.
      See Also:
    • toString

      public String toString()
      Returns a string representation of this tile for debugging purposes.
      Overrides:
      toString in class Object
      Returns:
      a string representation of this tile.
    • toString

      static String toString(Collection<Tile> tiles, int maximum)
      Returns a string representation of a collection of tiles. The tiles are formatted in a table in iteration order.

      This method is not public because it can consume a large amount of memory (the underlying StringBuffer can be quite large). Users are encouraged to use the method expecting a Writer, which may be expensive too but less than this method.

      Parameters:
      tiles - the tiles to format in a table.
      maximum - the maximum number of tiles to format. If there is more tiles, a message will be formatted below the table. A reasonable value like 5000 is recommended because attempt to format millions of tiles leads to OutOfMemoryError.
      Returns:
      a string representation of the given tiles as a table.
    • writeTable

      public static void writeTable(Collection<Tile> tiles, Writer out, int maximum) throws IOException
      Formats a collection of tiles in a table. The tiles are appended in iteration order.
      Parameters:
      tiles - the tiles to format in a table.
      out - where to write the table.
      maximum - the maximum number of tiles to format. If there is more tiles, a message will be formatted below the table. A reasonable value like 5000 is recommended because attempt to format millions of tiles leads to OutOfMemoryError.
      Throws:
      IOException - if an error occurred while writing to the given writer.