private static void applyGeoCodingFromGeoTiff(TIFFImageMetadata metadata, Product product) throws Exception { final Rectangle imageBounds = new Rectangle(product.getSceneRasterWidth(), product.getSceneRasterHeight()); final GeoTiffIIOMetadataDecoder metadataDecoder = new GeoTiffIIOMetadataDecoder(metadata); final GeoTiffMetadata2CRSAdapter geoTiff2CRSAdapter = new GeoTiffMetadata2CRSAdapter(null); // todo reactivate the following line if geotools has fixed the problem. (see BEAM-1510) // final MathTransform toModel = GeoTiffMetadata2CRSAdapter.getRasterToModel(metadataDecoder, // false); final MathTransform toModel = getRasterToModel(metadataDecoder); CoordinateReferenceSystem crs; try { crs = geoTiff2CRSAdapter.createCoordinateSystem(metadataDecoder); } catch (UnsupportedOperationException e) { if (toModel == null) { throw e; } else { // ENVI falls back to WGS84, if no CRS is given in the GeoTIFF. crs = DefaultGeographicCRS.WGS84; } } final CrsGeoCoding geoCoding = new CrsGeoCoding(crs, imageBounds, (AffineTransform) toModel); product.setGeoCoding(geoCoding); }
/** * 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) { } } }