Package org.geotools.coverage.io.geotiff

Source Code of org.geotools.coverage.io.geotiff.GeoTiffAccess$RGBPolicy

/**
*
*/
package org.geotools.coverage.io.geotiff;

import static org.geotools.coverage.io.driver.BaseFileDriver.URL;

import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.measure.quantity.Dimensionless;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
import javax.media.jai.IHSColorSpace;

import org.apache.commons.collections.map.ListOrderedMap;
import org.geotools.coverage.GridSampleDimension;
import org.geotools.coverage.TypeMap;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.io.CoverageAccess;
import org.geotools.coverage.io.CoverageSource;
import org.geotools.coverage.io.CoverageStore;
import org.geotools.coverage.io.driver.BaseFileDriver;
import org.geotools.coverage.io.driver.Driver;
import org.geotools.coverage.io.impl.BaseCoverageAccess;
import org.geotools.coverage.io.impl.DefaultCoverageAccess;
import org.geotools.coverage.io.impl.range.DefaultFieldType;
import org.geotools.coverage.io.impl.range.DefaultRangeType;
import org.geotools.coverage.io.impl.range.DimensionlessAxis;
import org.geotools.coverage.io.impl.range.HSV;
import org.geotools.coverage.io.impl.range.WavelengthAxis;
import org.geotools.coverage.io.metadata.MetadataNode;
import org.geotools.coverage.io.range.Axis;
import org.geotools.coverage.io.range.FieldType;
import org.geotools.coverage.io.range.RangeType;
import org.geotools.data.DataSourceException;
import org.geotools.data.DefaultServiceInfo;
import org.geotools.data.Parameter;
import org.geotools.data.ResourceInfo;
import org.geotools.data.ServiceInfo;
import org.geotools.factory.Hints;
import org.geotools.feature.NameImpl;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.util.NullProgressListener;
import org.geotools.util.SimpleInternationalString;
import org.opengis.coverage.ColorInterpretation;
import org.opengis.coverage.SampleDimension;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.feature.type.Name;
import org.opengis.geometry.DirectPosition;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform2D;
import org.opengis.util.InternationalString;
import org.opengis.util.ProgressListener;

/**
* Access to a file (or URL) in the GeoTiff Format.
*
* @author Simone Giannecchini, GeoSolutions.
* @author Jody Garnett
*
*
*
* @source $URL$
*/
@SuppressWarnings("deprecation")
public class GeoTiffAccess extends DefaultCoverageAccess implements CoverageAccess {

  /**
   * Recognise a DEM and produce a RangeType.
   */
  static class DEMPolicy extends RangePolicy {
    @Override
    public RangeType describe(GridCoverage2D coverage) {
      final GridSampleDimension[] sampleDimensions = coverage.getSampleDimensions();
      HashSet<SampleDimension> samples = new HashSet<SampleDimension>(Arrays.asList(sampleDimensions));
     
      SampleDimension sample = sampleDimensions[0];
     
      Name name = new NameImpl("DEM");
      InternationalString description = sample.getDescription();
      Unit<?> unit = Unit.ONE;
      final List<Axis<?,?>> axes = new ArrayList<Axis<?,?>>();
      axes.add( HSV.INTENSITY_AXIS );
      FieldType field = new DefaultFieldType( name, description, unit, axes, samples);     
     
      Set<FieldType> fields = Collections.singleton( field );
      DefaultRangeType range = new DefaultRangeType( name, description, fields );
     
      return range;
    }

    @Override
    public boolean match(GridCoverage2D coverage) {
      final GridSampleDimension[] sampleDimensions = coverage.getSampleDimensions();
      if( sampleDimensions.length != 1){
        return false;
      }
      final Unit<?> UoM=sampleDimensions[0].getUnits();
      if( sampleDimensions.length == 1 && UoM!=null&& UoM.equals(SI.METER))
        return true;
      return false;
    }
  }

