예제 #1
0
  /**
   * 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;
  }
예제 #2
0
  /**
   * 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.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();
    }

    AffineTransform rasterToModel = getRescaledRasterToModel(coverageRaster);
    try {
      return createCoverage(coverageRaster, ProjectiveTransform.create(rasterToModel));
    } catch (Exception e) {
      // dispose and close file
      ImageUtilities.disposePlanarImageChain(coverageRaster);

      // rethrow
      if (e instanceof DataSourceException) {
        throw (DataSourceException) e;
      }
      throw new DataSourceException(e);
    }
  }
예제 #3
0
  /**
   * 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) {
        TiePoint[] modelTiePoints = metadata.getModelTiePoints();
        if (modelTiePoints != null && modelTiePoints.length > 1) {
          // use a unit transform and expose the GCPs
          gcps = new GroundControlPoints(Arrays.asList(modelTiePoints), crs);
          raster2Model = ProjectiveTransform.create(new AffineTransform());
          crs = AbstractGridFormat.getDefaultCRS();
        } else {
          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) {
        }
    }
  }