Package org.geotools.gce.image

Source Code of org.geotools.gce.image.WorldImageReader

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2002-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.gce.image;

import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.renderable.ParameterBlock;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.channels.FileChannel;
import java.util.Iterator;
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.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;

import org.geotools.coverage.CoverageFactoryFinder;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridCoverageFactory;
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.data.DataSourceException;
import org.geotools.data.PrjFileReader;
import org.geotools.data.WorldFileReader;
import org.geotools.factory.Hints;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.image.io.ImageIOExt;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
import org.geotools.referencing.operation.matrix.XAffineTransform;
import org.geotools.referencing.operation.transform.ProjectiveTransform;
import org.opengis.coverage.grid.Format;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterValue;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.TransformException;

/**
* Reads a GridCoverage from a given source. WorldImage sources only support one
* GridCoverage so hasMoreGridCoverages() will return true until the only
* GridCoverage is read. No metadata is currently supported, so all related
* methods return null. In the early future we will start (hopefully supporting
* them).
*
* @author simone giannecchini
* @author alessio fabiani
* @author rgould
*
*
*
* @source $URL$
*/
public final class WorldImageReader extends AbstractGridCoverage2DReader
    implements GridCoverage2DReader {

  /** Logger. */
  private Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.gce.image");

  private boolean wmsRequest;

  private boolean metaFile;

  private String parentPath;

  private String extension;

  private ImageReaderSpi readerSPI;

  /**
   * Class constructor. Construct a new ImageWorldReader to read a
   * GridCoverage from the source object. The source must point to the raster
   * file itself, not the world file. If the source is a Java URL it checks if
   * it is ponting to a file and if so it converts the url into a file.
   *
   * @param input
   *            The source of a GridCoverage, can be a File, a URL or an input
   *            stream.
   * @throws DataSourceException
   */
  public WorldImageReader(Object input) throws DataSourceException {
    this(input, null);
  }
  /**
   * Class constructor. Construct a new ImageWorldReader to read a
   * GridCoverage from the source object. The source must point to the raster
   * file itself, not the world file. If the source is a Java URL it checks if
   * it is ponting to a file and if so it converts the url into a file.
   *
   * @param input
   *            The source of a GridCoverage, can be a File, a URL or an input
   *            stream.
   * @throws DataSourceException
   */
  public WorldImageReader(Object input,final Hints hints) throws DataSourceException {
    // /////////////////////////////////////////////////////////////////////
    //
    // Checking input
    //
    // /////////////////////////////////////////////////////////////////////
    if (input == null) {

      final IOException ex = new IOException(
          "WorldImage:No source set to read this coverage.");
      LOGGER.logp(Level.SEVERE, WorldImageReader.class.toString(),
          "WorldImageReader", ex.getLocalizedMessage(), ex);
      throw new DataSourceException(ex);
    }
    this.source=input;
   
    // //
    //
    // managing hints
    //
    // //
    if (this.hints == null)
      this.hints= new Hints()
    if (hints != null) {
            this.hints.add(hints);
    }

                // GridCoverageFactory initialization
                if (this.hints.containsKey(Hints.GRID_COVERAGE_FACTORY)) {
                    final Object factory = this.hints.get(Hints.GRID_COVERAGE_FACTORY);
                    if (factory != null && factory instanceof GridCoverageFactory) {
                        this.coverageFactory = (GridCoverageFactory) factory;
                    }
                }
                if (this.coverageFactory == null) {
                    this.coverageFactory = CoverageFactoryFinder.getGridCoverageFactory(this.hints);
                }
               
    coverageName = "image_coverage";
    try {
      boolean closeMe = true;

      // /////////////////////////////////////////////////////////////////////
      //
      // Source management
      //
      // /////////////////////////////////////////////////////////////////////
      if (input instanceof URL) {
        // URL that point to a file
        final URL sourceURL = ((URL) input);
        if (sourceURL.getProtocol().compareToIgnoreCase("file") == 0) {
          String auth = sourceURL.getAuthority();
          String path = sourceURL.getPath();
          if (auth != null && !auth.equals("")) {
            path = "//"+auth+path;
          }
          this.source = input = new File(URLDecoder.decode(path, "UTF-8"));
        } else if (sourceURL.getProtocol().equalsIgnoreCase("http")) {
          // // getting a stream to the reader
          // this.source = sourceURL.openStream();

          // /////////////////////////////////////////////////////////////////////
          //
          // WMS Request? I want to be able to handle that case too
          //
          // /////////////////////////////////////////////////////////////////////
          wmsRequest = WMSRequest(input);
        }
      }

      // //
      //
      // Name, path, etc...
      //
      // //
      if (input instanceof File) {
        final File sourceFile = (File) input;
        final String filename = sourceFile.getName();
        final int i = filename.lastIndexOf('.');
        final int length = filename.length();
        if (i > 0 && i < length - 1) {
          extension = filename.substring(i + 1).toLowerCase();
        }
        this.parentPath = sourceFile.getParent();
        this.coverageName = filename;
        final int dotIndex = coverageName.lastIndexOf(".");
        coverageName = (dotIndex == -1) ? coverageName : coverageName
            .substring(0, dotIndex);
      } else if (input instanceof URL)
        input = ((URL) input).openStream();
      // //
      //
      // Get a stream in order to read from it for getting the basic
      // information for this coverfage
      //
      // //
      if (input instanceof ImageInputStream){
          closeMe = false;
      }else{
          inStreamSPI= ImageIOExt.getImageInputStreamSPI(source);
          if (inStreamSPI == null)
              throw new DataSourceException(
                      "No input stream for the provided source");
                      inStream = inStreamSPI.createInputStreamInstance( this.source, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
                            
                       
      }
     
      if (inStream == null)
        throw new IllegalArgumentException(
            "No input stream for the provided source");

      // /////////////////////////////////////////////////////////////////////
      //
      // CRS
      //
      // /////////////////////////////////////////////////////////////////////
                        if (!wmsRequest) {
                            final Object tempCRS = this.hints.get(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM);
                            if (tempCRS != null) {
                                this.crs = (CoordinateReferenceSystem) tempCRS;
                                LOGGER.log(Level.WARNING,  "Using forced coordinate reference system ");
                            } else
                                readCRS();
                        }

      // /////////////////////////////////////////////////////////////////////
      //
      // Informations about multiple levels and such
      //
      // /////////////////////////////////////////////////////////////////////
      getHRInfo();

      // release the stream
      if (closeMe)
        inStream.close();
    } catch (IOException e) {
      LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
      throw new DataSourceException(e);
    } catch (TransformException e) {
      LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
      throw new DataSourceException(e);
    }
  }

  /**
   * Gets the relevant information for the underlying raster.
   *
   * @throws IOException
   * @throws TransformException
   */
  private void getHRInfo() throws IOException, TransformException {

    // //
    //
    // Get a reader for this format
    // TODO optimize this using image file extension when possible
    //
    // //
    final Iterator<ImageReader> it = ImageIO.getImageReaders(inStream);
    if (!it.hasNext())
      throw new DataSourceException("No reader avalaible for this source");
    final ImageReader reader = (ImageReader) it.next();
    readerSPI = reader.getOriginatingProvider();
    reader.setInput(inStream);
   
    //
                // parse and set layout
    //
                setLayout(reader);

    // //
    //
    // get the dimension of the hr image and build the model as well as
    // computing the resolution
    // //
    numOverviews = wmsRequest ? 0 : 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);

    // /////////////////////////////////////////////////////////////////////
    //
    // Envelope, coverage name and other resolution information
    //
    // /////////////////////////////////////////////////////////////////////
    if (source instanceof File) {
      prepareWorldImageGridToWorldTransform();

      // //
      //
      // In case we read from a real world file we have toget the envelope
      //
      // //
      if (!metaFile) {
        final AffineTransform tempTransform = new AffineTransform(
            (AffineTransform) raster2Model);
        tempTransform.translate(-0.5, -0.5);

        originalEnvelope = CRS.transform(ProjectiveTransform
            .create(tempTransform), new GeneralEnvelope(actualDim));
        originalEnvelope.setCoordinateReferenceSystem(crs);
        highestRes = new double[2];
        highestRes[0]=XAffineTransform.getScaleX0(tempTransform);
        highestRes[1]=XAffineTransform.getScaleY0(tempTransform);
      }
      else
      {
        // ///
        //
        // setting the higher resolution available for this coverage
        //
        // ///
        highestRes = getResolution(originalEnvelope, actualDim, crs);
        final GridToEnvelopeMapper mapper = new GridToEnvelopeMapper(originalGridRange, originalEnvelope);
        mapper.setPixelAnchor(PixelInCell.CELL_CENTER);
        this.raster2Model=mapper.createTransform();

      }


    }
    // //
    //
    // get information for the overviews in case ony exists
    //
    // //
    if (numOverviews >=1) {
      overViewResolutions = new double[numOverviews][2];
      for (int i = 0; i < numOverviews; i++) {
        overViewResolutions[i][0] = (highestRes[0]*this.originalGridRange.getSpan(0))/reader.getWidth(i+1);
        overViewResolutions[i][1] = (highestRes[1]*this.originalGridRange.getSpan(1))/reader.getHeight(i+1);
      }
    } else
      overViewResolutions = null;
  }

  /**
   * Returns the format that this Reader accepts.
   *
   * @return a new WorldImageFormat class
   */
  public Format getFormat() {
    return new WorldImageFormat();
  }

  /**
   * Reads an image from a source stream. Loads an image from a source stream,
   * then loads the values from the world file and constructs a new
   * GridCoverage from this information. When reading from a remote stream we
   * do not look for a world fiel but we suppose those information comes from
   * a different way (xml, gml, pigeon?)
   *
   * @param params
   *            WorldImageReader supports no parameters, it just ignores them.
   *
   * @return a new GridCoverage read from the source.
   *
   * @throws IllegalArgumentException
   *             DOCUMENT ME!
   * @throws IOException
   *             DOCUMENT ME!
   */
  public GridCoverage2D read(GeneralParameterValue[] params)
      throws IllegalArgumentException, IOException {

    // /////////////////////////////////////////////////////////////////////
    //
    // do we have parameters to use for reading from the specified source
    //
    // /////////////////////////////////////////////////////////////////////
    GeneralEnvelope requestedEnvelope = null;
    Rectangle dim = null;
    OverviewPolicy overviewPolicy=null;
    if (params != null) {
      // /////////////////////////////////////////////////////////////////////
      //
      // Checking params
      //
      // /////////////////////////////////////////////////////////////////////
      if (params != null) {
        for (int i = 0; i < params.length; i++) {
          final ParameterValue param = (ParameterValue) params[i];
          final String name = param.getDescriptor().getName().getCode();
          if (name.equals(
              AbstractGridFormat.READ_GRIDGEOMETRY2D.getName()
                  .toString())) {
            final GridGeometry2D gg = (GridGeometry2D) param
                .getValue();
            requestedEnvelope = new GeneralEnvelope((Envelope) gg
                .getEnvelope2D());
            dim = gg.getGridRange2D().getBounds();
            continue;
          }
          if (name.equals(AbstractGridFormat.OVERVIEW_POLICY
              .getName().toString())) {
            overviewPolicy=(OverviewPolicy) param.getValue();
            continue;
          }         
        }
      }
    }
    // /////////////////////////////////////////////////////////////////////
    //
    // set params
    //
    // /////////////////////////////////////////////////////////////////////
    Integer imageChoice = new Integer(0);
    final ImageReadParam readP = new ImageReadParam();
    if (!wmsRequest) {
      try {
        imageChoice = setReadParams(overviewPolicy,readP, requestedEnvelope, dim);
      } catch (TransformException e) {
        new DataSourceException(e);
      }
    }
    // /////////////////////////////////////////////////////////////////////
    //
    // Reading the source layer
    //
    // /////////////////////////////////////////////////////////////////////
//    final ImageReader reader = readerSPI.createReaderInstance();
//    final ImageInputStream inStream = wmsRequest ? ImageIO
//        .createImageInputStream(((URL) source).openStream()) : ImageIO
//        .createImageInputStream(source);
//   
    final Hints newHints = (Hints) hints.clone();
//    if (!wmsRequest) {
//      reader.setInput(inStream);
//      if (!reader.isImageTiled(imageChoice.intValue())) {
//        final Dimension tileSize = ImageUtilities
//            .toTileSize(new Dimension(reader.getWidth(imageChoice
//                .intValue()), reader.getHeight(imageChoice
//                .intValue())));
//        final ImageLayout layout = new ImageLayout();
//        layout.setTileGridXOffset(0);
//        layout.setTileGridYOffset(0);
//        layout.setTileHeight(tileSize.height);
//        layout.setTileWidth(tileSize.width);
//        newHints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout));
//      }
//    }
//    inStream.close();
    final ParameterBlock pbjRead = new ParameterBlock();
    pbjRead.add(inStreamSPI!=null?inStreamSPI.createInputStreamInstance(source, ImageIO.getUseCache(), ImageIO.getCacheDirectory()):ImageIO.createImageInputStream(source));   
//    pbjRead.add(wmsRequest ? ImageIO
//        .createImageInputStream(((URL) source).openStream()) : 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(readerSPI.createReaderInstance());
    final RenderedOp coverageRaster=JAI.create("ImageRead", pbjRead,
                        (RenderingHints) newHints);

    // /////////////////////////////////////////////////////////////////////
                //
                // 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));
                return createImageCoverage(coverageRaster, ProjectiveTransform.create((AffineTransform) tempRaster2Model));


  }

  /**
   * This method is used to check if we are connecting directly to a WMS with
   * a getmap request. In such a case we skip reading all the parameters we
   * can read from this http string.
   *
   * @param input
   *
   * @return true if we are dealing with a WMS request, false otherwise.
   */
  private boolean WMSRequest(Object input) {
    // TODO do we need the requested envelope?
    if (input instanceof URL
        && (((URL) input).getProtocol().equalsIgnoreCase("http"))) {
      try {
        // getting the query
        final String query = java.net.URLDecoder.decode(((URL) input)
            .getQuery().intern(), "UTF-8");

        // should we proceed? Let's look for a getmap WMS request
        if (query.intern().indexOf("GetMap") == -1) {
          return false;
        }

        // tokenizer on $
        final String[] pairs = query.split("&");

        // parse each pair
        final int numPairs = pairs.length;
        String[] kvp = null;

        for (int i = 0; i < numPairs; i++) {
          // splitting the pairs
          kvp = pairs[i].split("=");

          // checking the fields
          // BBOX
          if (kvp[0].equalsIgnoreCase("BBOX")) {
            // splitting fields
            kvp = kvp[1].split(",");
            originalEnvelope = new GeneralEnvelope(new double[] {
                Double.parseDouble(kvp[0]),
                Double.parseDouble(kvp[1]) }, new double[] {
                Double.parseDouble(kvp[2]),
                Double.parseDouble(kvp[3]) });
          }

          // SRS
          if (kvp[0].equalsIgnoreCase("SRS")) {
            crs = CRS.decode(kvp[1], true);
          }

          // layers
          if (kvp[0].equalsIgnoreCase("layers")) {
            this.coverageName = kvp[1].replaceAll(",", "_");
          }
        }

      } catch (IOException e) {
        // TODO how to handle this?
        return false;

      } catch (NoSuchAuthorityCodeException e) {
        // TODO how to handle this?
        return false;
      } catch (MismatchedDimensionException e) {
        // TODO how to handle this?
        return false;
      } catch (IndexOutOfBoundsException e) {
        // TODO how to handle this?
        return false;
      } catch (FactoryException e) {
        // TODO how to handle this?
        return false;
      }

      return true;
    }

    return false;
  }

  /**
   * This method is responsible for reading the CRS whhther a projection file
   * is provided. If no projection file is provided the second choice is the
   * CRS supplied via the crs paramter. If even this one is not avalaible we
   * default to EPSG:4326.
   *
   * @throws IOException
   */
    private void readCRS() throws IOException {

        // check to see if there is a projection file
        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 StringBuffer base = new StringBuffer(sourceAsString.substring(0, index))
                    .append(".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;
                try {
                    final FileChannel channel = new FileInputStream(prjFile).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.SEVERE, e.getLocalizedMessage(), e);
                        }
                }

            }
        }
        if (crs == null) {
            crs = AbstractGridFormat.getDefaultCRS();
            LOGGER.info("Unable to find crs, continuing with default CRS");
        }

    }

  /**
   * This method is in charge for reading the metadata file and for creating a
   * valid envelope (whether possible);
   *
   * TODO it would be great to having a centralized management for the world
   * file
   *
   * @throws IOException
   */
  private void prepareWorldImageGridToWorldTransform() throws IOException {

    // getting name and extension
    final String base = (parentPath != null) ? new StringBuffer(
        this.parentPath).append(File.separator).append(coverageName)
        .toString() : coverageName;

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

    if (file2Parse.exists()) {
      final WorldFileReader reader = new WorldFileReader(file2Parse);
      raster2Model = reader.getTransform();
    } else {
      // looking for another extension
      final Set<String> ext=WorldImageFormat.getWorldExtension(extension);
      final Iterator<String> it=ext.iterator();
      if(!it.hasNext())
        throw new DataSourceException("Unable to parse extension "+extension);
      do{
      file2Parse = new File(new StringBuffer(base).append((String)it.next()
          ).toString());
      }while(!file2Parse.exists()&&it.hasNext());
     
      if (file2Parse.exists()) {
        // parse world file
        final WorldFileReader reader = new WorldFileReader(file2Parse);
        raster2Model = reader.getTransform();
        metaFile = false;
      } else {
        // looking for a meta file
        file2Parse = new File(new StringBuffer(base).append(".meta")
            .toString());

        if (file2Parse.exists()) {
          parseMetaFile(file2Parse);
          metaFile = true;
        } else {
          final IOException ex = new IOException(
              "No file with meta information found!");
          LOGGER
              .logp(
                  Level.SEVERE,
                  WorldImageReader.class.toString(),
                  "private void prepareWorldImage2Model() throws IOException",
                  ex.getLocalizedMessage(), ex);
          throw ex;
        }
      }
    }
  }

  /**
   * This method is responsible for parsing a META file which is nothing more
   * than another format of a WorldFile used by the GIDB database.
   *
   * @param file2Parse
   *           
   *
   * @throws NumberFormatException
   * @throws IOException
   *
   * @task move me to a separate implementation
   */
  private void parseMetaFile(File file2Parse) throws NumberFormatException,
      IOException {
    double xMin = 0.0;
    double yMax = 0.0;
    double xMax = 0.0;
    double yMin = 0.0;

    // getting a buffered reader
    final BufferedReader in = new BufferedReader(new FileReader(file2Parse));

    // parsing the lines
    String str = null;
    int index = 0;
    double value = 0;

    while ((str = in.readLine()) != null) {
      switch (index) {
      case 1:
        value = Double.parseDouble(str.substring("Origin Longitude = "
            .intern().length()));
        xMin = value;

        break;

      case 2:
        value = Double.parseDouble(str.substring("Origin Latitude = "
            .intern().length()));
        yMin = value;

        break;

      case 3:
        value = Double.parseDouble(str.substring("Corner Longitude = "
            .intern().length()));
        xMax = value;

        break;

      case 4:
        value = Double.parseDouble(str.substring("Corner Latitude = "
            .intern().length()));
        yMax = value;

        break;

      default:
        break;
      }

      index++;
    }

    in.close();

    // building up envelope of this coverage
    originalEnvelope = new GeneralEnvelope(new double[] { xMin, yMin },
        new double[] { xMax, yMax });
    originalEnvelope.setCoordinateReferenceSystem(crs);
  }
 
  /**
   * Number of coverages for this reader is 1
   *
   * @return the number of coverages for this reader.
   */
  @Override
  public int getGridCoverageCount() {
    return 1;
  }

  /**
   * Returns the file extension of the image.
   *
   * @since 2.7
   */
  public String getExtension() {
      return extension;
  }
}
TOP

Related Classes of org.geotools.gce.image.WorldImageReader

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.