  static class GenericPhotometricPolicy extends RangePolicy {
    @Override
    public RangeType describe(GridCoverage2D coverage) {
      final GridSampleDimension[] sampleDimensions = coverage.getSampleDimensions();
      final HashSet<SampleDimension> samples = new HashSet<SampleDimension>(Arrays.asList(sampleDimensions));
      final DimensionlessAxis axis=DimensionlessAxis.createFromRenderedImage(coverage.getRenderedImage());
      final List<Axis<?,?>> axes= new ArrayList<Axis<?,?>>();
      axes.add(axis);
      final FieldType field = new DefaultFieldType( new NameImpl("photometric-FieldType"), new SimpleInternationalString("Photometric image field"), Dimensionless.UNIT,axes, samples);
      final DefaultRangeType range = new DefaultRangeTypenew NameImpl("photometric-RangeType")new SimpleInternationalString("Photometric range field"), Collections.singleton(field) )
      return range;
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean match(GridCoverage2D coverage) {
      final GridSampleDimension[] sampleDimensions = coverage.getSampleDimensions();
      final RenderedImage raster=coverage.getRenderedImage();
      if(raster==null)
        return false;
      final ColorModel cm= raster.getColorModel();
      if(cm==null)
        return false;       
      //get the color interpretation for the three bands
      final ColorInterpretation firstBandCI = TypeMap.getColorInterpretation(cm, 0);
     
      //    CMY - CMYK
      if(firstBandCI==ColorInterpretation.CYAN_BAND)
        return true;
     
      // HSV
      if(firstBandCI==ColorInterpretation.HUE_BAND)
        return true;
     
      //RGBA
      if(firstBandCI==ColorInterpretation.RED_BAND)
        return sampleDimensions.length==4;//RGBA
     
      //PALETTE
      if(firstBandCI==ColorInterpretation.PALETTE_INDEX)
        return true;     
     
      // GRAY, GRAY+ALPHA
      if(firstBandCI==ColorInterpretation.GRAY_INDEX&&sampleDimensions.length<=2)
      {
        if(sampleDimensions.length==2&&TypeMap.getColorInterpretation(cm, 1)==ColorInterpretation.ALPHA_BAND)
          return true;
        //gray if we do not have a UoM
        final Unit<?> uom=sampleDimensions[0].getUnits();
        if(uom==null|| uom.equals(Unit.ONE))
          return true;
        return false;
         
      }
     
     
      final ColorSpace cs = cm.getColorSpace();
      //IHS
      if(cs instanceof IHSColorSpace)
        return true;
      //YCbCr, LUV, LAB, HLS, IEXYZ
      switch(cs.getType()){
      case ColorSpace.TYPE_YCbCr:case ColorSpace.TYPE_Luv:case ColorSpace.TYPE_Lab:case ColorSpace.TYPE_HLS:case ColorSpace.CS_CIEXYZ:
        return true;
      default:
        return false;
     
       
      }

    }
  }
 
  /**
   * We are keeping one Info class for each coverage; this
   * way we have an object to hold onto things we care about:
   * <ul>
   * <li>GridGeometry2D
   * <li>GeneralEnvelope
   * <li>assorted metadata stuff mentioned by ResourceInfo
   * </ul>
   * @author Jody
   */
  public class Info implements ResourceInfo {
    private GridGeometry2D geometry;
    private GeneralEnvelope extent;
    private final Name name;
    private String title;
    private URI dataProduct;
   
    public Info( Name name ){
      this.name = name;
    }
    /**
     * We may need to improve ReferencedEnvelope to handle more
     * cases.
     */
    public ReferencedEnvelope getBounds() {
      return new ReferencedEnvelope(extent);
    }   
    public CoordinateReferenceSystem getCRS() {
      return extent.getCoordinateReferenceSystem();
    }
    public URI getDataProduct() {
      return dataProduct;
    }
    public String getDescription() {
      return null;
    }
    public GeneralEnvelope getExtent() {
      return extent;
    }
    public GridGeometry2D getGeometry() {
      return geometry;
    }
    public Set<String> getKeywords() {
      return null;
    }
    public String getName() {
      return name.getLocalPart();
    }   
    public Name getKey(){
      return name;
    }
    /**
     * This should be some indication of the data product being provided.
     */
    public URI getSchema() {
      return dataProduct;
    }
    public String getTitle() {
      return title;
    }
    public void setDataProduct(URI dataProduct) {
      this.dataProduct = dataProduct;
    }
    public void setExtent(GeneralEnvelope extent) {
      this.extent = extent;
    }
    public void setGeometry(GridGeometry2D geometry) {
      this.geometry = geometry;
    }
    public void setTitle(String title) {
      this.title = title;
    }
  }
  static abstract class RangePolicy {
    /**
     * Describe the provided GridCoverage.
     *
     * @param coverage
     * @return RangeType describing available data as a series of FieldType
     */
    public abstract RangeType describe(GridCoverage2D coverage);

