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