Class WorldFileStore

All Implemented Interfaces:
AutoCloseable, ResourceOnFileSystem, StoreResource, Resource, Localized
Direct Known Subclasses:
MultiImageStore, SingleImageStore, WritableStore

public class WorldFileStore extends PRJDataStore
A data store which creates grid coverages from Image I/O readers using World File convention. Georeferencing is defined by two auxiliary files having the same name than the image file but different suffixes:
  • A text file containing the coefficients of the affine transform mapping pixel coordinates to geodesic coordinates. The reader expects one coefficient per line, in the same order than the order expected by the AffineTransform(double[]) constructor, which is scaleX, shearY, shearX, scaleY, translateX, translateY. The reader looks for a file having the following suffixes, in preference order:
    1. The first letter of the image file extension, followed by the last letter of the image file extension, followed by 'w'. Example: "tfw" for "tiff" images, and "jgw" for "jpeg" images.
    2. The extension of the image file with a 'w' appended.
    3. The "wld" extension.
  • A text file containing the Coordinate Reference System (CRS) definition in Well Known Text (WKT) syntax. The reader looks for a file having the ".prj" extension.
Every auxiliary text file are expected to be encoded in UTF-8 and every numbers are expected to be formatted in US locale.

Type of input objects

The StorageConnector input should be an instance of the following types: Path, File, URL or URI. Other types such as ImageInputStream are also accepted but in those cases the auxiliary files cannot be read. For any input of unknown type, this data store first checks if an ImageReader accepts the input type directly. If none is found, this data store tries to create an input stream from the input object.

The storage input object may also be an ImageReader instance ready for use (i.e. with its input set to a non-null value). In that case, this data store will use the given image reader as-is. The image reader will be disposed and its input closed (if AutoCloseable) when this data store is closed.

Handling of multi-image files