    /**
     * Right now the init method asks the reader to produce a GridCoverage;
     * this method should switch to a ligther weight solution in the future
     * when metadata entries are available to check.
     * <p>
     * For now we usually check the SampleDimensions (as the best
     * description available).
     *
     * @param coverage
     * @return
     */
    public abstract boolean match(GridCoverage2D coverage);
  }

  /** Closure called with read access */
  public static abstract class Read<T> {
    public abstract T run(GeoTiffReader reader, GeoTiffAccess access)
        throws IOException;
  }

  /**
   * Recognise an RGB raster and produce a RangeType.
   */
  static class RGBPolicy extends RangePolicy {
    @Override
    public RangeType describe(GridCoverage2D coverage) {
      final GridSampleDimension[] sampleDimensions = coverage.getSampleDimensions();
      final HashSet<SampleDimension> samples = new HashSet<SampleDimension>(Arrays.asList(sampleDimensions));
      final WavelengthAxis<Double> axis=WavelengthAxis.RGB;
      final List<Axis<?,?>> axes= new ArrayList<Axis<?,?>>();
      axes.add(axis);
      final FieldType field = new DefaultFieldType( new NameImpl("RGB-FiledType"), new SimpleInternationalString("RGB image field"), Dimensionless.UNIT,axes, samples);
      final DefaultRangeType range = new DefaultRangeTypenew NameImpl("RGB-RangeType")new SimpleInternationalString("RGB range field"), Collections.singleton(field) )
      return range;
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean match(GridCoverage2D coverage) {
      final GridSampleDimension[] sampleDimensions = coverage.getSampleDimensions();
      if(sampleDimensions.length == 3)
      {
        final RenderedImage raster=coverage.getRenderedImage();
        if(raster==null)
          return false;
        final ColorModel cm= raster.getColorModel();
        if(cm==null)
          return false;       
        //get the color interpretation for the three bands
        if(TypeMap.getColorInterpretation(cm, 0)!=ColorInterpretation.RED_BAND)
          return false;
        if(TypeMap.getColorInterpretation(cm, 1)!=ColorInterpretation.GREEN_BAND)
          return false;
        if(TypeMap.getColorInterpretation(cm,2)!=ColorInterpretation.BLUE_BAND)
          return false;
        return true;
      }
      return false;
    }
  }

  /** Closure called with read access */
  public static abstract class Write<T> {
    public abstract T run(GeoTiffWriter reader, GeoTiffAccess access)
        throws IOException;
  }

  /**
   * Utility method to quickly report a failure to the progress listener and
   * make it available to rethrow.
   *
   * @param <T>
   * @param listener
   * @param problem
   * @return problem
   */
  private static <T extends Throwable> T fail(ProgressListener listener,
      T problem) {
    listener.exceptionOccurred(problem);
    return problem;
  }

  /**
   * Lock used to control access to file set.
   */
  final ReadWriteLock globalLock = new ReentrantReadWriteLock();
 
  /**
   * Set access capabilities provided.
   */
  final Set<AccessType> allowedAccessTypes = EnumSet.noneOf(AccessType.class);
  /**
   * Class used for input.
   * <p>
   * Two possibilities exist in the codebase right now:
   * <ul>
   * <li>File
   * <li>InputStream
   * </ul>
   */
  Class<?> inputClass;
  /**
   * Indicate that a new GeoTiff must be created at the indicated url.
   */
  private boolean mustCreate;
  /**
   * Number of coverages contained in the GeoTiff.
   */
  private int numberOfCoverages = 0;
 
  /**
   * URL indicating the resource being accessed.
   */
  URL input;

  /**
   * Info about each coverage by Name.
   */ 
  @SuppressWarnings("unchecked")
  Map<Name, Info> coverageInfo = new ListOrderedMap();
 
  /**
   * GridGeometry2D lookup by Name.
   */
  //HashMap<Name, GridGeometry2D> coverageGeometries = new HashMap<Name, GridGeometry2D>();

  /**
   * Names for the available coverages.
   */
  //ArrayList<Name> coverageNames = new ArrayList<Name>();

  /**
   * Bounds for the available coverages.
   */
  //HashMap<Name, GeneralEnvelope> coverageExtents = new HashMap<Name, GeneralEnvelope>();

  /**
   * RangeType describing our coverages.
   */
  RangeType rangeType;

  /**
   * Name of this coverage data product.
   */
  private NameImpl name;

