Package org.geotools.gce.geotiff

Source Code of org.geotools.gce.geotiff.GeoTiffReader

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2005-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.
*/
/*
* NOTICE OF RELEASE TO THE PUBLIC DOMAIN
*
* This work was created by employees of the USDA Forest Service's
* Fire Science Lab for internal use.  It is therefore ineligible for
* copyright under title 17, section 105 of the United States Code.  You
* may treat it as you would treat any public domain work: it may be used,
* changed, copied, or redistributed, with or without permission of the
* authors, for free or for compensation.  You may not claim exclusive
* ownership of this code because it is already owned by everyone.  Use this
* software entirely at your own risk.  No warranty of any kind is given.
*
* A copy of 17-USC-105 should have accompanied this distribution in the file
* 17USC105.html.  If not, you may access the law via the US Government's
* public websites:
*   - http://www.copyright.gov/title17/92chap1.html#105
*   - http://www.gpoaccess.gov/uscode/  (enter "17USC105" in the search box.)
*/
package org.geotools.gce.geotiff;

import it.geosolutions.imageioimpl.plugins.tiff.TIFFImageReaderSpi;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.awt.image.SampleModel;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.ImageInputStreamSpi;
import javax.imageio.stream.ImageInputStream;
import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RenderedOp;

import org.geotools.coverage.Category;
import org.geotools.coverage.GridSampleDimension;
import org.geotools.coverage.TypeMap;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridCoverage2DReader;
import org.geotools.coverage.grid.io.OverviewPolicy;
import org.geotools.coverage.grid.io.imageio.geotiff.GeoTiffIIOMetadataDecoder;
import org.geotools.coverage.grid.io.imageio.geotiff.GeoTiffMetadata2CRSAdapter;
import org.geotools.data.DataSourceException;
import org.geotools.data.DataUtilities;
import org.geotools.data.MapInfoFileReader;
import org.geotools.data.PrjFileReader;
import org.geotools.data.WorldFileReader;
import org.geotools.factory.Hints;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.image.ImageWorker;
import org.geotools.image.io.ImageIOExt;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.matrix.XAffineTransform;
import org.geotools.referencing.operation.transform.ProjectiveTransform;
import org.geotools.resources.coverage.CoverageUtilities;
import org.geotools.resources.i18n.Vocabulary;
import org.geotools.resources.i18n.VocabularyKeys;
import org.geotools.resources.image.ImageUtilities;
import org.geotools.util.NumberRange;
import org.opengis.coverage.ColorInterpretation;
import org.opengis.coverage.grid.Format;
import org.opengis.coverage.grid.GridCoverage;
import org.opengis.geometry.Envelope;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterValue;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;


/**
* this class is responsible for exposing the data and the Georeferencing
* metadata available to the Geotools library. This reader is heavily based on
* the capabilities provided by the ImageIO tools and JAI libraries.
*
*
* @author Bryce Nordgren, USDA Forest Service
* @author Simone Giannecchini
* @since 2.1
*
*/
public class GeoTiffReader extends AbstractGridCoverage2DReader implements GridCoverage2DReader {

  /** Logger for the {@link GeoTiffReader} class. */
  private Logger LOGGER = org.geotools.util.logging.Logging.getLogger(GeoTiffReader.class.toString());
 
  /** With this java switch I can control whether or not an external PRJ files takes precedence over the internal CRS definition*/
  public static final String OVERRIDE_CRS_SWITCH = "org.geotools.gce.geotiff.override.crs";
 
  /** With this java switch I can control whether or not an external PRJ files takes precedence over the internal CRS definition*/
  static boolean OVERRIDE_INNER_CRS=Boolean.valueOf(System.getProperty(GeoTiffReader.OVERRIDE_CRS_SWITCH, "True"));

  /** SPI for creating tiff readers in ImageIO tools */
  private final static TIFFImageReaderSpi READER_SPI = new TIFFImageReaderSpi();

  /** Adapter for the GeoTiff crs. */
  private GeoTiffMetadata2CRSAdapter gtcs;
 
  private double noData = Double.NaN;

    private File ovrSource;

    private ImageInputStreamSpi ovrInStreamSPI = null;

    private int extOvrImgChoice = -1;

  /**
   * Creates a new instance of GeoTiffReader
   *
   * @param input
   *            the GeoTiff file
   * @throws DataSourceException
   */
  public GeoTiffReader(Object input) throws DataSourceException {
    this(input, new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER,Boolean.TRUE));

  }

  /**
   * Creates a new instance of GeoTiffReader
   *
   * @param input
   *            the GeoTiff file
   * @param uHints
   *            user-supplied hints TODO currently are unused
   * @throws DataSourceException
   */
  public GeoTiffReader(Object input, Hints uHints) throws DataSourceException {
      super(input,uHints);
              
    // /////////////////////////////////////////////////////////////////////
    //
    // Set the source being careful in case it is an URL pointing to a file
    //
    // /////////////////////////////////////////////////////////////////////
    try {
     
      // setting source
      if (input instanceof URL) {
        final URL sourceURL = (URL) input;
        source = DataUtilities.urlToFile(sourceURL);
      }

      closeMe = true;
      // /////////////////////////////////////////////////////////////////////
      //
      // Get a stream in order to read from it for getting the basic
      // information for this coverage
      //
      // /////////////////////////////////////////////////////////////////////
      if ((source instanceof InputStream)|| (source instanceof ImageInputStream))
        closeMe = false;
      if(source instanceof ImageInputStream )
        inStream=(ImageInputStream) source;
      else{
          inStreamSPI = ImageIOExt.getImageInputStreamSPI(source);
          if (inStreamSPI == null)
                                throw new IllegalArgumentException("No input stream for the provided source");
          inStream = inStreamSPI.createInputStreamInstance(source, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
      }
      if (inStream == null)
        throw new IllegalArgumentException("No input stream for the provided source");

                        checkForExternalOverviews();
      // /////////////////////////////////////////////////////////////////////
      //
      // Informations about multiple levels and such
      //
      // /////////////////////////////////////////////////////////////////////
      getHRInfo(this.hints);

      // /////////////////////////////////////////////////////////////////////
      //
      // Coverage name
      //
      // /////////////////////////////////////////////////////////////////////
      coverageName = source instanceof File ? ((File) source).getName(): "geotiff_coverage";
      final int dotIndex = coverageName.lastIndexOf('.');
      if (dotIndex != -1 && dotIndex != coverageName.length())
        coverageName = coverageName.substring(0, dotIndex);

    } catch (IOException e) {
      throw new DataSourceException(e);
    }finally{
      // /////////////////////////////////////////////////////////////////////
      //
      // Freeing streams
      //
      // /////////////////////////////////////////////////////////////////////
      if (closeMe&&inStream!=null)//
        try{
          inStream.close();
        }catch (Throwable t) {
        }
    }
  }
 
    private void checkForExternalOverviews() {
        if (!(source instanceof File)) {
            return;
        }
        File src = (File) source;
        ovrSource = new File(src.getParent(), src.getName() + ".ovr");
        if (!ovrSource.exists()) {
            return;
        }
        ovrInStreamSPI = ImageIOExt.getImageInputStreamSPI(ovrSource);
    }

    /**
     * Collect georeferencing information about this geotiff.
     *
     * @param hints
     * @throws DataSourceException
     */
    private void getHRInfo(Hints hints) throws DataSourceException {
        ImageReader reader = null;
        ImageReader ovrReader = null;
        ImageInputStream ovrStream = null;
        try {
            // //
            //
            // Get a reader for this format
            //
            // //
            reader = READER_SPI.createReaderInstance();

            // //
            //
            // get the METADATA
            //
            // //
            inStream.mark();
            reader.setInput(inStream);
            final IIOMetadata iioMetadata = reader.getImageMetadata(0);
            final GeoTiffIIOMetadataDecoder metadata = new GeoTiffIIOMetadataDecoder(iioMetadata);
            gtcs = new GeoTiffMetadata2CRSAdapter(hints);
           
            // //
            //
            // get the CRS INFO
            //
            // //
            final Object tempCRS = this.hints.get(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM);
            if (tempCRS != null) {
                this.crs = (CoordinateReferenceSystem) tempCRS;
                if (LOGGER.isLoggable(Level.FINE))
                    LOGGER.log(Level.FINE, "Using forced coordinate reference system");
            } else {
             
              // check external prj first
              crs = getCRS(source);
                               
              // now, if we did not want to override the inner CRS or we did not have any external PRJ at hand
              // let's look inside the geotiff
                if (!OVERRIDE_INNER_CRS || crs==null){
                  if(metadata.hasGeoKey()&& gtcs != null){
                      crs = gtcs.createCoordinateSystem(metadata);
                  }
                }


            }

            //
            // No data
            //
            if (metadata.hasNoData()){
                noData = metadata.getNoData();
            }
           
            //
            // parse and set layout
            //
            setLayout(reader);
           
            // //
            //
            // get the dimension of the hr image and build the model as well as
            // computing the resolution
            // //
            numOverviews = reader.getNumImages(true) - 1;
            int hrWidth = reader.getWidth(0);
            int hrHeight = reader.getHeight(0);
            final Rectangle actualDim = new Rectangle(0, 0, hrWidth, hrHeight);
            originalGridRange = new GridEnvelope2D(actualDim);

            if (gtcs != null&& metadata!=null&& (metadata.hasModelTrasformation()||(metadata.hasPixelScales()&&metadata.hasTiePoints()))) {
                this.raster2Model = GeoTiffMetadata2CRSAdapter.getRasterToModel(metadata);
            } else {
              // world file
                this.raster2Model = parseWorldFile(source);
               
                // now world file --> mapinfo?
                if (raster2Model == null) {
                    MapInfoFileReader mifReader = parseMapInfoFile(source);
                    if(mifReader!=null){
                        raster2Model = mifReader.getTransform();
                        crs = mifReader.getCRS();
                    }

                }
            }
           
            if (crs == null){
                if(LOGGER.isLoggable(Level.WARNING)){
                    LOGGER.warning("Coordinate Reference System is not available");
                }
                crs = AbstractGridFormat.getDefaultCRS();
            }

            if (this.raster2Model == null) {
                throw new DataSourceException("Raster to Model Transformation is not available");
            }

            // create envelope using corner transformation
            final AffineTransform tempTransform = new AffineTransform(
                    (AffineTransform) raster2Model);
            tempTransform.concatenate(CoverageUtilities.CENTER_TO_CORNER);
            originalEnvelope = CRS.transform(ProjectiveTransform.create(tempTransform),
                    new GeneralEnvelope(actualDim));
            originalEnvelope.setCoordinateReferenceSystem(crs);

            // ///
            //
            // setting the higher resolution available for this coverage
            //
            // ///
            highestRes = new double[2];
            highestRes[0] = XAffineTransform.getScaleX0(tempTransform);
            highestRes[1] = XAffineTransform.getScaleY0(tempTransform);

            if (ovrInStreamSPI != null) {
                ovrReader = READER_SPI.createReaderInstance();
                ovrStream = ovrInStreamSPI.createInputStreamInstance(ovrSource,
                        ImageIO.getUseCache(), ImageIO.getCacheDirectory());
                ovrReader.setInput(ovrStream);
                // this includes the real image as this is a image index, we need to add one.
                extOvrImgChoice = numOverviews + 1;
                numOverviews = numOverviews + ovrReader.getNumImages(true);
                if (numOverviews < extOvrImgChoice)
                    extOvrImgChoice = -1;
            }
           
           
            // //
            //
            // get information for the successive images
            //
            // //
            if (numOverviews >= 1) {
                overViewResolutions = new double[numOverviews][2];
                // Internal overviews start at 1, so lastInternalOverview matches numOverviews if no
                // external.
                int firstExternalOverview = extOvrImgChoice == -1 ? numOverviews : extOvrImgChoice - 1;
                double spanRes0 = highestRes[0] * this.originalGridRange.getSpan(0);
                double spanRes1 = highestRes[1] * this.originalGridRange.getSpan(1);
                for (int i = 0; i < firstExternalOverview; i++) {
                    overViewResolutions[i][0] = spanRes0 / reader.getWidth(i + 1);
                    overViewResolutions[i][1] = spanRes1 / reader.getHeight(i + 1);
                }
                for (int i = firstExternalOverview; i < numOverviews; i++) {
                    overViewResolutions[i][0] = spanRes0 / ovrReader.getWidth(i - firstExternalOverview);
                    overViewResolutions[i][1] = spanRes1 / ovrReader.getHeight(i - firstExternalOverview);
                }
              
            } else
                overViewResolutions = null;
        } catch (Throwable e) {
            throw new DataSourceException(e);
        } finally {
            if (reader != null)
                try {
                    reader.dispose();
                } catch (Throwable t) {
                }
               
            if (ovrReader != null)
                try {
                    ovrReader.dispose();
                } catch (Throwable t) {
                }

            if (ovrStream != null)
                try {
                    ovrStream.close();
                } catch (Throwable t) {
                }

            if (inStream != null)
                try {
                    inStream.reset();
                } catch (Throwable t) {
                }

        }
    }

  /**
   * @see org.opengis.coverage.grid.GridCoverageReader#getFormat()
   */
  public Format getFormat() {
    return new GeoTiffFormat();
  }

  /**
   * This method reads in the TIFF image, constructs an appropriate CRS,
   * determines the math transform from raster to the CRS model, and
   * constructs a GridCoverage.
   *
   * @param params
   *            currently ignored, potentially may be used for hints.
   *
   * @return grid coverage represented by the image
   *
   * @throws IOException
   *             on any IO related troubles
   */
  public GridCoverage2D read(GeneralParameterValue[] params) throws IOException {
    GeneralEnvelope requestedEnvelope = null;
    Rectangle dim = null;
    Color inputTransparentColor=null;
    OverviewPolicy overviewPolicy=null;
    int[] suggestedTileSize=null;
    if (params != null) {

      //
      // Checking params
      //
      if (params != null) {
        for (int i = 0; i < params.length; i++) {
          final ParameterValue param = (ParameterValue) params[i];
          final ReferenceIdentifier name = param.getDescriptor().getName();
          if (name.equals(AbstractGridFormat.READ_GRIDGEOMETRY2D.getName())) {
            final GridGeometry2D gg = (GridGeometry2D) param.getValue();
            requestedEnvelope = new GeneralEnvelope((Envelope) gg.getEnvelope2D());
            dim = gg.getGridRange2D().getBounds();
            continue;
          }
          if (name.equals(AbstractGridFormat.OVERVIEW_POLICY.getName())) {
            overviewPolicy=(OverviewPolicy) param.getValue();
            continue;
         
                    if (name.equals(AbstractGridFormat.INPUT_TRANSPARENT_COLOR.getName())) {
                        inputTransparentColor = (Color) param.getValue();
                        continue;
                   
                    if (name.equals(AbstractGridFormat.SUGGESTED_TILE_SIZE.getName())) {
                        String suggestedTileSize_= (String) param.getValue();
                        if(suggestedTileSize_!=null&&suggestedTileSize_.length()>0){
                            suggestedTileSize_=suggestedTileSize_.trim();
                            int commaPosition=suggestedTileSize_.indexOf(",");
                            if(commaPosition<0){
                                int tileDim=Integer.parseInt(suggestedTileSize_);
                                suggestedTileSize= new int[]{tileDim,tileDim};
                            } else {
                                int tileW=Integer.parseInt(suggestedTileSize_.substring(0,commaPosition));
                                int tileH=Integer.parseInt(suggestedTileSize_.substring(commaPosition+1));
                                suggestedTileSize= new int[]{tileW,tileH};
                            }
                        }
                        continue;
                    }                                              
        }
      }
    }

    //
    // set params
    //
    Integer imageChoice = new Integer(0);
    final ImageReadParam readP = new ImageReadParam();
    try {
      imageChoice = setReadParams(overviewPolicy, readP,requestedEnvelope, dim);
    } catch (TransformException e) {
      new DataSourceException(e);
    }

    //
    // IMAGE READ OPERATION
    //
        Hints newHints = null;
    if(suggestedTileSize!=null){
        newHints= (Hints) hints.clone();
            final ImageLayout layout = new ImageLayout();
            layout.setTileGridXOffset(0);
            layout.setTileGridYOffset(0);
            layout.setTileHeight(suggestedTileSize[1]);
            layout.setTileWidth(suggestedTileSize[0]);
            newHints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout));
    }
    final ParameterBlock pbjRead = new ParameterBlock();
        if (extOvrImgChoice >= 0 && imageChoice >= extOvrImgChoice) {
            pbjRead.add(ovrInStreamSPI.createInputStreamInstance(ovrSource, ImageIO.getUseCache(),ImageIO.getCacheDirectory()));
            pbjRead.add(imageChoice - extOvrImgChoice);
        } else {
            pbjRead.add(inStreamSPI != null ? inStreamSPI.createInputStreamInstance(source, ImageIO.getUseCache(), ImageIO.getCacheDirectory()) : ImageIO.createImageInputStream(source));
            pbjRead.add(imageChoice);
        }
      pbjRead.add(Boolean.FALSE);
    pbjRead.add(Boolean.FALSE);
    pbjRead.add(Boolean.FALSE);
    pbjRead.add(null);
    pbjRead.add(null);
    pbjRead.add(readP);
    pbjRead.add(READER_SPI.createReaderInstance());
    RenderedOp coverageRaster=JAI.create("ImageRead", pbjRead,newHints!=null?(RenderingHints) newHints:null);
   
        //
        // MASKING INPUT COLOR as indicated
        //
    if(inputTransparentColor!=null){
        coverageRaster= new ImageWorker(coverageRaster).setRenderingHints(newHints).makeColorTransparent(inputTransparentColor).getRenderedOperation();
    }
   
    //
    // BUILDING COVERAGE
    //
        // I need to calculate a new transformation (raster2Model)
        // between the cropped image and the required
        // adjustedRequestEnvelope
        final int ssWidth = coverageRaster.getWidth();
        final int ssHeight = coverageRaster.getHeight();
        if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.log(Level.FINE, "Coverage read: width = " + ssWidth+ " height = " + ssHeight);
        }

        // //
        //
        // setting new coefficients to define a new affineTransformation
        // to be applied to the grid to world transformation
        // -----------------------------------------------------------------------------------
        //
        // With respect to the original envelope, the obtained planarImage
        // needs to be rescaled. The scaling factors are computed as the
        // ratio between the cropped source region sizes and the read
        // image sizes.
        //
        // //
        final double scaleX = originalGridRange.getSpan(0) / (1.0 * ssWidth);
        final double scaleY = originalGridRange.getSpan(1) / (1.0 * ssHeight);
        final AffineTransform tempRaster2Model = new AffineTransform((AffineTransform) raster2Model);
        tempRaster2Model.concatenate(new AffineTransform(scaleX, 0, 0, scaleY, 0, 0));
        try{
          return createCoverage(coverageRaster, ProjectiveTransform.create((AffineTransform) tempRaster2Model));
        }catch(Exception e){
          // dispose and close file
          ImageUtilities.disposePlanarImageChain(coverageRaster);
         
          // rethrow
          if(e instanceof DataSourceException){
            throw (DataSourceException)e;
          }
          throw new DataSourceException(e);
        }


  }

    /**
     * Returns the geotiff metadata for this geotiff file.
     *
     * @return the metadata
     */
    public GeoTiffIIOMetadataDecoder getMetadata() {
        GeoTiffIIOMetadataDecoder metadata = null;
        ImageReader reader = null;
        boolean closeMe = true;
        ImageInputStream stream = null;
       
        try {
            if ((source instanceof InputStream)|| (source instanceof ImageInputStream)){
                closeMe = false;
            }
            if (source instanceof ImageInputStream ) {
                    stream =(ImageInputStream) source;
            } else {
                inStreamSPI = ImageIOExt.getImageInputStreamSPI(source);
                if (inStreamSPI == null) {
                    throw new IllegalArgumentException("No input stream for the provided source");
                }
                stream = inStreamSPI.createInputStreamInstance(source, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
            }
            if (stream == null) {
                    throw new IllegalArgumentException("No input stream for the provided source");
            }
            stream.mark();
            reader = READER_SPI.createReaderInstance();
            reader.setInput(stream);
            final IIOMetadata iioMetadata = reader.getImageMetadata(0);
            metadata = new GeoTiffIIOMetadataDecoder(iioMetadata);
        } catch (IOException e) {
            if (LOGGER.isLoggable(Level.SEVERE)) {
                LOGGER.log(Level.SEVERE, e.getMessage(), e);
            }
        } finally {
            if (reader != null)
                try {
                    reader.dispose();
                } catch (Throwable t) {
                }

            if (stream != null){
                try {
                    stream.reset();
                } catch (Throwable t) {
                }
                if (closeMe){
                    try {
                        stream.close();
                    } catch (Throwable t) {
                    }
                }
            }
        }
        return metadata;
    }
 
  /**
         * Creates a {@link GridCoverage} for the provided {@link PlanarImage} using
         * the {@link #raster2Model} that was provided for this coverage.
         *
         * <p>
         * This method is vital when working with coverages that have a raster to
         * model transformation that is not a simple scale and translate.
         *
         * @param image
         *            contains the data for the coverage to create.
         * @param raster2Model
         *            is the {@link MathTransform} that maps from the raster space
         *            to the model space.
         * @return a {@link GridCoverage}
         * @throws IOException
         */
        protected final GridCoverage2D createCoverage(PlanarImage image, MathTransform raster2Model) throws IOException {

        //creating bands
        final SampleModel sm = image.getSampleModel();
        final ColorModel cm = image.getColorModel();
        final int numBands = sm.getNumBands();
        final GridSampleDimension[] bands = new GridSampleDimension[numBands];
        // setting bands names.
       
        Category noDataCategory = null;
        final Map<String, Double> properties = new HashMap<String, Double>();       
        if (!Double.isNaN(noData)){
            noDataCategory = new Category(Vocabulary
                    .formatInternational(VocabularyKeys.NODATA), new Color[] { new Color(0, 0, 0, 0) }, NumberRange
                    .create(noData, noData), NumberRange
                    .create(noData, noData));

            properties.put("GC_NODATA", new Double(noData));
        }
       
        Set<String> bandNames = new HashSet<String>();
        for (int i = 0; i < numBands; i++) {
                final ColorInterpretation colorInterpretation=TypeMap.getColorInterpretation(cm, i);
                if(colorInterpretation==null)
                       throw new IOException("Unrecognized sample dimension type");
                Category[] categories = null;
                if (noDataCategory != null) {
                    categories = new Category[]{noDataCategory};
                }
                String bandName = colorInterpretation.name();
                // make sure we create no duplicate band names
                if(colorInterpretation == ColorInterpretation.UNDEFINED || bandNames.contains(bandName)) {
                    bandName = "Band" + (i + 1);
                }
                bands[i] = new GridSampleDimension(bandName,categories,null).geophysics(true);
        }
        // creating coverage
        if (raster2Model != null) {
                return coverageFactory.create(coverageName, image, crs,raster2Model, bands, null, properties);
        }
        return coverageFactory.create(coverageName, image, new GeneralEnvelope(originalEnvelope), bands, null, properties);

        }
 
 
        private CoordinateReferenceSystem getCRS(Object source) {
            CoordinateReferenceSystem crs = null;
        if (source instanceof File
                || (source instanceof URL && (((URL) source).getProtocol() == "file"))) {
            // getting name for the prj file
            final String sourceAsString;

            if (source instanceof File) {
                sourceAsString = ((File) source).getAbsolutePath();
            } else {
                String auth = ((URL) source).getAuthority();
                String path = ((URL) source).getPath();
                if (auth != null && !auth.equals("")) {
                    sourceAsString = "//" + auth + path;
                } else {
                    sourceAsString = path;
                }
            }

            final int index = sourceAsString.lastIndexOf(".");
            final String base=index>0?sourceAsString.substring(0, index)+".prj":sourceAsString+".prj";

            // does it exist?
            final File prjFile = new File(base.toString());
            if (prjFile.exists()) {
                // it exists then we have top read it
                PrjFileReader projReader = null;
                FileInputStream instream=null;
                try {
                  instream=new FileInputStream(prjFile);
                    final FileChannel channel = instream.getChannel();
                    projReader = new PrjFileReader(channel);
                    crs = projReader.getCoordinateReferenceSystem();
                } catch (FileNotFoundException e) {
                    // warn about the error but proceed, it is not fatal
                    // we have at least the default crs to use
                    LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
                } catch (IOException e) {
                    // warn about the error but proceed, it is not fatal
                    // we have at least the default crs to use
                    LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
                } catch (FactoryException e) {
                    // warn about the error but proceed, it is not fatal
                    // we have at least the default crs to use
                    LOGGER.log(Level.INFO, e.getLocalizedMessage(), e);
                } finally {
                    if (projReader != null)
                        try {
                            projReader.close();
                        } catch (IOException e) {
                            // warn about the error but proceed, it is not fatal
                            // we have at least the default crs to use
                            LOGGER .log(Level.FINE, e.getLocalizedMessage(),e);
                        }
                       
                        if (instream != null)
                            try {
                                instream.close();
                            } catch (IOException e) {
                                // warn about the error but proceed, it is not fatal
                                // we have at least the default crs to use
                                LOGGER.log(Level.FINE, e.getLocalizedMessage(),e);
                            }                       
                }

            }
        }
        return crs;
    }
       
       
    /**
     * @throws IOException
     */
    static MathTransform parseWorldFile(Object source) throws IOException {
        MathTransform raster2Model = null;

        // TODO: Add support for FileImageInputStreamExt
        // TODO: Check for WorldFile on URL beside the actual connection.
        if (source instanceof File) {
            final File sourceFile = ((File) source);
            String parentPath = sourceFile.getParent();
            String filename = sourceFile.getName();
            final int i = filename.lastIndexOf('.');
            filename = (i == -1) ? filename : filename.substring(0, i);
           
            // getting name and extension
            final String base = (parentPath != null) ? new StringBuilder(
                    parentPath).append(File.separator).append(filename)
                    .toString() : filename;

            // We can now construct the baseURL from this string.
            File file2Parse = new File(new StringBuilder(base).append(".wld")
                    .toString());

            if (file2Parse.exists()) {
                final WorldFileReader reader = new WorldFileReader(file2Parse);
                raster2Model = reader.getTransform();
            } else {
                // looking for another extension
                file2Parse = new File(new StringBuilder(base).append(".tfw")
                        .toString());

                if (file2Parse.exists()) {
                    // parse world file
                    final WorldFileReader reader = new WorldFileReader(
                            file2Parse);
                    raster2Model = reader.getTransform();
                }
            }
        }
        return raster2Model;
    }
   
    /**
     * @throws IOException
     */
    static MapInfoFileReader parseMapInfoFile(Object source) throws IOException {
        if (source instanceof File) {
            final File sourceFile = ((File) source);
            String parentPath = sourceFile.getParent();
            String filename = sourceFile.getName();
            final int i = filename.lastIndexOf('.');
            filename = (i == -1) ? filename : filename.substring(0, i);
           
            // getting name and extension
            final String base = (parentPath != null) ? new StringBuilder(
                    parentPath).append(File.separator).append(filename)
                    .toString() : filename;

            // We can now construct the baseURL from this string.
            File file2Parse = new File(new StringBuilder(base).append(".tab")
                    .toString());

            if (file2Parse.exists()) {
                final MapInfoFileReader reader = new MapInfoFileReader(file2Parse);
                return reader;
            }
        }
        return null;
    }

  /**
   * Number of coverages for this reader is 1
   *
   * @return the number of coverages for this reader.
   */
  @Override
  public int getGridCoverageCount() {
    return 1;
  }

}
TOP

Related Classes of org.geotools.gce.geotiff.GeoTiffReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.