this.maxDataWidth = maxDataWidth; this.maxDataHeight = maxDataHeight; RasterRect origData = new RasterRect( 0, 0, maxDataWidth, maxDataHeight ); maxViewData = RasterRect.intersection( origData, view ); if ( maxViewData == null ) { maxViewData = new RasterRect( 0, 0, 0, 0 );
/** * Create an intersection of the given RasterRects, if the given rasterects do not intersect, null will be returned. * * @param first * @param second * @return the intersection or <code>null</code> if the given rectangles do not intersect. */ public static final RasterRect intersection( RasterRect first, RasterRect second ) { int fmaxX = first.x + first.width; int smaxX = second.x + second.width; int fmaxY = first.y + first.height; int smaxY = second.y + second.height; if ( second.x >= fmaxX || smaxX <= first.x || second.y >= fmaxY || smaxY <= first.y ) { /* right outside || left outside || bottom outside || top outside */ return null; } int x = Math.max( first.x, second.x ); int y = Math.max( first.y, second.y ); int width = Math.min( smaxX, fmaxX ) - x; int height = Math.min( smaxY, fmaxY ) - y; // y values return new RasterRect( x, y, width, height ); } }
/** * Creates a RasterData object object with given size, number of bands, data type and interleaving. The view will be * 0, 0, width, height, the default raster cache location will be used. * * @param width * width of the raster * @param height * height of the raster * @param dataInfo * defining the bands, datatype and interleave type. * @param reader * to get the data from, maybe <code>null</code> * @param addToCache * if the reader should be added to the cache (almost always should be true). * @return new RasterData */ public static ByteBufferRasterData createRasterData( int width, int height, RasterDataInfo dataInfo, RasterReader reader, boolean addToCache ) { return createRasterData( new RasterRect( 0, 0, width, height ), dataInfo, reader, addToCache, null ); }
/** * Returns an Envelope for a raster with given size. * * The calculation considers the origin and resolution of the raster. * * @param targetLocation * of the origin, specifies if the the newly created envelope should consider the origin located at the * OUTER or CENTER of a pixel. * @param width * in raster coordinates * @param height * in raster coordinates * @param crs * the coordinate system for the envelope * * @return the calculated envelope */ public Envelope getEnvelope( OriginLocation targetLocation, int width, int height, ICRS crs ) { return getEnvelope( targetLocation, new RasterRect( 0, 0, width, height ), crs ); }
/** * Calculates the envelope for a tile at a given position in the grid. * * @param column * column , must be in the range [0 ... #columns - 1] * @param row * row , must be in the range [0 ... #rows - 1] * @return the tile's envelope */ protected Envelope getTileEnvelope( int column, int row ) { int xOffset = column * tileRasterWidth; int yOffset = row * tileRasterHeight; RasterRect rect = new RasterRect( xOffset, yOffset, tileRasterWidth, tileRasterHeight ); return this.geoRef.getEnvelope( rect, null ); // double xOffset = column * tileWidth; // double yOffset = ( rows - row - 1 ) * tileHeight; // // double minX = envelope.getMin().get0() + xOffset; // double minY = envelope.getMin().get1() + yOffset; // double maxX = minX + tileWidth; // double maxY = minY + tileHeight; // // return geomFac.createEnvelope( minX, minY, maxX, maxY, envelope.getCoordinateSystem() ); }
/** * Creates a RasterData object object with given size, number of bands, data type and interleaving filled with the * given ByteArray. A cachereader will be created. * * @param width * width of the raster * @param height * height of the raster * @param rdi * containing the number of bands, the data type and the interleave type. * @param geoRef * needed for the reader. * @param byteBuffer * on which the memory reader will operate upon. * @param createCacheFile * true if a cache file should back the data * @param cacheId * the name of the cache file to use in the default {@link RasterCache}. * @param options * which can be used to get the cache data from. * @return new RasterData */ public static ByteBufferRasterData createRasterData( int width, int height, RasterDataInfo rdi, RasterGeoReference geoRef, ByteBuffer byteBuffer, boolean createCacheFile, String cacheId, RasterIOOptions options ) { return createRasterData( new RasterRect( 0, 0, width, height ), rdi, geoRef, byteBuffer, createCacheFile, cacheId, options ); }
@Override public BufferResult read( RasterRect rect, ByteBuffer buffer ) throws IOException { RasterRect tmpRect = new RasterRect( rect.x + tileRectInGrid.x, rect.y + tileRectInGrid.y, rect.width, rect.height ); BufferResult bufferResult = originalReader.read( tmpRect, buffer ); bufferResult.getResult().clear(); // PixelInterleavedRasterData rd = new PixelInterleavedRasterData( bufferResult.getRect(), // bufferResult.getRect().width, // bufferResult.getRect().height, // new RasterDataInfo( BandType.RGB, // DataType.BYTE, // InterleaveType.PIXEL ) ); // rd.setByteBuffer( bufferResult.getResult() ); // BufferedImage image = RasterFactory.rasterDataToImage( rd ); // ImageIO.write( image, "png", new File( "/tmp/" + tmpRect.toString() + ".png" ) ); // bufferResult.getRect().x -= tileRectInGrid.x; // bufferResult.getRect().y -= tileRectInGrid.y; return bufferResult; }
private void copyValuesFromTile( int tileColumn, int tileRow, RasterRect dstRect, ByteBuffer srcBuffer, ByteBuffer dstBuffer ) throws IOException { int tileWidth = getTileRasterWidth(); int tileHeight = getTileRasterHeight(); RasterRect tileRect = new RasterRect( tileWidth * tileColumn, tileHeight * tileRow, tileWidth, tileHeight ); Rasters.copyValuesFromTile( tileRect, dstRect, srcBuffer, dstBuffer, sampleSize ); }
/** * Returns a single band of the raster. * * @param band * Number of the selected band. * @return A copy of the selected band. */ public SimpleRaster getBand( int band ) { return new SimpleRaster( getRasterData().getSubset( new RasterRect( 0, 0, getColumns(), getRows() ), new BandType[] {} ), getEnvelope(), getRasterReference(), metadata ); }
/** * @param reader * to be used for the tiles. * @param options * */ protected TiledRasterData( GridReader reader, RasterIOOptions options ) { if ( reader == null ) { throw new NullPointerException( "Grid reader may not be null." ); } this.columns = reader.getTileColumns(); this.rows = reader.getTileRows(); this.tileWidth = reader.getTileRasterWidth(); this.tileHeight = reader.getTileRasterHeight(); tiles = new RasterData[this.columns * this.rows]; for ( int row = 0; row < rows; ++row ) { for ( int col = 0; col < columns; ++col ) { TileOffsetReader r = new TileOffsetReader( reader, new RasterRect( col * tileWidth, row * tileHeight, tileWidth, tileHeight ) ); tiles[( row * columns ) + col] = RasterDataFactory.createRasterData( new RasterRect( 0, 0, tileWidth, tileHeight ), reader.getRasterDataInfo(), r, false, options ); } } this.sampleDomain = new RasterRect( 0, 0, reader.getWidth(), reader.getHeight() ); this.dataInfo = reader.getRasterDataInfo(); }
/** * only called from constructor, no synchronization needed. * * @param filledBuffer */ private void createTilesFromFilledBuffer( ByteBuffer filledBuffer, int width, int height ) { if ( filledBuffer != null ) { // create tiling RasterRect dataRect = new RasterRect( 0, 0, width, height ); ByteBuffer origBuffer = filledBuffer.asReadOnlyBuffer(); for ( int row = 0; row < getTileRows(); ++row ) { for ( int col = 0; col < getTileColumns(); ++col ) { TileEntry entry = getEntry( col, row ); if ( entry != null ) { ByteBuffer entryBuffer = allocateTileBuffer( false, true ); try { Rasters.copyValuesFromTile( dataRect, entry.getRasterRect(), origBuffer, entryBuffer, sampleSize ); } catch ( IOException e ) { LOG.error( "Could not create tile from buffer because: " + e.getLocalizedMessage(), e ); } this.inMemorySize += entry.setBuffer( entryBuffer ); } } } // remove the old buffer from memory filledBuffer = null; origBuffer = null; } }
/** * Creates a new empty SimpleRaster with same DataType and InterleaveType. Size is determined by the given envelope. * * @param rEnv * The raster envelope of the new SimpleRaster. * @param env * The boundary of the new SimpleRaster. * @return A new empty SimpleRaster. */ public SimpleRaster createCompatibleSimpleRaster( RasterGeoReference rEnv, Envelope env ) { int[] size = rEnv.getSize( env ); RasterRect rasterRect = new RasterRect( 0, 0, size[0], size[1] ); RasterData data = this.getRasterData(); BandType[] bands = data.getDataInfo().bandInfo; RasterData newRaster = data.createCompatibleWritableRasterData( rasterRect, bands ); return new SimpleRaster( newRaster, env, rEnv, metadata ); }
/** * Creates a SimpleRaster with same size, DataType and InterleaveType * * @param bands * number of bands * @return new empty SimpleRaster */ public SimpleRaster createCompatibleSimpleRaster( BandType[] bands ) { RasterData data = this.getRasterData(); RasterData newRaster = data.createCompatibleWritableRasterData( new RasterRect( 0, 0, getColumns(), getRows() ), bands ); return new SimpleRaster( newRaster, getEnvelope(), getRasterReference(), metadata ); }
/** * Creates a new empty writable SimpleRaster with same size, DataType and InterleaveType. * * @return new empty SimpleRaster */ public SimpleRaster createCompatibleSimpleRaster() { int height = this.getRows(); int width = this.getColumns(); RasterData data = this.getRasterData(); BandType[] bands = data.getDataInfo().bandInfo; RasterData newRaster = data.createCompatibleWritableRasterData( new RasterRect( 0, 0, width, height ), bands ); return new SimpleRaster( newRaster, this.getEnvelope(), this.getRasterReference(), metadata ); }
/** * Calculates the envelope for a tile at a given position in the grid. * * @param column * column id, must be in the range [0 ... #columns - 1] * @param row * row id, must be in the range [0 ... #rows - 1] * @return the tile's envelope */ protected Envelope getTileEnvelope( int column, int row ) { int xOffset = column * infoFile.getTileRasterWidth(); int yOffset = row * infoFile.getTileRasterHeight(); RasterRect rect = new RasterRect( xOffset, yOffset, infoFile.getTileRasterWidth(), infoFile.getTileRasterHeight() ); return infoFile.getGeoReference().getEnvelope( rect, null ); // double xOffset = columnId * tileWidth; // double yOffset = ( infoFile.rows() - rowId - 1 ) * tileHeight; // // double minX = envelope.getMin().get0() + xOffset; // double minY = envelope.getMin().get1() + yOffset; // double maxX = minX + tileWidth; // double maxY = minY + tileHeight; // // return geomFac.createEnvelope( minX, minY, maxX, maxY, envelope.getCoordinateSystem() ); }
@Override public BufferResult read( RasterRect rect, ByteBuffer resultBuffer ) throws IOException { BufferResult res = null; RasterRect fRect = snapToGrid( rect ); if ( fRect != null ) { int[] minCRmaxCR = getIntersectingTiles( fRect ); if ( minCRmaxCR == null ) { return null; } int size = fRect.width * fRect.height * sampleSize; if ( resultBuffer == null ) { resultBuffer = ByteBufferPool.allocate( size, false ); } synchronized ( LOCK ) { FileChannel channel = getFileChannel(); RasterRect tmpRect = new RasterRect( 0, 0, fRect.width, fRect.height ); for ( int col = minCRmaxCR[0]; col <= minCRmaxCR[2]; ++col ) { for ( int row = minCRmaxCR[1]; row <= minCRmaxCR[3]; ++row ) { readValuesFromTile( col, row, fRect, channel, resultBuffer ); } } res = new BufferResult( tmpRect, resultBuffer ); closeReadStream(); } } return res; }
@Override public BufferResult read( RasterRect rect, ByteBuffer resultBuffer ) throws IOException { BufferResult res = null; RasterRect fRect = snapToGrid( rect ); if ( fRect != null ) { int[] minCRmaxCR = getIntersectingTiles( fRect ); if ( minCRmaxCR == null ) { return null; } int size = fRect.width * fRect.height * sampleSize; if ( resultBuffer == null ) { resultBuffer = ByteBufferPool.allocate( size, false ); } RasterRect tmpRect = new RasterRect( 0, 0, fRect.width, fRect.height ); for ( int col = minCRmaxCR[0]; col <= minCRmaxCR[2]; ++col ) { for ( int row = minCRmaxCR[1]; row <= minCRmaxCR[3]; ++row ) { int tileId = getTileId( col, row ); int blobNo = tileId / getTilesPerBlob(); FileChannel channel = blobChannels[blobNo]; readValuesFromTile( col, row, fRect, channel, resultBuffer ); } } res = new BufferResult( tmpRect, resultBuffer ); } return res; }
/** * Instantiate the map * * @return a new map */ private Map<Integer, TileEntry> instantiateTiles() { synchronized ( LOCK ) { Map<Integer, TileEntry> result = new ConcurrentHashMap<Integer, TileEntry>( getTileColumns() * getTileRows() * 2 ); CacheInfoFile infoFile = (CacheInfoFile) this.infoFile; boolean[][] tilesOnFile = infoFile.getTilesOnFile(); if ( tilesOnFile == null || tilesOnFile.length != getTileRows() || tilesOnFile[getTileRows() - 1].length != getTileColumns() ) { tilesOnFile = new boolean[getTileRows()][getTileColumns()]; } for ( int r = 0; r < getTileRows(); ++r ) { for ( int c = 0; c < getTileColumns(); ++c ) { RasterRect rect = new RasterRect( c * getTileRasterWidth(), r * getTileRasterHeight(), getTileRasterWidth(), getTileRasterHeight() ); int key = getTileId( c, r ); TileEntry entry = new TileEntry( rect ); entry.setTileOnFile( tilesOnFile[r][c] ); result.put( key, entry ); } } return result; } }
/** * Instantiates this grid reader with the given information. * * @param infoFile */ protected synchronized void instantiate( GridMetaInfoFile infoFile ) { this.infoFile = infoFile; this.envelope = infoFile.getEnvelope( OriginLocation.OUTER ); this.rasterRect = new RasterRect( 0, 0, infoFile.columns() * infoFile.getTileRasterWidth(), infoFile.rows() * infoFile.getTileRasterHeight() ); this.rasterDataInfo = infoFile.getDataInfo(); // this.envelopeWidth = envelope.getMax().get0() - envelope.getMin().get0(); // this.envelopeHeight = envelope.getMax().get1() - envelope.getMin().get1(); // this.envelopeWidth = envelope.getSpan0(); // this.envelopeHeight = envelope.getSpan1(); // this.rows = infoFile.rows(); // this.columns = infoFile.columns(); // this.tileSamplesX = infoFile.getTileSamplesX(); // this.tileSamplesY = infoFile.getTileSamplesY(); // this.tileWidth = envelope.getSpan0() / infoFile.columns(); // this.tileHeight = envelope.getSpan1() / infoFile.rows(); this.tilesPerBlob = infoFile.columns() * infoFile.rows(); this.sampleSize = ( rasterDataInfo.getDataType().getSize() * rasterDataInfo.bands() ); this.bytesPerTile = infoFile.getTileRasterWidth() * infoFile.getTileRasterHeight() * sampleSize; }
/** * Interpolates the given raster to retrieve a raster with the given width and height. * * @param sourceRaster * the raster to get an interpolation version from * @param dstWidth * the width (columns) of the resulting raster * @param dstHeight * the height (rows) of the resulting raster * @return the interpolated raster */ public AbstractRaster interPolate( AbstractRaster sourceRaster, int dstWidth, int dstHeight ) { SimpleRaster simpleSourceRaster = sourceRaster.getAsSimpleRaster(); RasterData srcData = simpleSourceRaster.getReadOnlyRasterData(); RasterGeoReference srcREnv = simpleSourceRaster.getRasterReference(); // interpolation is needed. Interpolation interpolation = InterpolationFactory.getInterpolation( interpolationType, srcData ); RasterRect rr = new RasterRect( 0, 0, dstWidth, dstHeight ); RasterData dstData = srcData.createCompatibleWritableRasterData( rr, null ); RasterGeoReference dstREnv = RasterGeoReference.create( sourceRaster.getRasterReference().getOriginLocation(), sourceRaster.getEnvelope(), dstWidth, dstHeight ); // use warp to calculate the correct sample positions in the source raster. // the warp is a cubic polynomial function created of 100 points in the dstEnvelope. This function will map // points from the source crs to the target crs very accurate. WarpPolynomial warp = createWarp( dstWidth, dstHeight, srcREnv, dstREnv ); warpTransform( warp, interpolation, dstData ); return new SimpleRaster( dstData, sourceRaster.getEnvelope(), dstREnv, (ResourceMetadata) sourceRaster.getMetadata() ); }