Because some image formats can store an arbitrary number of images, this data store is considered as an aggregate with one resource per image. All image should have the same size and all resources will share the same GridGeometry. However, this base class does not implement the Aggregate interface directly in order to give a chance to subclasses to implement GridCoverageResource directly when the format is known to support only one image per file.
Since:
1.2
Version:
1.3
  • Field Details

    • KNOWN_FORMATS

      private static final String[] KNOWN_FORMATS
      Image I/O format names (ignoring case) for which we have an entry in the SpatialMetadata database.
      See Also:
    • MAIN_IMAGE

      static final int MAIN_IMAGE
      Index of the main image. This is relevant only with formats capable to store an arbitrary number of images. Current implementation assumes that the main image is always the first one, but it may become configurable in a future version if useful.
      See Also:
    • DEFAULT_SUFFIX

      private static final String DEFAULT_SUFFIX
      The default World File suffix when it cannot be determined from URIDataStore.location. This is a GDAL convention.
      See Also:
    • CELL_ANCHOR

      static final org.opengis.referencing.datum.PixelInCell CELL_ANCHOR
      The "cell center" versus "cell corner" interpretation of translation coefficients. The ESRI specification said that the coefficients map to pixel center.
    • suffix

      final String suffix
      The filename extension (may be an empty string), or null if unknown. It does not include the leading dot.
    • suffixWLD

      private String suffixWLD
      The filename extension for the auxiliary "world file". For the TIFF format, this is typically "tfw". This is computed as a side-effect of readWorldFile().
    • reader

      private ImageReader reader
      The image reader, set by the constructor and cleared when the store is closed. May also be null if the store is initially write-only, in which case a reader may be created the first time than an image is read.
      See Also:
    • toClose

      private Closeable toClose
      The object to close when WorldFileStore is closed. It may be a different object than reader input or writer output, because some ImageInputStream.close() implementations in the standard Java javax.imageio.stream package do not close the underlying stream.

      The type is Closeable instead of AutoCloseable because the former is idempotent: invoking Closeable.close() many times has no effect. By contrast AutoCloseable does not offer this guarantee. Because it is hard to know what ImageInputStream.close() will do, we need idempotent toClose for safety. Note that ImageInputStream.close() violates the idempotent contract of Closeable.close(), so an additional check will be necessary in our close() implementation.

      See Also:
    • width

      private int width
      Width and height of the main image. The gridGeometry is assumed valid only for images having this size.
      See Also:
    • height

      private int height
      Width and height of the main image. The gridGeometry is assumed valid only for images having this size.
      See Also:
    • gridGeometry

      private GridGeometry gridGeometry
      The conversion from pixel center to CRS, or null if none or not yet computed. The grid extent has the size given by width and height.
      See Also:
    • components

      private WorldFileStore.Components components
      All images in this resource, created when first needed. Elements in this list will also be created when first needed.
      See Also:
    • metadata

      private org.opengis.metadata.Metadata metadata
      The metadata object, or null if not yet created.
      See Also:
    • identifiers

      final Map<String,Boolean> identifiers
      Identifiers used by a resource. Identifiers must be unique in the data store, so after an identifier has been used it cannot be reused anymore even if the resource having that identifier has been removed. Values associated to identifiers tell whether the resource still exist.
      See Also:
  • Constructor Details

    • WorldFileStore

      public WorldFileStore(WorldFileStoreProvider provider, StorageConnector connector) throws DataStoreException, IOException
      Creates a new store from the given file, URL or stream.
      Parameters:
      provider - the factory that created this DataStore instance, or null if unspecified.
      connector - information about the storage (URL, stream, etc).
      Throws:
      DataStoreException - if an error occurred while opening the stream.
      IOException - if an error occurred while creating the image reader instance.
    • WorldFileStore

      WorldFileStore(FormatFinder format, boolean readOnly) throws DataStoreException, IOException
      Creates a new store from the given file, URL or stream.
      Parameters:
      format - information about the storage (URL, stream, etc) and the reader/writer to use.
      readOnly - true if the store should be open in read-only mode, ignoring format. This is a workaround for RFE #4093999 in Sun's bug database, for allowing us to invoke
      invalid reference
      FormatFinder#cleanup()
      when invoked from the public constructor.
      Throws:
      DataStoreException - if an error occurred while opening the stream.
      IOException - if an error occurred while creating the image reader instance.
  • Method Details

    • configureReader

      private void configureReader()
      Sets the locale to use for warning messages, if supported. If the reader does not support the locale, the reader's default locale will be used.
    • getWorldFileSuffix

      private String getWorldFileSuffix()
      Returns the preferred suffix for the auxiliary world file. For TIFF images, this is "tfw". This method tries to use the same case (lower-case or upper-case) than the suffix of the main file.
    • readWorldFile

      private AffineTransform2D readWorldFile() throws IOException, DataStoreException
      Reads the "World file" by searching for an auxiliary file with a suffix inferred from the suffix of the main file. This method tries suffixes with the following conventions, in preference order.
      1. First letter of main file suffix, followed by last letter, followed by 'w'.
      2. Full suffix of the main file followed by 'w'.
      3. "wld".
      Returns:
      the "World file" content as an affine transform, or null if none was found.
      Throws:
      IOException - if an I/O error occurred.
      DataStoreException - if the auxiliary file content cannot be parsed.
    • readWorldFile

      private AffineTransform2D readWorldFile(String wld) throws IOException, DataStoreException
      Reads the "World file" by parsing an auxiliary file with the given suffix.
      Parameters:
      wld - suffix of the auxiliary file.
      Returns:
      the "World file" content as an affine transform, or null if none was found.
      Throws:
      IOException - if an I/O error occurred.
      DataStoreException - if the file content cannot be parsed.
    • resources

      final Resources resources()
      Returns the localized resources for producing warnings or error messages.
    • errors

      private Errors errors()
      Returns the localized resources for producing error messages.
    • getImageFormat

      public String[] getImageFormat(boolean asMimeType)
      Returns the Image I/O format names or MIME types of the image read by this data store. More than one names may be returned if the format has aliases or if the MIME type has legacy types (e.g. official "image/png" and legacy "image/x-png").
      Parameters:
      asMimeType - true for MIME types, or false for format names.
      Returns:
      the requested names, or an empty array if none or unknown.
    • getComponentFiles

      public Path[] getComponentFiles() throws DataStoreException
      Returns paths to the main file together with auxiliary files.
      Specified by:
      getComponentFiles in interface ResourceOnFileSystem
      Overrides:
      getComponentFiles in class PRJDataStore
      Returns:
      paths to the main file and auxiliary files, or an empty array if unknown.
      Throws:
      DataStoreException - if the URI cannot be converted to a Path.
    • getGridGeometry

      final GridGeometry getGridGeometry(int index) throws IOException, DataStoreException
      Gets the grid geometry for image at the given index. This method should be invoked only once per image, and the result cached.
      Parameters:
      index - index of the image for which to read the grid geometry.
      Returns:
      grid geometry of the image at the given index.
      Throws:
      IndexOutOfBoundsException - if the image index is out of bounds.
      IOException - if an I/O error occurred.
      DataStoreException - if the *.prj or *.tfw auxiliary file content cannot be parsed.
    • setGridGeometry

      String setGridGeometry(int index, GridGeometry gg) throws IOException, DataStoreException
      Sets the store-wide grid geometry when a new coverage is written. The WritableStore implementation is responsible for making sure that the new grid geometry is compatible with preexisting grid geometry.
      Parameters:
      index - index of the image for which to set the grid geometry.
      gg - the new grid geometry.
      Returns:
      suffix of the "world file", or null if the image cannot be written.
      Throws:
      IOException
      DataStoreException
    • getMetadata

      public org.opengis.metadata.Metadata getMetadata() throws DataStoreException
      Returns information about the data store as a whole.
      Specified by:
      getMetadata in interface Resource
      Specified by:
      getMetadata in class DataStore
      Returns:
      information about resources in the data store. Should not be null.
      Throws:
      DataStoreException - if an error occurred while reading the metadata.
      See Also:
    • components

      public Collection<? extends GridCoverageResource> components() throws DataStoreException
      Returns all images in this store. Note that fetching the size of the list is a potentially costly operation.
      Returns:
      list of images in this store.
      Throws:
      DataStoreException
    • components

      final WorldFileStore.Components components(boolean create, int numImages)
      Returns all images in this store, or null if none and create is false.
      Parameters:
      create - whether to create the component list if it was not already created.
      numImages - number of images, or any negative value if unknown.
    • remove

      void remove(Resource resource) throws DataStoreException
      Invoked by WorldFileStore.Components when the caller want to remove a resource. The actual implementation is provided by WritableStore.
      Throws:
      DataStoreException
    • createImageResource

      WorldFileResource createImageResource(int index) throws DataStoreException, IOException
      Creates a GridCoverageResource for the specified image. This method is invoked by WorldFileStore.Components when first needed and the result is cached by the caller.
      Parameters:
      index - index of the image for which to create a resource.
      Returns:
      resource for the image identified by the given index.
      Throws:
      IndexOutOfBoundsException - if the image index is out of bounds.
      DataStoreException
      IOException
    • isComponentHidden

      boolean isComponentHidden()
      Whether the component of this data store is used only as a delegate. This is false when the components will be given to the user, or true if the singleton component will be used only for internal purposes.
    • prepareReader

      ImageReader prepareReader(ImageReader current) throws IOException
      Prepares an image reader compatible with the writer and sets its input. This method is invoked for switching from write mode to read mode. Its actual implementation is provided by WritableResource.
      Parameters:
      current - the current image reader, or null if none.
      Returns:
      the image reader to use, or null if none.
      Throws:
      IOException - if an error occurred while preparing the reader.
    • getCurrentReader

      final ImageReader getCurrentReader()
      Returns the reader without doing any validation. The reader may be null either because the store is closed or because the store is initially opened in write-only mode. The reader may have a null input.
    • reader

      final ImageReader reader() throws DataStoreException, IOException
      Returns the reader if it has not been closed.
      Throws:
      DataStoreClosedException - if this data store is closed.
      IOException - if an error occurred while preparing the reader.
      DataStoreException
    • close

      public void close() throws DataStoreException
      Closes this data store and releases any underlying resources.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in class DataStore
      Throws:
      DataStoreException - if an error occurred while closing this data store.
      See Also: