/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2001-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.coverage.io; // J2SE dependencies import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Locale; import javax.imageio.ImageIO; import javax.imageio.ImageReader; // OpenGIS dependencies import org.opengis.coverage.grid.GridCoverage; import org.opengis.coverage.grid.GridRange; import org.opengis.geometry.Envelope; import org.opengis.referencing.crs.CoordinateReferenceSystem; // Geotools dependencies import org.geotools.factory.Hints; import org.geotools.resources.i18n.ErrorKeys; import org.geotools.coverage.GridSampleDimension; import org.geotools.image.io.text.TextMetadataParser; /** * An implementation of {@link AbstractGridCoverageReader} using informations parsed by a * {@link TextMetadataParser} object. This reader is typically used for format that * stores pixel values and geographic metadata in separated files. For example, * pixel values may be stored as a PNG images ou a RAW binary file, and geographic * metadata (coordinate system, geographic location, etc.) may be stored in a separated * text file. The text file is parsed by a {@link TextMetadataParser} object, while the pixel * values are read by a {@link ImageReader} object. * * @since 2.2 * @source $URL$ * @version $Id$ * @author Martin Desruisseaux (IRD) * @author Cédric Briançon * * @deprecated To be refactored (work in progress). */ public class ExoreferencedGridCoverageReader extends AbstractGridCoverageReader { /** * The object to use for parsing the meta-data. */ protected final TextMetadataParser metadata; /** * File extension (by default the same than format name). */ private final String extension; /** * Constructs a new {@code ExoreferencedGridCoverageReader} * using the specified {@link TextMetadataParser}. * * @param hints The factory hints to use. * @param formatName The name for this format. This format name should be * understood by {@link ImageIO#getImageReadersByFormatName(String)}, * unless {@link #getImageReaders} is overridden. * @param parser The {@link TextMetadataParser} to use for reading geographic metadata. */ public ExoreferencedGridCoverageReader(final Hints hints, final String formatName, final TextMetadataParser parser) { this(hints, formatName, formatName, parser); } /** * Constructs a new {@code ExoreferencedGridCoverageReader} * using the specified {@link MetadataBuilder}. * * @param hints The factory hints to use. * @param formatName The name for this format. This format name should be * understood by {@link ImageIO#getImageReadersByFormatName(String)}, * unless {@link #getImageReaders} is overridden. * @param extension Filename's extensions for file of this format. * @param parser The {@link TextMetadataParser} to use for reading geographic metadata. */ public ExoreferencedGridCoverageReader(final Hints hints, final String formatName, final String extension, final TextMetadataParser parser) { super(hints, formatName); metadata = parser; if (parser == null) { throw new IllegalArgumentException(); } this.extension = extension; } /** * Restores the coverage reader to its initial state. * * @throws IOException if an error occurs while disposing resources. */ @Override public synchronized void reset() throws IOException { metadata.clear(); super.reset(); } /** * Sets the current {@linkplain Locale locale} of this grid coverage reader to the given value. * A value of {@code null} removes any previous setting, and indicates that the reader should * localize as it sees fit. */ @Override public synchronized void setLocale(final Locale locale) { super.setLocale(locale); } /** * Sets the input source to the given object. The input must be {@link File} or an * {@link URL} object. The input source must be the <em>metadata</em> file or URL. * The image file or URL will be derived from the metadata filename by a call to * {@link #toImageFileName}, which may be overridden. * * @param input The {@link File} or {@link URL} to be read. * @param seekForwardOnly if {@code true}, grid coverages and metadata may only * be read in ascending order from the input source. * @throws IOException if an I/O operation failed. * @throws IllegalArgumentException if input is not an instance * of a classe supported by this reader. */ @Override public synchronized void setInput(Object input, final boolean seekForwardOnly) throws IOException { if (input instanceof File) { final File file = (File) input; metadata.clear(); metadata.load(file); input = new File(file.getParent(), toImageFileName(file.getName())); } else if (input instanceof URL) { final URL url = (URL) input; metadata.clear(); metadata.load(url); // TODO: invokes rename(String) here and rebuild the URL. throw new UnsupportedOperationException("URL support not yet implemented"); } else { throw new IllegalArgumentException(getString(ErrorKeys.NO_IMAGE_READER)); } super.setInput(input, seekForwardOnly); } /** * Returns the filename for image data. This method is invoked by {@link #setInput} after * {@link #metadata} has been loaded. Default implementation just replace the file extension * by the {@code extension} argument specified to the constructor. * * @param filename The filename part of metadata file. This is the filename part * of the file supplied by users to {@link #setInput}. * @return The filename to use for for the image file. The directory is assumed * to be the same than the metadata file. */ protected String toImageFileName(String filename) { int ext = filename.lastIndexOf('.'); if (ext < 0) { ext = filename.length(); } return filename.substring(0, ext) + '.' + extension; } /** * Returns the coordinate system for the {@link GridCoverage} to be read. * The default implementation invokes * <code>{@linkplain #metadata}.{@linkplain MetadataBuilder#getCoordinateReferenceSystem() * getCoordinateReferenceSystem()}</code>. * * @param index The index of the image to be queried. * @return The coordinate system for the {@link GridCoverage} at the specified index. * @throws IllegalStateException if the input source has not been set. * @throws IndexOutOfBoundsException if the supplied index is out of bounds. * @throws IOException if an error occurs reading the width information from * the input source. */ public synchronized CoordinateReferenceSystem getCoordinateReferenceSystem(final int index) throws IOException { checkImageIndex(index); //return metadata.getCoordinateReferenceSystem(); return null; } /** * Returns the envelope for the {@link GridCoverage} to be read. * The default implementation invokes * <code>{@linkplain #metadata}.{@linkplain MetadataBuilder#getEnvelope() getEnvelope()}</code>. * * @param index The index of the image to be queried. * @return The envelope for the {@link GridCoverage} at the specified index. * @throws IllegalStateException if the input source has not been set. * @throws IndexOutOfBoundsException if the supplied index is out of bounds. * @throws IOException if an error occurs reading the width information from * the input source. */ public synchronized Envelope getEnvelope(final int index) throws IOException { checkImageIndex(index); return null; } /** * Returns the grid range for the {@link GridCoverage} to be read. * The default implementation invokes * <code>{@linkplain #metadata}.{@linkplain MetadataBuilder#getGridRange() getGridRange()}</code>. * * @param index The index of the image to be queried. * @return The grid range for the {@link GridCoverage} at the specified index. * @throws IllegalStateException if the input source has not been set. * @throws IndexOutOfBoundsException if the supplied index is out of bounds. * @throws IOException if an error occurs reading the width information from * the input source. */ @Override public synchronized GridRange getGridRange(final int index) throws IOException { checkImageIndex(index); return null; } /** * Returns the sample dimensions for each band of the {@link GridCoverage} * to be read. If sample dimensions are not known, then this method returns * {@code null}. The default implementation invokes * <code>{@linkplain #metadata}.{@linkplain MetadataBuilder#getSampleDimensions() * getSampleDimensions()}</code>. * * @param index The index of the image to be queried. * @return The category lists for the {@link GridCoverage} at the specified index. * This array's length must be equals to the number of bands in {@link GridCoverage}. * @throws IllegalStateException if the input source has not been set. * @throws IndexOutOfBoundsException if the supplied index is out of bounds. * @throws IOException if an error occurs reading the width information from * the input source. */ @Override public synchronized GridSampleDimension[] getSampleDimensions(final int index) throws IOException { checkImageIndex(index); return null; } }