/**
   * Retrieves the original grid to world transformation for this {@link
   * AbstractGridCoverage2DReader}.
   *
   * @param pixInCell specifies the datum of the transformation we want.
   * @return the original grid to world transformation for this {@link
   *     AbstractGridCoverage2DReader}.
   */
  @Override
  public MathTransform getOriginalGridToWorld(String coverageName, PixelInCell pixInCell) {
    if (!checkName(coverageName)) {
      throw new IllegalArgumentException(
          "The specified coverageName " + coverageName + "is not supported");
    }
    synchronized (this) {
      if (raster2Model == null) {
        final GridToEnvelopeMapper geMapper =
            new GridToEnvelopeMapper(
                getOriginalGridRange(coverageName), getOriginalEnvelope(coverageName));
        geMapper.setPixelAnchor(PixelInCell.CELL_CENTER);
        raster2Model = geMapper.createTransform();
      }
    }

    // we do not have to change the pixel datum
    if (pixInCell == PixelInCell.CELL_CENTER) return raster2Model;

    // we do have to change the pixel datum
    if (raster2Model instanceof AffineTransform) {
      final AffineTransform tr = new AffineTransform((AffineTransform) raster2Model);
      tr.concatenate(AffineTransform.getTranslateInstance(-0.5, -0.5));
      return ProjectiveTransform.create(tr);
    }
    if (raster2Model instanceof IdentityTransform) {
      final AffineTransform tr = new AffineTransform(1, 0, 0, 1, 0, 0);
      tr.concatenate(AffineTransform.getTranslateInstance(-0.5, -0.5));
      return ProjectiveTransform.create(tr);
    }
    throw new IllegalStateException("This reader's grid to world transform is invalud!");
  }
