/**
   * Creates a new instance of a {@link AIGReader}. I assume nothing about file extension.
   *
   * @param input Source object for which we want to build an {@link AIGReader}.
   * @param hints Hints to be used by this reader throughout his life.
   * @throws DataSourceException
   */
  public AbstractGridCoverage2DReader(Object input, Hints hints) throws DataSourceException {

    //
    // basic management of hints
    //
    if (hints == null) this.hints = new Hints();
    if (hints != null) {
      this.hints = hints.clone();
    }

    // GridCoverageFactory initialization
    if (this.hints.containsKey(Hints.GRID_COVERAGE_FACTORY)) {
      final Object factory = this.hints.get(Hints.GRID_COVERAGE_FACTORY);
      if (factory != null && factory instanceof GridCoverageFactory) {
        this.coverageFactory = (GridCoverageFactory) factory;
      }
    }
    if (this.coverageFactory == null) {
      this.coverageFactory = CoverageFactoryFinder.getGridCoverageFactory(this.hints);
    }

    //
    // Setting input
    //
    if (input == null) {
      final IOException ex = new IOException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1, "input"));
      throw new DataSourceException(ex);
    }
    this.source = input;
  }
Example #2
0
  /**
   * Performs a translation using the "Resample" operation.
   *
   * @param grid the {@link GridCoverage2D} to apply the translation on.
   * @throws NoninvertibleTransformException If a "grid to CRS" transform is not invertible.
   */
  private void doTranslation(GridCoverage2D grid) throws NoninvertibleTransformException {
    final int transX = -253;
    final int transY = -456;
    final double scaleX = 0.04;
    final double scaleY = -0.04;
    final ParameterBlock block =
        new ParameterBlock()
            .addSource(grid.getRenderedImage())
            .add((float) transX)
            .add((float) transY);
    RenderedImage image = JAI.create("Translate", block);
    assertEquals("Incorrect X translation", transX, image.getMinX());
    assertEquals("Incorrect Y translation", transY, image.getMinY());

    /*
     * Create a grid coverage from the translated image but with the same envelope.
     * Consequently, the 'gridToCoordinateSystem' should be translated by the same
     * amount, with the opposite sign.
     */
    AffineTransform expected = getAffineTransform(grid);
    assertNotNull(expected);
    expected = new AffineTransform(expected); // Get a mutable instance.
    final GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null);
    grid =
        factory.create(
            "Translated",
            image,
            grid.getEnvelope(),
            grid.getSampleDimensions(),
            new GridCoverage2D[] {grid},
            grid.getProperties());
    expected.translate(-transX, -transY);
    assertTransformEquals(expected, getAffineTransform(grid));

    /*
     * Apply the "Resample" operation with a specific 'gridToCoordinateSystem' transform.
     * The envelope is left unchanged. The "Resample" operation should compute automatically
     * new image bounds.
     */
    final AffineTransform at = AffineTransform.getScaleInstance(scaleX, scaleY);
    final MathTransform tr = ProjectiveTransform.create(at);
    // account for the half pixel correction between the two spaces since we are talking raster here
    // but the resample will talk model!
    final MathTransform correctedTransform =
        PixelTranslation.translate(tr, PixelInCell.CELL_CORNER, PixelInCell.CELL_CENTER);
    final GridGeometry2D geometry = new GridGeometry2D(null, correctedTransform, null);
    final GridCoverage2D newGrid =
        (GridCoverage2D)
            Operations.DEFAULT.resample(grid, grid.getCoordinateReferenceSystem(), geometry, null);
    assertEquals(correctedTransform, getAffineTransform(newGrid));
    image = newGrid.getRenderedImage();
    expected.preConcatenate(at.createInverse());
    final Point point = new Point(transX, transY);
    assertSame(point, expected.transform(point, point)); // Round toward neareast integer
  }
  /**
   * Creates a {@link GridCoverage2D coverage} from the {@link WritableRaster writable raster} and
   * the necessary geographic Information.
   *
   * @param name the name of the coverage.
   * @param writableRaster the raster containing the data.
   * @param envelopeParams the map of boundary parameters.
   * @param crs the {@link CoordinateReferenceSystem}.
   * @return the {@link GridCoverage2D coverage}.
   */
  public static GridCoverage2D buildCoverage(
      String name,
      WritableRaster writableRaster,
      HashMap<String, Double> envelopeParams,
      CoordinateReferenceSystem crs) {

    double west = envelopeParams.get(WEST);
    double south = envelopeParams.get(SOUTH);
    double east = envelopeParams.get(EAST);
    double north = envelopeParams.get(NORTH);
    Envelope2D writeEnvelope = new Envelope2D(crs, west, south, east - west, north - south);
    GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null);

    GridCoverage2D coverage2D = factory.create(name, writableRaster, writeEnvelope);
    return coverage2D;
  }
