/** * 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; }
/** * 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); } }
/** * 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) { } } }