  private Map<String, Serializable> connectionParameters;
  /**
   * An internal class defining the policy to interact with the GridCoveage.
   * <p>
   * A policy is selected from the list below during the init() method; giving
   * us a single place to examin and decide how interaction occurs.
   */
  static List<RangePolicy> rangeDefinitions = new ArrayList<RangePolicy>();
  static {
    rangeDefinitions.add(new DEMPolicy());
    rangeDefinitions.add(new RGBPolicy());
   
  }
 
  /**
   * Access a GeoTiff from the provided source.
   * <p>
   * Please note this constructor has package visibility; you are expected to
   * use the GeoTiffDriver for any and all access.
   *
   * @param source
   * @param params
   * @param hints
   * @param listener
   * @param canCreate
   * @throws IOException
   */
  GeoTiffAccess(
      final Driver driver,
      URL source,
      final Map<String, Serializable> params,
      final Hints hints,
      ProgressListener listener,
      final boolean canCreate)
      throws IOException {
    super(driver);

    if (listener == null)
      listener = new NullProgressListener();

    // url lookup
    if (source == null) {
      if (params.containsKey(URL.key)) {
        source = (URL) params.get(URL.key);
      }
    }
    if (source == null)
      throw new IllegalArgumentException("Source 'url' is required");

    connectionParameters = new HashMap<String, Serializable>();
    if (params != null) {
      connectionParameters.putAll(params);
    }
    connectionParameters.put(URL.key, source);
    // get the protocol
    final String protocol = source.getProtocol();
    listener.setTask(new SimpleInternationalString("connect"));
    try {
      // file
      if (protocol.equalsIgnoreCase("file")) {
        // convert to file
        final File sourceFile = BaseFileDriver.urlToFile(source);

        // does it exists?
        if (!sourceFile.exists()) {
          // can we create?
          if (!canCreate) {
            throw new FileNotFoundException("GeoTIFF file '"+ sourceFile + "' does not exist.");
          }
          // leave a flag saying that we must create it
          this.mustCreate = true;

          // get the parent dir
          final File parentDir = sourceFile.getParentFile();
          // check that it is directory,exists and can be written
          if (!parentDir.exists() || !parentDir.isDirectory()|| !parentDir.canWrite()) {
            throw new IllegalArgumentException("Invalid input");
          }
          // set access type
          this.allowedAccessTypes.add(AccessType.READ_WRITE);
        } else {
          // check that it is a file,exists and can be at least read
          if (!sourceFile.exists() || !sourceFile.isFile()|| !sourceFile.canRead()) {
            throw fail(listener, new IllegalArgumentException("Read access required to file " + sourceFile));
          }
          // set access type
          if (sourceFile.canWrite()) {
            // set access type
            this.allowedAccessTypes.add(AccessType.READ_WRITE);
          }
          // set access type
          this.allowedAccessTypes.add(AccessType.READ_ONLY);
        }
        listener.progress(0.1f);
        // set the class type
        this.inputClass = File.class;
        this.input = source;

        // initialize
        this.init();

        return;
      }

      // input stream
      if (protocol.equalsIgnoreCase("http")
          || protocol.equalsIgnoreCase("ftp")) {
        InputStream inStream = null;
        try {
          listener.progress(0.1f);
          // check that the url actually exists and can be read
          inStream = source.openStream();

          // try and read a few bytes
          final byte[] bytes = new byte[256];
          if (inStream.read(bytes) <= 0) {
            throw new IllegalArgumentException(
                "Input stream could not be opened");
          }
          // set the input class type
          this.inputClass = InputStream.class;
          this.input = source;

          // set access type
          this.allowedAccessTypes.add(AccessType.READ_ONLY);

          // initialize
          this.init();

          return;
        } catch (Throwable t) {
          throw fail(listener, new IllegalArgumentException(
              "Could not connect to input", t));
        } finally {
          if (inStream != null)
            try {

            } catch (Exception e) {
              inStream.close();
            }
        }

      }
      // nothing else for the moment
      throw new IllegalArgumentException("Invalid input");
    } finally {
      listener.complete();
    }
  } 

  public CoverageSource access(Name name, Map<String, Serializable> params,
      AccessType accessType, Hints hints, ProgressListener listener)
      throws IOException {
    if (listener == null)
      listener = new NullProgressListener();
    listener.started();
    try {
      if (!allowedAccessTypes.contains(accessType))
        throw new IllegalAccessError("Illegal access type requested");
      if (!this.coverageInfo.containsKey(name)) {
        String localPart = name.getLocalPart().lastIndexOf(":") > 0 ? name
            .getLocalPart().substring(
                name.getLocalPart().lastIndexOf(":") + 1)
            : name.getLocalPart();
        if (!this.coverageInfo.containsKey(new NameImpl(localPart))) {
          throw new IllegalArgumentException("Name not found "
              + name.toString());
        } else
          return new GeoTiffStore(this, new NameImpl(localPart));
      } else
        return new GeoTiffStore(this, name);
    } finally {
      listener.complete();
    }
  }