Beispiel #2
0
  private void init(
      final BoundingBox granuleBBOX,
      final URL granuleUrl,
      final ImageReaderSpi suggestedSPI,
      final Geometry inclusionGeometry,
      final boolean heterogeneousGranules,
      final boolean handleArtifactsFiltering) {
    this.granuleBBOX = ReferencedEnvelope.reference(granuleBBOX);
    this.granuleUrl = granuleUrl;
    this.inclusionGeometry = inclusionGeometry;
    this.handleArtifactsFiltering = handleArtifactsFiltering;
    filterMe = handleArtifactsFiltering && inclusionGeometry != null;

    // create the base grid to world transformation
    ImageInputStream inStream = null;
    ImageReader reader = null;
    try {
      //
      // get info about the raster we have to read
      //

      // get a stream
      if (cachedStreamSPI == null) {
        cachedStreamSPI = ImageIOExt.getImageInputStreamSPI(granuleUrl, true);
        if (cachedStreamSPI == null) {
          final File file = DataUtilities.urlToFile(granuleUrl);
          if (file != null) {
            if (LOGGER.isLoggable(Level.WARNING)) {
              LOGGER.log(Level.WARNING, Utils.getFileInfo(file));
            }
          }
          throw new IllegalArgumentException(
              "Unable to get an input stream for the provided granule " + granuleUrl.toString());
        }
      }
      assert cachedStreamSPI != null : "no cachedStreamSPI available!";
      inStream =
          cachedStreamSPI.createInputStreamInstance(
              granuleUrl, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
      if (inStream == null) {
        final File file = DataUtilities.urlToFile(granuleUrl);
        if (file != null) {
          if (LOGGER.isLoggable(Level.WARNING)) {
            LOGGER.log(Level.WARNING, Utils.getFileInfo(file));
          }
        }
        throw new IllegalArgumentException(
            "Unable to get an input stream for the provided file " + granuleUrl.toString());
      }

      // get a reader and try to cache the suggested SPI first
      if (cachedReaderSPI == null) {
        inStream.mark();
        if (suggestedSPI != null && suggestedSPI.canDecodeInput(inStream)) {
          cachedReaderSPI = suggestedSPI;
          inStream.reset();
        } else {
          inStream.mark();
          reader = ImageIOExt.getImageioReader(inStream);
          if (reader != null) cachedReaderSPI = reader.getOriginatingProvider();
          inStream.reset();
        }
      }
      reader = cachedReaderSPI.createReaderInstance();
      if (reader == null)
        throw new IllegalArgumentException(
            "Unable to get an ImageReader for the provided file " + granuleUrl.toString());
      reader.setInput(inStream);
      // get selected level and base level dimensions
      final Rectangle originalDimension = Utils.getDimension(0, reader);

      // build the g2W for this tile, in principle we should get it
      // somehow from the tile itself or from the index, but at the moment
      // we do not have such info, hence we assume that it is a simple
      // scale and translate
      final GridToEnvelopeMapper geMapper =
          new GridToEnvelopeMapper(new GridEnvelope2D(originalDimension), granuleBBOX);
      geMapper.setPixelAnchor(
          PixelInCell
              .CELL_CENTER); // this is the default behavior but it is nice to write it down anyway
      this.baseGridToWorld = geMapper.createAffineTransform();

      try {
        if (inclusionGeometry != null) {
          geMapper.setPixelAnchor(PixelInCell.CELL_CORNER);
          Geometry mapped = JTS.transform(inclusionGeometry, geMapper.createTransform().inverse());
          this.granuleROIShape = new ROIGeometry(mapped);
        }

      } catch (TransformException e1) {
        throw new IllegalArgumentException(e1);
      }

      // add the base level
      this.granuleLevels.put(
          Integer.valueOf(0),
          new GranuleOverviewLevelDescriptor(
              1, 1, originalDimension.width, originalDimension.height));

      ////////////////////// Setting overviewController ///////////////////////
      if (heterogeneousGranules) {
        // //
        //
        // Right now we are setting up overviewsController by assuming that
        // overviews are internal images as happens in TIFF images
        // We can improve this by leveraging on coverageReaders
        //
        // //

        // Getting the first level descriptor
        final GranuleOverviewLevelDescriptor baseOverviewLevelDescriptor = granuleLevels.get(0);

        // Variables initialization
        final int numberOfOvervies = reader.getNumImages(true) - 1;
        final AffineTransform2D baseG2W = baseOverviewLevelDescriptor.getGridToWorldTransform();
        final int width = baseOverviewLevelDescriptor.getWidth();
        final int height = baseOverviewLevelDescriptor.getHeight();
        final double resX = AffineTransform2D.getScaleX0(baseG2W);
        final double resY = AffineTransform2D.getScaleY0(baseG2W);
        final double[] highestRes = new double[] {resX, resY};
        final double[][] overviewsResolution = new double[numberOfOvervies][2];

        // Populating overviews and initializing overviewsController
        for (int i = 0; i < numberOfOvervies; i++) {
          overviewsResolution[i][0] = (highestRes[0] * width) / reader.getWidth(i + 1);
          overviewsResolution[i][1] = (highestRes[1] * height) / reader.getWidth(i + 1);
        }
        overviewsController =
            new OverviewsController(highestRes, numberOfOvervies, overviewsResolution);
      }
      //////////////////////////////////////////////////////////////////////////

    } catch (IllegalStateException e) {
      throw new IllegalArgumentException(e);

    } catch (IOException e) {
      throw new IllegalArgumentException(e);
    } finally {
      // close/dispose stream and readers
      try {
        if (inStream != null) {
          inStream.close();
        }
      } catch (Throwable e) {
        throw new IllegalArgumentException(e);
      } finally {
        if (reader != null) {
          reader.dispose();
        }
      }
    }
  }
 @Override
 protected GridToEnvelopeMapper initialValue() {
   final GridToEnvelopeMapper mapper = new GridToEnvelopeMapper();
   mapper.setPixelAnchor(PixelInCell.CELL_CORNER);
   return mapper;
 }
  /**
   * Tests the {@link OverviewsController} with support for different resolutions/different number
   * of overviews.
   *
   * <p>world_a.tif => Pixel Size = (0.833333333333333,-0.833333333333333); 4 overviews world_b.tif
   * => Pixel Size = (1.406250000000000,-1.406250000000000); 2 overviews
   *
   * @throws IOException
   * @throws MismatchedDimensionException
   * @throws FactoryException
   * @throws TransformException
   */
  @Test
  public void testHeterogeneousGranules()
      throws IOException, MismatchedDimensionException, FactoryException, TransformException {

    final CoordinateReferenceSystem WGS84 = CRS.decode("EPSG:4326", true);
    final ReferencedEnvelope TEST_BBOX_A = new ReferencedEnvelope(-180, 0, -90, 90, WGS84);
    final ReferencedEnvelope TEST_BBOX_B = new ReferencedEnvelope(0, 180, 0, 90, WGS84);

    URL heterogeneousGranulesURL = TestData.url(this, "heterogeneous");
    // //
    //
    // Initialize mosaic variables
    //
    // //
    final Hints hints = new Hints(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, WGS84);
    final AbstractGridFormat format =
        (AbstractGridFormat) GridFormatFinder.findFormat(heterogeneousGranulesURL, hints);
    Assert.assertNotNull(format);
    Assert.assertFalse("UknownFormat", format instanceof UnknownFormat);

    final ImageMosaicReader reader =
        (ImageMosaicReader) format.getReader(heterogeneousGranulesURL, hints);
    Assert.assertNotNull(reader);

    final int nOv = reader.getNumberOfOvervies();
    final double[] hRes = reader.getHighestRes();
    final RasterManager rasterManager = new RasterManager(reader);

    // //
    //
    // Initialize granules related variables
    //
    // //
    final File g1File = new File(DataUtilities.urlToFile(heterogeneousGranulesURL), "world_a.tif");
    final File g2File = new File(DataUtilities.urlToFile(heterogeneousGranulesURL), "world_b.tif");
    final ImageReadParam readParamsG1 = new ImageReadParam();
    final ImageReadParam readParamsG2 = new ImageReadParam();
    int imageIndexG1 = 0;
    int imageIndexG2 = 0;

    final GranuleDescriptor granuleDescriptor1 =
        new GranuleDescriptor(g1File.getAbsolutePath(), TEST_BBOX_A, spi, (Geometry) null, true);
    final GranuleDescriptor granuleDescriptor2 =
        new GranuleDescriptor(g2File.getAbsolutePath(), TEST_BBOX_B, spi, (Geometry) null, true);
    assertNotNull(granuleDescriptor1.toString());
    assertNotNull(granuleDescriptor2.toString());

    final OverviewsController ovControllerG1 = granuleDescriptor1.overviewsController;
    final OverviewsController ovControllerG2 = granuleDescriptor2.overviewsController;

    // //
    //
    // Initializing read request
    //
    // //
    final GeneralEnvelope envelope = reader.getOriginalEnvelope();
    final GridEnvelope originalRange = reader.getOriginalGridRange();
    final Rectangle rasterArea =
        new Rectangle(
            0,
            0,
            (int) Math.ceil(originalRange.getSpan(0) / 9.0),
            (int) Math.ceil(originalRange.getSpan(1) / 9.0));
    final GridEnvelope2D range = new GridEnvelope2D(rasterArea);
    final GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(range, envelope);
    geMapper.setPixelAnchor(PixelInCell.CELL_CENTER);
    final AffineTransform gridToWorld = geMapper.createAffineTransform();
    final double requestedResolution[] =
        new double[] {
          XAffineTransform.getScaleX0(gridToWorld), XAffineTransform.getScaleY0(gridToWorld)
        };

    TestSet at = null;
    if (nOv == 4 && Math.abs(hRes[0] - 0.833333333333) <= THRESHOLD) {
      at = at1;
    } else if (nOv == 2 && Math.abs(hRes[0] - 1.40625) <= THRESHOLD) {
      at = at2;
    } else {
      return;
    }

    // //
    //
    // Starting OverviewsController tests
    //
    // //
    final OverviewPolicy[] ovPolicies =
        new OverviewPolicy[] {
          OverviewPolicy.QUALITY,
          OverviewPolicy.SPEED,
          OverviewPolicy.NEAREST,
          OverviewPolicy.IGNORE
        };
    for (int i = 0; i < ovPolicies.length; i++) {
      OverviewPolicy ovPolicy = ovPolicies[i];
      LOGGER.info("Testing with OverviewPolicy = " + ovPolicy.toString());
      imageIndexG1 =
          ReadParamsController.setReadParams(
              requestedResolution,
              ovPolicy,
              DecimationPolicy.ALLOW,
              readParamsG1,
              rasterManager,
              ovControllerG1);
      imageIndexG2 =
          ReadParamsController.setReadParams(
              requestedResolution,
              ovPolicy,
              DecimationPolicy.ALLOW,
              readParamsG2,
              rasterManager,
              ovControllerG2);
      assertSame(at.ot[i].g1.imageIndex, imageIndexG1);
      assertSame(at.ot[i].g2.imageIndex, imageIndexG2);
      assertSame(at.ot[i].g1.ssx, readParamsG1.getSourceXSubsampling());
      assertSame(at.ot[i].g1.ssy, readParamsG1.getSourceYSubsampling());
      assertSame(at.ot[i].g2.ssx, readParamsG2.getSourceXSubsampling());
      assertSame(at.ot[i].g2.ssy, readParamsG2.getSourceYSubsampling());
    }
  }