Example #4
0
  /** Tests that flipping axis on a coverage whose origin is not (0,0) works as expected */
  @Test
  public void testFlipTranslated() throws Exception {
    // build a translated image
    SampleModel sm =
        RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, 256, 256, 3);
    ColorModel cm = PlanarImage.createColorModel(sm);
    TiledImage ti = new TiledImage(-10, -10, 5, 5, 0, 0, sm, cm);
    Graphics2D g = ti.createGraphics();
    g.setColor(Color.GREEN);
    g.fillRect(-10, -10, 5, 5);
    g.dispose();

    // build a coverage around it
    CoordinateReferenceSystem wgs84LatLon = CRS.decode("EPSG:4326");
    final GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null);
    GridCoverage2D coverage =
        factory.create("translated", ti, new Envelope2D(wgs84LatLon, 3, 5, 6, 8));

    // verify we're good
    int[] pixel = new int[3];
    coverage.evaluate((DirectPosition) new DirectPosition2D(4, 6), pixel);
    assertEquals(0, pixel[0]);
    assertEquals(255, pixel[1]);
    assertEquals(0, pixel[2]);

    // now reproject flipping the axis
    CoordinateReferenceSystem wgs84LonLat = CRS.decode("EPSG:4326", true);
    GridGeometry gg =
        new GridGeometry2D(
            new GridEnvelope2D(-10, -10, 5, 5), (Envelope) new Envelope2D(wgs84LonLat, 5, 3, 8, 6));
    GridCoverage2D flipped =
        (GridCoverage2D)
            Operations.DEFAULT.resample(
                coverage, wgs84LonLat, gg, Interpolation.getInstance(Interpolation.INTERP_NEAREST));

    // before the fix the pixel would have been black
    flipped.evaluate((DirectPosition) new DirectPosition2D(6, 4), pixel);
    assertEquals(0, pixel[0]);
    assertEquals(255, pixel[1]);
    assertEquals(0, pixel[2]);
  }
  public void contextInitialized(ServletContextEvent sce) {
    // start up tctool - remove it before committing!!!!
    // new tilecachetool.TCTool().setVisible(true);

    // Register logging, and bridge to JAI logging
    GeoTools.init((Hints) null);

    // Custom GeoTools ImagingListener used to ignore common warnings
    JAI.getDefaultInstance()
        .setImagingListener(
            new ImagingListener() {
              final Logger LOGGER = Logging.getLogger("javax.media.jai");

              @Override
              public boolean errorOccurred(
                  String message, Throwable thrown, Object where, boolean isRetryable)
                  throws RuntimeException {
                if (isSerializableRenderedImageFinalization(where, thrown)) {
                  LOGGER.log(Level.FINEST, message, thrown);
                } else if (message.contains("Continuing in pure Java mode")) {
                  LOGGER.log(Level.FINE, message, thrown);
                } else {
                  LOGGER.log(Level.INFO, message, thrown);
                }
                return false; // we are not trying to recover
              }

              private boolean isSerializableRenderedImageFinalization(Object where, Throwable t) {
                if (!(where instanceof SerializableRenderedImage)) {
                  return false;
                }

                // check if it's the finalizer
                StackTraceElement[] elements = t.getStackTrace();
                for (StackTraceElement element : elements) {
                  if (element.getMethodName().equals("finalize")
                      && element.getClassName().endsWith("SerializableRenderedImage")) return true;
                }

                return false;
              }
            });

    // setup concurrent operation registry
    JAI jaiDef = JAI.getDefaultInstance();
    if (!(jaiDef.getOperationRegistry() instanceof ConcurrentOperationRegistry
        || jaiDef.getOperationRegistry()
            instanceof it.geosolutions.jaiext.ConcurrentOperationRegistry)) {
      jaiDef.setOperationRegistry(ConcurrentOperationRegistry.initializeRegistry());
    }

    // setup the concurrent tile cache (has proper memory limit handling also for small tiles)
    if (!(jaiDef.getTileCache() instanceof ConcurrentTileCacheMultiMap)) {
      jaiDef.setTileCache(new ConcurrentTileCacheMultiMap());
    }

    // make sure we remember if GeoServer controls logging or not
    String strValue =
        GeoServerExtensions.getProperty(
            LoggingUtils.RELINQUISH_LOG4J_CONTROL, sce.getServletContext());
    relinquishLoggingControl = Boolean.valueOf(strValue);

    // if the server admin did not set it up otherwise, force X/Y axis
    // ordering
    // This one is a good place because we need to initialize this property
    // before any other opeation can trigger the initialization of the CRS
    // subsystem
    if (System.getProperty("org.geotools.referencing.forceXY") == null) {
      System.setProperty("org.geotools.referencing.forceXY", "true");
    }
    if (Boolean.TRUE.equals(Hints.getSystemDefault(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER))) {
      Hints.putSystemDefault(Hints.FORCE_AXIS_ORDER_HONORING, "http");
    }
    Hints.putSystemDefault(Hints.LENIENT_DATUM_SHIFT, true);

    // setup the referencing tolerance to make it more tolerant to tiny differences
    // between projections (increases the chance of matching a random prj file content
    // to an actual EPSG code
    String comparisonToleranceProperty =
        GeoServerExtensions.getProperty(COMPARISON_TOLERANCE_PROPERTY);
    double comparisonTolerance = DEFAULT_COMPARISON_TOLERANCE;
    if (comparisonToleranceProperty != null) {
      try {
        comparisonTolerance = Double.parseDouble(comparisonToleranceProperty);
      } catch (NumberFormatException nfe) {
        if (LOGGER.isLoggable(Level.WARNING)) {
          LOGGER.warning(
              "Unable to parse the specified COMPARISON_TOLERANCE "
                  + "system property: "
                  + comparisonToleranceProperty
                  + " which should be a number. Using Default: "
                  + DEFAULT_COMPARISON_TOLERANCE);
        }
      }
    }
    Hints.putSystemDefault(Hints.COMPARISON_TOLERANCE, comparisonTolerance);

    final Hints defHints = GeoTools.getDefaultHints();

    // Initialize GridCoverageFactory so that we don't make a lookup every time a factory is needed
    Hints.putSystemDefault(
        Hints.GRID_COVERAGE_FACTORY, CoverageFactoryFinder.getGridCoverageFactory(defHints));

    // don't allow the connection to the EPSG database to time out. This is a server app,
    // we can afford keeping the EPSG db always on
    System.setProperty("org.geotools.epsg.factory.timeout", "-1");

    // HACK: java.util.prefs are awful. See
    // http://www.allaboutbalance.com/disableprefs. When the site comes
    // back up we should implement their better way of fixing the problem.
    System.setProperty("java.util.prefs.syncInterval", "5000000");

    // Fix issue with tomcat and JreMemoryLeakPreventionListener causing issues with
    // IIORegistry leading to imageio plugins not being properly initialized
    ImageIO.scanForPlugins();

    // in any case, the native png reader is worse than the pure java ones, so
    // let's disable it (the native png writer is on the other side faster)...
    ImageIOExt.allowNativeCodec("png", ImageReaderSpi.class, false);
    ImageIOExt.allowNativeCodec("png", ImageWriterSpi.class, true);

    // initialize GeoTools factories so that we don't make a SPI lookup every time a factory is
    // needed
    Hints.putSystemDefault(Hints.FILTER_FACTORY, CommonFactoryFinder.getFilterFactory2(null));
    Hints.putSystemDefault(Hints.STYLE_FACTORY, CommonFactoryFinder.getStyleFactory(null));
    Hints.putSystemDefault(Hints.FEATURE_FACTORY, CommonFactoryFinder.getFeatureFactory(null));

    // initialize the default executor service
    final ThreadPoolExecutor executor =
        new ThreadPoolExecutor(
            CoverageAccessInfoImpl.DEFAULT_CorePoolSize,
            CoverageAccessInfoImpl.DEFAULT_MaxPoolSize,
            CoverageAccessInfoImpl.DEFAULT_KeepAliveTime,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());
    Hints.putSystemDefault(Hints.EXECUTOR_SERVICE, executor);
  }
  public ArcSDEGridCoverage2DReaderJAI(
      final ArcSDERasterFormat parent,
      final RasterReaderFactory rasterReaderFactory,
      final RasterDatasetInfo rasterInfo,
      final Hints hints)
      throws IOException {
    // check it's a supported format
    {
      final int bitsPerSample = rasterInfo.getBand(0, 0).getCellType().getBitsPerSample();
      if (rasterInfo.getNumBands() > 1 && (bitsPerSample == 1 || bitsPerSample == 4)) {
        throw new IllegalArgumentException(
            bitsPerSample + "-bit rasters with more than one band are not supported");
      }
    }
    this.parent = parent;
    this.rasterReaderFactory = rasterReaderFactory;
    this.rasterInfo = rasterInfo;

    super.hints = hints;
    super.coverageFactory = CoverageFactoryFinder.getGridCoverageFactory(this.hints);
    super.crs = rasterInfo.getCoverageCrs();
    super.originalEnvelope = rasterInfo.getOriginalEnvelope(PixelInCell.CELL_CENTER);

    GridEnvelope gridRange = rasterInfo.getOriginalGridRange();
    // super.originalGridRange = new GeneralGridRange(gridRange.toRectangle());
    super.originalGridRange = gridRange;

    super.coverageName = rasterInfo.getRasterTable();
    final int numLevels = rasterInfo.getNumPyramidLevels(0);

    // level 0 is not an overview, but the raster itself
    super.numOverviews = numLevels - 1;

    // ///
    //
    // setting the higher resolution avalaible for this coverage
    //
    // ///
    highestRes =
        super.getResolution(
            originalEnvelope,
            new Rectangle(
                originalGridRange.getLow(0),
                originalGridRange.getLow(1),
                originalGridRange.getSpan(0),
                originalGridRange.getSpan(1)),
            crs);
    // //
    //
    // get information for the successive images
    //
    // //
    // REVISIT may the different rasters in the raster dataset have different pyramid levels? I
    // guess so
    if (numOverviews > 0) {
      overViewResolutions = new double[numOverviews][2];
      for (int pyramidLevel = 1; pyramidLevel <= numOverviews; pyramidLevel++) {
        GridEnvelope levelGridRange = rasterInfo.getGridRange(0, pyramidLevel);
        GeneralEnvelope levelEnvelope = rasterInfo.getGridEnvelope(0, pyramidLevel);

        Rectangle2D levelGridRangeRect =
            new Rectangle2D.Double(
                levelGridRange.getLow(0),
                levelGridRange.getLow(1),
                levelGridRange.getSpan(0),
                levelGridRange.getSpan(1));
        overViewResolutions[pyramidLevel - 1] =
            super.getResolution(levelEnvelope, levelGridRangeRect, crs);
      }
    } else {
      overViewResolutions = null;
    }
  }