  public boolean canCreate(Name name, Map<String, Serializable> params,
      Hints hints, ProgressListener listener) throws IOException {
    return allowedAccessTypes.contains(AccessType.READ_WRITE);
  }


  /*
   * (non-Javadoc)
   *
   * @see
   * org.geotools.coverage.io.CoverageAccess#create(org.opengis.feature.type
   * .Name, java.util.Map, org.geotools.coverage.io.CoverageAccess.AccessType,
   * org.geotools.factory.Hints, org.opengis.util.ProgressListener)
   */
  public CoverageStore create(Name name, Map<String, Serializable> params,
      Hints hints, ProgressListener listener) throws IOException {
    if (!allowedAccessTypes.contains(AccessType.READ_WRITE)) {
      throw new IllegalAccessError("Illegal access type requested");
    }
    this.coverageInfo.put(name, new Info(name));
    return new GeoTiffStore(this, name);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.geotools.coverage.io.CoverageAccess#dispose()
   */
  public void dispose() {
    input = null;
    inputClass = null;
  }


  public Map<String, Serializable> getConnectParameters() {
    return Collections.unmodifiableMap(connectionParameters);
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.geotools.coverage.io.CoverageAccess#getExtent(org.opengis.feature
   * .type.Name, org.opengis.util.ProgressListener)
   */
  public GeneralEnvelope getExtent(Name name,
      ProgressListener listener) {
   
    Info info = getInfo( name, listener);
    return info.getExtent();
  }

  /**
   * ResourceInfo for the indicated coverage.
   * @param name
   * @param listener
   * @return
   */
  public Info getInfo(final Name name, ProgressListener listener) {
    /**
     * I am going to lazily create these and hold onto them rather than having a bunch
     * of little HashMaps for things like Extent; CoverageGeometries and so on...
     */
    if (listener == null){
      listener = new NullProgressListener();
    }
    try {
      listener.started();
      if( coverageInfo.containsKey(name)){
        return coverageInfo.get(name);
      }
      /*
      // info not available let us look?
      return read(new Read<Info>() {
        public Info run(GeoTiffReader reader,
            GeoTiffAccess access) throws IOException {
          // check again incase another thread was fetching the answer
          if( coverageInfo.containsKey(name)){
            return coverageInfo.get(name);
          }
          // okay let us figure it out
          return new Info(name);
        }
      });
      */
      listener.exceptionOccurred(new IOException("Unknown coverage "+name));
      return null;
    }
    finally {
      listener.complete();
    }
  }

  /*
   * (non-Javadoc)
   *
   * @seeorg.geotools.coverage.io.CoverageAccess#getInfo(org.opengis.util.
   * ProgressListener)
   */
  public ServiceInfo getInfo(ProgressListener listener) {
    if (listener == null)
      listener = new NullProgressListener();
    try {
      return read(new Read<ServiceInfo>() {
        public ServiceInfo run(GeoTiffReader reader,
            GeoTiffAccess access) throws IOException {
          DefaultServiceInfo info = new DefaultServiceInfo();
          info.setTitle(reader.getCoverageName());

          StringBuffer description = new StringBuffer();
         
          Driver driver = getDriver();
          description.append( "Name: ");
          description.append( reader.getCoverageName() );
          description.append( "\nDriver: ");
          description.append( driver.getName() );
          description.append( "/" );
          description.append( getDriver().getTitle() );
          description.append( "\nSize is ");
          GridEnvelope size = reader.getOriginalGridRange();
          description.append(size.getSpan(0));
          description.append(", ");
          description.append(size.getSpan(1));
          description.append("\nCoordinate System is:\n");
          CoordinateReferenceSystem crs = reader.getCrs();
          description.append( crs.toWKT() );
         
          GeneralEnvelope bbox = reader.getOriginalEnvelope();         
          description.append("\nOrigion = ( ");
          DirectPosition lower = bbox.getLowerCorner();
         
          for( int dimension = 0; dimension < crs.getCoordinateSystem().getDimension(); dimension++ ){           
            if( dimension != 0 ){
              description.append(", ");
            }
            description.append( lower.getOrdinate( dimension ) );           
          }
          description.append(" )");
         
          info.setDescription(description.toString());

          try {
            info.setSource(input.toURI());
          } catch (URISyntaxException e1) {
          }
          try {
            // This should be a representation of the data product
            info.setSchema(new URI(
                    "http://www.remotesensing.org/geotiff/spec/geotiffhome.html"));
          } catch (URISyntaxException e) {
          }
          try {
            if (inputClass == File.class) {
              info.setPublisher(new URI(System
                  .getProperty("user.name")));
            } else {
              info.setPublisher(new URI(input.getProtocol()
                  + input.getHost()));
            }
          } catch (URISyntaxException e) {
            e.printStackTrace();
          }
          return info;
        }
      });
    } catch (IOException problem) {
      listener.exceptionOccurred(problem);
      return null;
    }
  }

  /*
   * (non-Javadoc)
   *
   * @seeorg.geotools.coverage.io.CoverageAccess#getNames(org.opengis.util.
   * ProgressListener)
   */
  public List<Name> getNames(ProgressListener listener) {
    if (listener == null)
      listener = new NullProgressListener();
    listener.started();
    try {
      return Collections.unmodifiableList(
          new ArrayList<Name>( coverageInfo.keySet()));
    } finally {
      listener.complete();
    }
  }
 
  /*
   * (non-Javadoc)
   *
   * @see
   * org.geotools.coverage.io.CoverageAccess#getNumCoverages(org.opengis.util
   * .ProgressListener)
   */
  public int getCoveragesNumber(ProgressListener listener) {
    return this.numberOfCoverages;
  }
  public Set<AccessType> getSupportedAccessTypes() {
    return Collections.unmodifiableSet(allowedAccessTypes);
  }

  private void init() throws IOException {
    // check if we already have something or not
    if (this.mustCreate) {
      this.numberOfCoverages = 0;
      return;
    }
    try  {
      read(new Read<Object>() {
        @Override
        public Object run(GeoTiffReader reader, GeoTiffAccess access)
            throws IOException {
          // set the number of coverages
          numberOfCoverages = reader.getGridCoverageCount();
 
          final GeneralEnvelope envelope = reader.getOriginalEnvelope();
          final CoordinateReferenceSystem crs = reader.getCrs();
          final GridEnvelope range = reader.getOriginalGridRange();
          final MathTransform2D g2w = (MathTransform2D) reader
              .getOriginalGridToWorld(PixelInCell.CELL_CENTER);
 
          name = new NameImpl(reader.getCoverageName());
          Info info = new Info( name );
          info.setGeometry( new GridGeometry2D(range, g2w, crs) );
          info.setExtent(envelope);
          coverageInfo.put( name, info );

          // init RANGE
          final GridCoverage2D gc = (GridCoverage2D) reader.read(null);
          for (RangePolicy policy : rangeDefinitions) {
            try {
              if (policy.match(gc)) {
                rangeType = policy.describe(gc);
              }
            } catch (Throwable eek) {
 
            }
          }         
          return null; // nothing to return
        }
      });
    }
    catch (Throwable t ){
      // could not init out state ... something must be horribly wrong
      numberOfCoverages = 0;
      coverageInfo.clear();     
      if( t instanceof IOException ){
        throw (IOException) t;
      }
      else {
        throw new DataSourceException("Could not initialize FieldType information", t );
      }
    }
    // get the needed info from them to set the extent
  }

  public boolean isCreateSupported() {
    return allowedAccessTypes.contains(AccessType.READ_WRITE);
  }

  /** Method called to read the GeoTiff file or input stream */
  public <T> T read(Read<T> read) throws IOException {
    // open up a reader
    globalLock.readLock().lock();
    try {
      GeoTiffReader reader = new GeoTiffReader(this.input);
      try {
        return read.run(reader, this);
      } finally {
        if (reader != null) {
          reader.dispose();
        }
      }
    } finally {
      globalLock.readLock().unlock();
    }
  }

  //
  // utility methods
  //

  /** Method called to read the GeoTiff file or input stream */
  public <T> T write(Write<T> write) throws IOException {
    // open up a reader
    globalLock.writeLock().lock();
    try {
      GeoTiffWriter writer = new GeoTiffWriter(this.input);
      try {
        return write.run(writer, this);
      } finally {
        if (writer != null) {
          writer.dispose();
        }
      }
    } finally {
      globalLock.writeLock().unlock();
    }
  }
}
TOP

Related Classes of org.geotools.coverage.io.geotiff.GeoTiffAccess$RGBPolicy

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.