|
|
|
svn_geotools
|
Author: danieleromagnoli
Date: 2009-11-13 10:58:51 -0500 (Fri, 13 Nov 2009) New Revision: 34375 Modified: trunk/modules/unsupported/jp2kakadu/pom.xml trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/ReadType.java trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java Log: Aligning Kakadu module to 2.6.x Modified: trunk/modules/unsupported/jp2kakadu/pom.xml =================================================================== --- trunk/modules/unsupported/jp2kakadu/pom.xml 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/pom.xml 2009-11-13 15:58:51 UTC (rev 34375) @@ -90,12 +90,12 @@ <dependency> <groupId>it.geosolutions.imageio-ext</groupId> <artifactId>imageio-ext-kakadu</artifactId> - <version>${imageio.ext.version}</version> + <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>it.geosolutions.imageio-ext</groupId> <artifactId>imageio-ext-utilities</artifactId> - <version>${imageio.ext.version}</version> + <version>1.0-SNAPSHOT</version> </dependency> <!-- Test dependencies --> Modified: trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java =================================================================== --- trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java 2009-11-13 15:58:51 UTC (rev 34375) @@ -1,6 +1,8 @@ package org.geotools.coverageio.jp2kak; +import it.geosolutions.imageio.utilities.Utilities; + import java.awt.Dimension; import java.awt.Rectangle; import java.awt.RenderingHints; @@ -16,6 +18,7 @@ import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; import javax.imageio.stream.ImageInputStream; import javax.media.jai.ImageLayout; import javax.media.jai.Interpolation; @@ -325,6 +328,8 @@ final Map<Integer,Level> granuleLevels= Collections.synchronizedMap(new HashMap<Integer,Level>()); AffineTransform baseGridToWorld; + + ImageReaderSpi cachedSPI; public Granule(BoundingBox granuleBBOX, File granuleFile) { super(); @@ -332,8 +337,8 @@ this.granuleFile = granuleFile; // create the base grid to world transformation - ImageInputStream inStream=null; - ImageReader reader=null; + ImageInputStream inStream = null; + ImageReader reader = null; try { // //get info about the raster we have to read @@ -341,15 +346,19 @@ // get a stream inStream = Utils.getInputStream(granuleFile); - if(inStream==null) - throw new IllegalArgumentException("Unable to get an input stream for the provided file "+granuleFile.toString()); - - // get a reader - reader = Utils.getReader(inStream); - if(reader==null) - { - throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleFile.toString()); + if(inStream == null) + throw new IllegalArgumentException("Unable to get an input stream for the provided file "+granuleFile.getAbsolutePath()); + + // get a reader and try to cache the relevant SPI + if(cachedSPI == null){ + reader = Utils.getReader( inStream); + if(reader != null) + cachedSPI = reader.getOriginatingProvider(); } + else + reader = cachedSPI.createReaderInstance(); + if(reader == null) + throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleFile.getAbsolutePath()); //get selected level and base level dimensions final Rectangle originalDimension = Utils.getDimension(0,inStream, reader); @@ -359,15 +368,12 @@ // 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 - ); + 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(); + this.baseGridToWorld = geMapper.createAffineTransform(); - // add the base level - this.granuleLevels.put(Integer.valueOf(0),new Level(1,1,originalDimension.width,originalDimension.height)); + this.granuleLevels.put(Integer.valueOf(0), new Level(1, 1, originalDimension.width, originalDimension.height)); } catch (IllegalStateException e) { throw new IllegalArgumentException(e); @@ -377,14 +383,14 @@ } finally{ try{ - if(inStream!=null) + if(inStream != null) inStream.close(); } catch (Throwable e) { throw new IllegalArgumentException(e); } finally{ - if(reader!=null) + if(reader != null) reader.dispose(); } } @@ -395,7 +401,7 @@ final ImageReadParam readParameters, final int imageIndex, final ReferencedEnvelope cropBBox, - final MathTransform2D mosaicWorldToGrid, + final MathTransform2D worldToGrid, final RasterLayerRequest request, final Dimension tileDimension) throws IOException { @@ -418,8 +424,14 @@ if(inStream==null) return null; - // get a reader - reader = Utils.getReader(inStream); + // get a reader and try to cache the relevant SPI + if(cachedSPI==null){ + reader = Utils.getReader( inStream); + if(reader!=null) + cachedSPI=reader.getOriginatingProvider(); + } + else + reader=cachedSPI.createReaderInstance(); if(reader==null) { if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) @@ -446,23 +458,29 @@ XRectangle2D.intersect(sourceArea, selectedlevel.rasterDimensions, sourceArea);//make sure roundings don't bother us // is it empty?? if (sourceArea.isEmpty()) { - if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) - LOGGER.warning("Got empty area for granule "+this.toString()+ " with request "+request.toString()); + if (LOGGER.isLoggable(java.util.logging.Level.FINE)) + LOGGER.fine("Got empty area for granule "+this.toString()+ " with request "+request.toString()); return null; } else if (LOGGER.isLoggable(java.util.logging.Level.FINE)) LOGGER.fine((new StringBuffer("Loading level ").append( imageIndex).append(" with source region ").append( sourceArea).toString())); + final int ssx = readParameters.getSourceXSubsampling(); + final int ssy = readParameters.getSourceYSubsampling(); + final int newSubSamplingFactor = Utilities.getSubSamplingFactor2(ssx,ssy); + if (newSubSamplingFactor != 0){ + readParameters.setSourceSubsampling(newSubSamplingFactor, newSubSamplingFactor,0,0); + } + // set the source region readParameters.setSourceRegion(sourceArea); - - // read - final RenderedImage raster = request.getReadType().read(readParameters,imageIndex, granuleFile, selectedlevel.rasterDimensions,tileDimension); - if (raster == null) - return null; + final RenderedImage raster; try{ - raster.getWidth(); + // read + raster= request.getReadType().read(readParameters,imageIndex, granuleFile, selectedlevel.rasterDimensions,tileDimension,cachedSPI); + if (raster == null) + return null; } catch (Throwable e) { if(LOGGER.isLoggable(java.util.logging.Level.FINE)) @@ -484,51 +502,47 @@ // image sizes. // // place it in the mosaic using the coords created above; - double decimationScaleX = ((1.0 * sourceArea.width) / raster.getWidth()); - double decimationScaleY = ((1.0 * sourceArea.height) / raster.getHeight()); + double decimationScaleX = ((1.0 * sourceArea.width) / raster.getWidth()); + double decimationScaleY = ((1.0 * sourceArea.height) / raster.getHeight()); final AffineTransform decimationScaleTranform = XAffineTransform.getScaleInstance(decimationScaleX, decimationScaleY); // keep into account translation to work into the selected level raster space - final AffineTransform afterDecimationTranslateTranform =XAffineTransform.getTranslateInstance(sourceArea.x, sourceArea.y); - + final AffineTransform afterDecimationTranslateTranform = XAffineTransform.getTranslateInstance(sourceArea.x, sourceArea.y); // now we need to go back to the base level raster space - final AffineTransform backToBaseLevelScaleTransform =selectedlevel.baseToLevelTransform; + final AffineTransform backToBaseLevelScaleTransform = selectedlevel.baseToLevelTransform; - // now create the overall transform - final AffineTransform tempRaster2Model = new AffineTransform(baseGridToWorld); - tempRaster2Model.concatenate(Utils.CENTER_TO_CORNER); + final AffineTransform finalRaster2Model = new AffineTransform(baseGridToWorld); + finalRaster2Model.concatenate(Utils.CENTER_TO_CORNER); if(!XAffineTransform.isIdentity(backToBaseLevelScaleTransform,10E-6)) - tempRaster2Model.concatenate(backToBaseLevelScaleTransform); + finalRaster2Model.concatenate(backToBaseLevelScaleTransform); if(!XAffineTransform.isIdentity(afterDecimationTranslateTranform,10E-6)) - tempRaster2Model.concatenate(afterDecimationTranslateTranform); + finalRaster2Model.concatenate(afterDecimationTranslateTranform); if(!XAffineTransform.isIdentity(decimationScaleTranform,10E-6)) - tempRaster2Model.concatenate(decimationScaleTranform); + finalRaster2Model.concatenate(decimationScaleTranform); // keep into account translation factors to place this tile - final AffineTransform translationTransform = new AffineTransform((AffineTransform) mosaicWorldToGrid); - translationTransform.concatenate(tempRaster2Model); + finalRaster2Model.preConcatenate((AffineTransform) worldToGrid); final InterpolationNearest nearest = new InterpolationNearest(); //paranoiac check to avoid that JAI freaks out when computing its internal layouT on images that are too small Rectangle2D finalLayout= layoutHelper( raster, - (float)translationTransform.getScaleX(), - (float)translationTransform.getScaleY(), - (float)translationTransform.getTranslateX(), - (float)translationTransform.getTranslateY(), + (float)finalRaster2Model.getScaleX(), + (float)finalRaster2Model.getScaleY(), + (float)finalRaster2Model.getTranslateX(), + (float)finalRaster2Model.getTranslateY(), nearest); - if(finalLayout.isEmpty()) - { + if(finalLayout.isEmpty()){ if(LOGGER.isLoggable(java.util.logging.Level.FINE)) - LOGGER.fine("Unable to create a granule "+this.toString()+ " due to jai scale bug"); + LOGGER.fine("Unable to create a granule " + this.toString()+ " due to jai scale bug"); return null; } // apply the affine transform conserving indexed color model final RenderingHints localHints = new RenderingHints(JAI.KEY_REPLACE_INDEX_COLOR_MODEL, Boolean.FALSE); - if(XAffineTransform.isIdentity(translationTransform,10E-6)) + if(XAffineTransform.isIdentity(finalRaster2Model,10E-6)) return raster; else { @@ -547,7 +561,7 @@ } // border extender // return WarpDescriptor.create(raster, new WarpAffine(translationTransform.createInverse()),new InterpolationNearest(), request.getBackgroundValues(),localHints); - return AffineDescriptor.create(raster, translationTransform, nearest, /*request.getBackgroundValues()*/ null,localHints); + return AffineDescriptor.create(raster, finalRaster2Model, nearest, /*request.getBackgroundValues()*/ null,localHints); } } catch (IllegalStateException e) { @@ -574,10 +588,8 @@ reader.dispose(); } } - } - public Level getLevel(final int index) { synchronized (granuleLevels) { if(granuleLevels.containsKey(Integer.valueOf(index))) @@ -598,12 +610,16 @@ if(inStream==null) throw new IllegalArgumentException(); - // get a reader - reader = Utils.getReader( inStream); + // get a reader and try to cache the relevant SPI + if(cachedSPI==null){ + reader = Utils.getReader( inStream); + if(reader!=null) + cachedSPI=reader.getOriginatingProvider(); + } + else + reader=cachedSPI.createReaderInstance(); if(reader==null) - { - throw new IllegalArgumentException(); - } + throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleFile.getAbsolutePath()); //get selected level and base level dimensions final Rectangle levelDimension = Utils.getDimension(index,inStream, reader); @@ -644,7 +660,6 @@ } } - @Override public String toString() { // build a decent representation for this level Modified: trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java =================================================================== --- trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java 2009-11-13 15:58:51 UTC (rev 34375) @@ -26,6 +26,7 @@ import javax.imageio.spi.ImageReaderSpi; +import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; import org.geotools.coverage.grid.io.AbstractGridFormat; import org.geotools.coverage.grid.io.imageio.GeoToolsWriteParams; import org.geotools.data.DataSourceException; @@ -150,7 +151,7 @@ /** * @see org.geotools.data.coverage.grid.AbstractGridFormat#getReader(Object, Hints) */ - public GridCoverageReader getReader(Object source, Hints hints) { + public AbstractGridCoverage2DReader getReader(Object source, Hints hints) { try { return new JP2KReader(source, hints); } catch (MismatchedDimensionException e) { @@ -171,7 +172,7 @@ /** * @see org.geotools.data.coverage.grid.AbstractGridFormat#getReader(Object) */ - public GridCoverageReader getReader( Object source ) { + public AbstractGridCoverage2DReader getReader( Object source ) { return getReader(source, null); } Modified: trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java =================================================================== --- trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java 2009-11-13 15:58:51 UTC (rev 34375) @@ -32,6 +32,7 @@ import java.net.URL; import java.net.URLDecoder; import java.util.Collection; +import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,9 +42,9 @@ import javax.imageio.metadata.IIOMetadataNode; import org.geotools.coverage.CoverageFactoryFinder; -import org.geotools.coverage.grid.GeneralGridRange; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverageFactory; +import org.geotools.coverage.grid.GridEnvelope2D; import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader; import org.geotools.coverage.grid.io.AbstractGridFormat; import org.geotools.coverage.grid.io.imageio.geotiff.GeoTiffIIOMetadataDecoder; @@ -60,6 +61,7 @@ import org.opengis.coverage.grid.Format; import org.opengis.coverage.grid.GridCoverage; import org.opengis.coverage.grid.GridCoverageReader; +import org.opengis.coverage.grid.GridRange; import org.opengis.geometry.Envelope; import org.opengis.parameter.GeneralParameterValue; import org.opengis.referencing.FactoryException; @@ -89,11 +91,22 @@ /** The system-dependent default name-separator character. */ private final static char SEPARATOR = File.separatorChar; - private final static short[] geoJp2UUID = new short[] { 0xb1, 0x4b, 0xf8, - 0xbd, 0x08, 0x3d, 0x4b, 0x43, 0xa5, 0xae, 0x8c, 0xd7, 0xd5, 0xa6, - 0xce, 0x03 }; + private final static short[] GEOJP2_UUID = new short[] { 0xb1, 0x4b, 0xf8, 0xbd, 0x08, + 0x3d, 0x4b, 0x43, 0xa5, 0xae, 0x8c, 0xd7, 0xd5, 0xa6, 0xce, 0x03 }; + + private final static short[] MSIG_WORLDFILEBOX_UUID = new short[] { 0x96, 0xa9, 0xf1, 0xf1, + 0xdc, 0x98, 0x40, 0x2d, 0xa7, 0xae, 0xd6, 0x8e, 0x34, 0x45, 0x18, 0x09 }; + private final static int WORLD_FILE_INTERPRETATION_PIXEL_CORNER = 1; + /** + * The base {@link GridRange} for the {@link GridCoverage2D} of this reader. + */ + private GridEnvelope2D nativeGridRange = null; + + private GeneralEnvelope nativeEnvelope = null; + + /** * Creates a new instance of a {@link JP2KReader}. I assume nothing about * file extension. * @@ -122,43 +135,87 @@ final IIOMetadata metadata = reader.getStreamMetadata(); int hrWidth = reader.getWidth(0); int hrHeight = reader.getHeight(0); - final Rectangle actualDim = new Rectangle(0, 0, hrWidth, - hrHeight); - this.originalGridRange = new GeneralGridRange(actualDim); + final Rectangle actualDim = new Rectangle(0, 0, hrWidth, hrHeight); + this.nativeGridRange = new GridEnvelope2D(actualDim); if (this.crs == null) { parsePRJFile(); } - if (this.originalEnvelope == null) + if (this.nativeEnvelope == null) parseWorldFile(); - if (this.crs == null || this.originalEnvelope == null) - checkGeoJP2CRS(metadata); + if (this.crs == null || this.nativeEnvelope == null) + checkUUIDBoxes(metadata); // // // // If no sufficient information have been found to set the // envelope, try other ways, such as looking for a WorldFile // // // - if (this.originalEnvelope == null) { + if (this.nativeEnvelope == null) { throw new DataSourceException( "Unavailable envelope for this coverage"); } // setting the coordinate reference system for the envelope + originalEnvelope = getCoverageEnvelope(); originalEnvelope.setCoordinateReferenceSystem(crs); + originalGridRange = getCoverageGridRange(); // Additional settings due to "final" methods getOriginalXXX } - private boolean isGeoJP2(byte[] id) { - for (int i = 0; i < geoJp2UUID.length; i++) { - if ((id[i] & 0xFF) != geoJp2UUID[i]) + /** + * @param nativeEnvelope + * the nativeEnvelope to set + */ + protected void setCoverageEnvelope(GeneralEnvelope coverageEnvelope) { + this.nativeEnvelope = coverageEnvelope; + } + + /** + * @return the nativeEnvelope + */ + protected GeneralEnvelope getCoverageEnvelope() { + return nativeEnvelope; + } + + /** + * @param nativeGridRange + * the nativeGridRange to set + */ + protected void setCoverageGridRange(GridEnvelope2D coverageGridRange) { + this.nativeGridRange = coverageGridRange; + } + + /** + * @return the nativeGridRange + */ + protected GridEnvelope2D getCoverageGridRange() { + return nativeGridRange; + } + + private boolean isGeoJP2(final byte[] id) { + return isSameUUID(id, GEOJP2_UUID); + } + + private boolean isWorldBox(final byte[] id) { + return isSameUUID(id, MSIG_WORLDFILEBOX_UUID); + } + + private boolean isSameUUID(final byte[] id, final short[] uuid) { + for (int i = 0; i < uuid.length; i++) { + if ((id[i] & 0xFF) != uuid[i]) return false; } return true; } - private void checkGeoJP2CRS(final IIOMetadata metadata) throws IOException{ + /** + * Look for UUID boxes containing GeoJP2 Boxes / MSIG World Box + * @param metadata + * @throws IOException + */ + private void checkUUIDBoxes(final IIOMetadata metadata) throws IOException{ if (!(metadata instanceof JP2KStreamMetadata)) { if (LOGGER.isLoggable(Level.WARNING)) LOGGER.warning("Unexpected error! Metadata should be an instance of the expected class:" @@ -169,75 +226,185 @@ // Looking for the UUIDBoxMetadataNode // // // - CoordinateReferenceSystem coordinateReferenceSystem = null; - IIOMetadataNode uuidBoxMetadataNode = ((JP2KStreamMetadata) metadata) - .searchFirstOccurrenceNode(UUIDBox.BOX_TYPE); - if (uuidBoxMetadataNode != null - && uuidBoxMetadataNode instanceof UUIDBoxMetadataNode) { - UUIDBoxMetadataNode uuid = (UUIDBoxMetadataNode) uuidBoxMetadataNode; - final byte[] id = uuid.getUuid(); - final boolean isGeoJP2 = isGeoJP2(id); - - if (isGeoJP2) { - final ByteArrayInputStream inputStream = new ByteArrayInputStream( - uuid.getData()); - final TIFFImageReader tiffreader = (TIFFImageReader) new TIFFImageReaderSpi() - .createReaderInstance(); - tiffreader - .setInput(ImageIO.createImageInputStream(inputStream)); - final IIOMetadata tiffmetadata = tiffreader.getImageMetadata(0); - final GeoTiffIIOMetadataDecoder metadataDecoder = new GeoTiffIIOMetadataDecoder( - tiffmetadata); - final GeoTiffMetadata2CRSAdapter adapter = new GeoTiffMetadata2CRSAdapter( - null); - try { - coordinateReferenceSystem = adapter - .createCoordinateSystem(metadataDecoder); - if (coordinateReferenceSystem != null) { - if (this.crs == null) - this.crs = coordinateReferenceSystem; + final List<IIOMetadataNode> uuidBoxMetadataNodes = ((JP2KStreamMetadata) metadata) + .searchOccurrencesNode(UUIDBox.BOX_TYPE); + UUIDBoxMetadataNode geoJP2uuid = null; + UUIDBoxMetadataNode worldBoxuuid = null; + if (uuidBoxMetadataNodes != null && !uuidBoxMetadataNodes.isEmpty()){ + for (IIOMetadataNode node: uuidBoxMetadataNodes){ + if (node instanceof UUIDBoxMetadataNode) { + final UUIDBoxMetadataNode uuid = (UUIDBoxMetadataNode) node; + final byte[] id = uuid.getUuid(); + if (isGeoJP2(id)) { + geoJP2uuid = uuid; + continue; } - if (this.raster2Model == null){ - this.raster2Model = adapter - .getRasterToModel(metadataDecoder); - final AffineTransform tempTransform = new AffineTransform( - (AffineTransform) raster2Model); - tempTransform.translate(-0.5, -0.5); - GeneralEnvelope envelope = CRS.transform( - ProjectiveTransform.create(tempTransform), - new GeneralEnvelope(originalGridRange.toRectangle())); - envelope - .setCoordinateReferenceSystem(crs); - this.originalEnvelope = envelope; + + if (isWorldBox(id)){ + worldBoxuuid = uuid; } - - } catch (FactoryException e) { - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.log(Level.FINE, - "Unable to parse CRS from underlying TIFF", e); - coordinateReferenceSystem = null; - } catch (TransformException e) { - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.log(Level.FINE, - "Unable to parse CRS from underlying TIFF", e); - coordinateReferenceSystem = null; - } catch (UnsupportedOperationException e) { - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.log(Level.FINE, - "Unable to parse CRS from underlying TIFF due to an unsupported CRS", e); - coordinateReferenceSystem = null; - } finally { - if (inputStream != null) - try { - inputStream.close(); - } catch (IOException ioe) { - // Eat exception. - } } - } + } } + + if (geoJP2uuid!=null) + getGeoJP2(geoJP2uuid); + + // // + // + // Without a proper crs, the World Box is useless + // + // // + if (worldBoxuuid!=null && crs != null){ + getWorldBox(worldBoxuuid); + } + } + + private void getWorldBox(final UUIDBoxMetadataNode uuid) throws IOException { + + // // + // + // Parsing Header + // + // // + final byte[] bb = uuid.getData(); + if (bb[0]!='M'||bb[1]!='S'||bb[2]!='I'||bb[3]!='G') + return; + + // Version number: useless + // bb[4] bb[5] + + final int worldFileInterpretation = bb[6]; + final int chunkNumber = bb[14]; + + // // + // + // Parsing Chunk + // + // // + final int ckIndex = 16; + final int chunkIndex = bb[ckIndex]; + final long chunkLength = Utils.bytes2long(bb, ckIndex+2); + + if (chunkIndex!=0 && chunkLength!=48) + return; + + // // + // Parsing the Grid to World transformation + // // + final double xScale = Utils.bytes2double(bb,ckIndex+6); + final double xRotation = Utils.bytes2double(bb,ckIndex+14); + final double yRotation = Utils.bytes2double(bb,ckIndex+22); + final double yScale = Utils.bytes2double(bb,ckIndex+30); + final double xUpperLeft = Utils.bytes2double(bb,ckIndex+38); + final double yUpperLeft = Utils.bytes2double(bb,ckIndex+46); + + final boolean footerOk = (bb[ckIndex + 54] == (byte)0xFF) && (bb[ckIndex + 55] == (byte)0x00); + // // + // Setting up the grid to world transformation + // // + final AffineTransform tempTransform = new AffineTransform( + xScale, yRotation, xRotation, + yScale, xUpperLeft, yUpperLeft); + this.raster2Model = ProjectiveTransform.create(tempTransform); + + // //////////////////////////////////////////////////////////////////// + // + // Quoting from 3.2.2.1 at: + // http://www.lizardtech.com/support/kb/docs/geotiff_box.txt + // + // "This was instituted with version 1.03.11 (May 15, 2003) to signify that we + // clarified the definition of the georeferencing data and found out that that + // data represents the upper left corner of the upper left pixel, not the + // center as we had thought, so the [world chunk values are] not equal to the + // geotiff data, but is shifted by 0.5*scale to the center of the pixel." + // + // Finally note that: + // If the world chunk is present, these values should override + // the corresponding values in the GeoTIFF box. + // + // //////////////////////////////////////////////////////////////////// + if (worldFileInterpretation == WORLD_FILE_INTERPRETATION_PIXEL_CORNER) + tempTransform.translate(-0.5, -0.5); + + try { + final GeneralEnvelope envelope = CRS.transform(ProjectiveTransform.create(tempTransform), + new GeneralEnvelope(nativeGridRange)); + envelope.setCoordinateReferenceSystem(crs); + this.nativeEnvelope = envelope; + } catch (TransformException e) { + if (LOGGER.isLoggable(Level.FINE)) + LOGGER.log(Level.FINE,"Unable to parse CRS from underlying TIFF", e); + } catch (UnsupportedOperationException e) { + if (LOGGER.isLoggable(Level.FINE)) + LOGGER.log(Level.FINE,"Unable to parse CRS from underlying TIFF due to an unsupported CRS", e); + } + + } + + /** + * Get the degenerate GeoTIFF to obtain the related CoordinateReferenceSystem tags + * @param uuid + * @throws IOException + */ + private void getGeoJP2(final UUIDBoxMetadataNode uuid) throws IOException { + + CoordinateReferenceSystem coordinateReferenceSystem = null; + final ByteArrayInputStream inputStream = new ByteArrayInputStream(uuid.getData()); + final TIFFImageReader tiffreader = (TIFFImageReader) new TIFFImageReaderSpi().createReaderInstance(); + tiffreader.setInput(ImageIO.createImageInputStream(inputStream)); + final IIOMetadata tiffmetadata = tiffreader.getImageMetadata(0); + try { + final GeoTiffIIOMetadataDecoder metadataDecoder = new GeoTiffIIOMetadataDecoder(tiffmetadata); + final GeoTiffMetadata2CRSAdapter adapter = new GeoTiffMetadata2CRSAdapter(null); + coordinateReferenceSystem = adapter.createCoordinateSystem(metadataDecoder); + if (coordinateReferenceSystem != null) { + if (this.crs == null) + this.crs = coordinateReferenceSystem; + } + if (this.raster2Model == null){ + this.raster2Model = adapter.getRasterToModel(metadataDecoder); + final AffineTransform tempTransform = new AffineTransform((AffineTransform) raster2Model); + tempTransform.translate(-0.5, -0.5); + GeneralEnvelope envelope = CRS.transform(ProjectiveTransform.create(tempTransform), + new GeneralEnvelope(nativeGridRange)); + envelope.setCoordinateReferenceSystem(crs); + this.nativeEnvelope = envelope; + } + + } catch (FactoryException e) { + if (LOGGER.isLoggable(Level.FINE)) + LOGGER.log(Level.FINE, + "Unable to parse CRS from underlying TIFF", e); + coordinateReferenceSystem = null; + } catch (TransformException e) { + if (LOGGER.isLoggable(Level.FINE)) + LOGGER.log(Level.FINE, + "Unable to parse CRS from underlying TIFF", e); + coordinateReferenceSystem = null; + } catch (UnsupportedOperationException e) { + if (LOGGER.isLoggable(Level.FINE)) + LOGGER.log(Level.FINE, + "Unable to parse CRS from underlying TIFF", e); + coordinateReferenceSystem = null; + } catch (IllegalArgumentException e) { + if (LOGGER.isLoggable(Level.FINE)) + LOGGER.log(Level.FINE, + "Unable to parse CRS from underlying TIFF", e); + coordinateReferenceSystem = null; + } finally { + if (inputStream != null) + try { + inputStream.close(); + } catch (IOException ioe) { + // Eat exception. + } + } + + } + /** * Number of coverages for this reader is 1 * @@ -360,7 +527,7 @@ /** * @see org.opengis.coverage.grid.GridCoverageReader#read(org.opengis.parameter.GeneralParameterValue[]) */ - public GridCoverage read(GeneralParameterValue[] params) throws IOException { + public GridCoverage2D read(GeneralParameterValue[] params) throws IOException { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Reading image from " + sourceURL.toString()); @@ -370,7 +537,7 @@ final Collection<GridCoverage2D> response = rasterManager.read(params); if(response.isEmpty()) - throw new DataSourceException("Unable to create a coverage for this request "); + return null; else return response.iterator().next(); } @@ -518,13 +685,12 @@ // // // - MathTransform tempTransform =PixelTranslation.translate(raster2Model, PixelInCell.CELL_CENTER, PixelInCell.CELL_CORNER); + MathTransform tempTransform = PixelTranslation.translate(raster2Model, PixelInCell.CELL_CENTER, PixelInCell.CELL_CORNER); try { - final Envelope gridRange = new GeneralEnvelope( - originalGridRange.toRectangle()); + final Envelope gridRange = new GeneralEnvelope(nativeGridRange); final GeneralEnvelope coverageEnvelope = CRS.transform( tempTransform, gridRange); - originalEnvelope = coverageEnvelope; + nativeEnvelope = coverageEnvelope; } catch (TransformException e) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e); @@ -557,8 +723,8 @@ final Rectangle originalDim = new Rectangle(0, 0, reader.getWidth(0), reader.getHeight(0)); - if (originalGridRange == null) { - originalGridRange = new GeneralGridRange(originalDim); + if (nativeGridRange == null) { + nativeGridRange = new GridEnvelope2D(originalDim); } // /// @@ -573,17 +739,7 @@ highestRes[0]).append(",").append(highestRes[1]) .toString()); numOverviews = 0; -// final double[][] resolutions = configuration.getLevels(); overViewResolutions = numOverviews >= 1 ? new double[numOverviews][2]: null; -// highestRes = new double[2]; -// highestRes[0] = resolutions[0][0]; -// highestRes[1] =resolutions[0][1]; -// if(numOverviews>0){ -// for (int i = 0; i < numOverviews; i++) { -// overViewResolutions[i][0] = resolutions[i+1][0]; -// overViewResolutions[i][1] = resolutions[i+1][1]; -// } -// } } Modified: trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java =================================================================== --- trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java 2009-11-13 15:58:51 UTC (rev 34375) @@ -42,6 +42,8 @@ import org.geotools.referencing.operation.matrix.XAffineTransform; import org.geotools.referencing.operation.transform.ProjectiveTransform; import org.geotools.resources.geometry.XRectangle2D; +import org.geotools.resources.i18n.ErrorKeys; +import org.geotools.resources.i18n.Errors; import org.opengis.geometry.BoundingBox; import org.opengis.geometry.Envelope; import org.opengis.geometry.MismatchedDimensionException; @@ -859,35 +861,41 @@ // the effect is a degradation of quality, but we take that into account emprically // requestedResolution=null; +// +// // compute the raster that correspond to the crop bbox at the highest resolution +// final Rectangle sourceRasterArea = new GeneralGridEnvelope( +// CRS.transform( +// PixelTranslation.translate(rasterManager.getRaster2Model(),PixelInCell.CELL_CENTER,PixelInCell.CELL_CORNER).inverse(), +// cropBBox),PixelInCell.CELL_CORNER,false).toRectangle(); +// XRectangle2D.intersect(sourceRasterArea, rasterManager.spatialDomainManager.coverageRasterArea, sourceRasterArea); +// if(sourceRasterArea.isEmpty()) +// throw new DataSourceException("The request source raster area is empty"); - // compute the raster that correspond to the crop bbox at the highest resolution - final Rectangle sourceRasterArea = new GeneralGridEnvelope( - CRS.transform( - PixelTranslation.translate(rasterManager.getRaster2Model(),PixelInCell.CELL_CENTER,PixelInCell.CELL_CORNER).inverse(), - cropBBox),PixelInCell.CELL_CORNER,false).toRectangle(); - XRectangle2D.intersect(sourceRasterArea, rasterManager.spatialDomainManager.coverageRasterArea, sourceRasterArea); - if(sourceRasterArea.isEmpty()) - throw new DataSourceException("aaa"); - // transform the crop bbox to the request model space - final GeneralEnvelope envelope=CRS.transform(destinationToSourceTransform.inverse(), cropBBox); - final GridToEnvelopeMapper geMapper= new GridToEnvelopeMapper(new GridEnvelope2D(sourceRasterArea),envelope); + final GeneralEnvelope requestedEnvelopeInSourceCRS=CRS.transform(destinationToSourceTransform.inverse(), cropBBox); + final GridToEnvelopeMapper geMapper= new GridToEnvelopeMapper(new GridEnvelope2D(requestedRasterArea),requestedEnvelopeInSourceCRS); final AffineTransform tempTransform = geMapper.createAffineTransform(); - final double scaleX=XAffineTransform.getScaleX0((AffineTransform) requestedGridToWorld)/XAffineTransform.getScaleX0(tempTransform); - final double scaleY=XAffineTransform.getScaleY0((AffineTransform) requestedGridToWorld)/XAffineTransform.getScaleY0(tempTransform); - // - // empiric adjustment to get a finer resolution to have better quality when reprojecting - // TODO make it parametric - // - requestedRasterScaleFactors= new double[2]; - requestedRasterScaleFactors[0]=scaleX*1.0; - requestedRasterScaleFactors[1]=scaleY*1.0; +// final double scaleX=XAffineTransform.getScaleX0((AffineTransform) requestedGridToWorld)/XAffineTransform.getScaleX0(tempTransform); +// final double scaleY=XAffineTransform.getScaleY0((AffineTransform) requestedGridToWorld)/XAffineTransform.getScaleY0(tempTransform); +// // +// // empiric adjustment to get a finer resolution to have better quality when reprojecting +// // TODO make it parametric +// // +// requestedRasterScaleFactors= new double[2]; +// requestedRasterScaleFactors[0]=scaleX*1.0; +// requestedRasterScaleFactors[1]=scaleY*1.0; - - // adjust the final grid to world - final GridToEnvelopeMapper geMapper1= new GridToEnvelopeMapper(new GridEnvelope2D(destinationRasterArea),cropBBox); - requestedGridToWorld= geMapper1.createAffineTransform(); + requestedResolution= new double[] + { + XAffineTransform.getScaleX0(tempTransform), + XAffineTransform.getScaleY0(tempTransform) + }; +// +// +// // adjust the final grid to world +// final GridToEnvelopeMapper geMapper1= new GridToEnvelopeMapper(new GridEnvelope2D(destinationRasterArea),cropBBox); +// requestedGridToWorld= geMapper1.createAffineTransform(); } @@ -898,34 +906,17 @@ // the crs of the request and the one of the coverage are the // same, we can get the resolution from the grid to world // -// if(requestedGridToWorld instanceof AffineTransform){ - requestedResolution= new double[] - { - XAffineTransform.getScaleX0(requestedGridToWorld), - XAffineTransform.getScaleY0(requestedGridToWorld) - }; -// } -// else{ -// // get the matrix -// final Matrix matrix= ((LinearTransform)requestedGridToWorld).getMatrix(); -// final XAffineTransform transform=new XAffineTransform( -// matrix.getElement(0, 0), -// matrix.getElement(1, 0), -// matrix.getElement(0, 1), -// matrix.getElement(1, 1), -// matrix.getElement(0, 2), -// matrix.getElement(1, 2)); -// requestedResolution= new double[] -// { -// XAffineTransform.getScaleX0(transform), -// XAffineTransform.getScaleY0(transform) -// }; -// } -// + requestedResolution= new double[] + { + XAffineTransform.getScaleX0(requestedGridToWorld), + XAffineTransform.getScaleY0(requestedGridToWorld) + }; } } + else + // should not happen + throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1,requestedGridToWorld.toString())); - //leave return; }catch (Throwable e) { @@ -1132,10 +1123,10 @@ public Dimension getTileDimensions() { return tileDimensions; } - - public double[] getRequestedRasterScaleFactors() { - return requestedRasterScaleFactors!=null?requestedRasterScaleFactors.clone():requestedRasterScaleFactors; - } +// +// public double[] getRequestedRasterScaleFactors() { +// return requestedRasterScaleFactors!=null?requestedRasterScaleFactors.clone():requestedRasterScaleFactors; +// } @Override public String toString() { Modified: trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java =================================================================== --- trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java 2009-11-13 15:58:51 UTC (rev 34375) @@ -19,6 +19,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Rectangle; +import java.awt.geom.AffineTransform; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.awt.image.MultiPixelPackedSampleModel; @@ -61,6 +62,7 @@ import org.opengis.coverage.grid.GridCoverage; import org.opengis.geometry.BoundingBox; import org.opengis.referencing.datum.PixelInCell; +import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransform2D; import org.opengis.referencing.operation.TransformException; @@ -193,10 +195,7 @@ // //create a granule loader final GranuleLoader loader = new GranuleLoader(baseReadParameters, imageChoice, bbox, finalWorldToGridCorner,granule,request.getTileDimensions()); -// if(!multithreadingAllowed) - tasks.add(new FutureTask<RenderedImage>(loader)); -// else -// tasks.add(JP2KReader.multiThreadedLoader.submit(loader)); + tasks.add(new FutureTask<RenderedImage>(loader)); granulesNumber++; } @@ -352,6 +351,8 @@ private String location; + private MathTransform baseGridToWorld; + /** * Construct a {@code RasterLayerResponse} given a specific * {@link RasterLayerRequest}, a {@code GridCoverageFactory} to produce @@ -386,6 +387,7 @@ coverageEnvelope = rasterManager.getCoverageEnvelope(); this.coverageFactory = rasterManager.getCoverageFactory(); this.rasterManager = rasterManager; + baseGridToWorld=rasterManager.getRaster2Model(); transparentColor=request.getInputTransparentColor(); useMultithreading = request.isUseMultithreading(); @@ -474,6 +476,7 @@ // level dimension and envelope. The grid to world transforms for // the other levels can be computed accordingly knowning the scale // factors. + if (request.getRequestedBBox() != null&& request.getRequestedRasterArea() != null) imageChoice = setReadParams(request.getOverviewPolicy(), baseReadParameters,request); else @@ -492,28 +495,36 @@ else bbox = new ReferencedEnvelope(coverageEnvelope); + //compute final world to grid + // base grid to world for the center of pixels + final AffineTransform g2w = new AffineTransform((AffineTransform) baseGridToWorld); + // move it to the corner + g2w.concatenate(Utils.CENTER_TO_CORNER); - //compute final world to grid - OverviewLevel level = rasterManager.overviewsController.resolutionsLevels.get(imageChoice); - finalGridToWorldCorner = new AffineTransform2D( - level.resolutionX*baseReadParameters.getSourceXSubsampling(), + //keep into account overviews and subsampling + final OverviewLevel level = rasterManager.overviewsController.resolutionsLevels.get(imageChoice); + final OverviewLevel baseLevel = rasterManager.overviewsController.resolutionsLevels.get(0); + final AffineTransform2D adjustments = new AffineTransform2D( + (level.resolutionX/baseLevel.resolutionX)*baseReadParameters.getSourceXSubsampling(), 0, 0, - -level.resolutionY*baseReadParameters.getSourceYSubsampling(), - bbox.getLowerCorner().getOrdinate(0), - bbox.getUpperCorner().getOrdinate(1)); + (level.resolutionY/baseLevel.resolutionY)*baseReadParameters.getSourceYSubsampling(), + 0, + 0); + g2w.concatenate(adjustments); + finalGridToWorldCorner = new AffineTransform2D(g2w); finalWorldToGridCorner = finalGridToWorldCorner.inverse();// compute raster bounds rasterBounds=new GeneralGridEnvelope(CRS.transform(finalWorldToGridCorner, bbox),PixelInCell.CELL_CORNER,false).toRectangle(); - // create the index visitor and visit the feature + // create Init the granuleWorker final GranuleWorker worker = new GranuleWorker(); - worker.init(bbox); + worker.init(new ReferencedEnvelope(coverageEnvelope)); worker.produce(); // // Did we actually load anything?? Notice that it might happen that - // either we have wholes inside the definition area for the mosaic + // either we have holes inside the definition area for the mosaic // or we had some problem with missing tiles, therefore it might // happen that for some bboxes we don't have anything to load. // Modified: trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java =================================================================== --- trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java 2009-11-13 15:58:51 UTC (rev 34375) @@ -6,13 +6,14 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageReadParam; -import org.geotools.coverage.grid.GeneralGridEnvelope; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverageFactory; +import org.geotools.coverage.grid.GridEnvelope2D; import org.geotools.coverage.grid.io.OverviewPolicy; import org.geotools.data.DataSourceException; import org.geotools.factory.Hints; @@ -77,7 +78,6 @@ return "OverviewLevel[Choice=" + imageChoice + ",scaleFactor=" + scaleFactor + "]"; } - @Override public int hashCode() { int hash= Utilities.hash(imageChoice, 31); @@ -86,8 +86,6 @@ hash=Utilities.hash(scaleFactor, hash); return hash; } - - } class OverviewsController { @@ -101,7 +99,7 @@ // -the aspect ratio for the overviews is constant // -the provided resolutions are taken directly from the grid resolutionsLevels.add(new OverviewLevel(1, highestRes[0],highestRes[1], 0)); - if (numberOfOvervies > 0) { + if (numberOfOverviews > 0) { for (int i = 0; i < overviewsResolution.length; i++) resolutionsLevels.add( new OverviewLevel( @@ -147,13 +145,14 @@ requestedScaleFactorY = reqy / max.resolutionY; } else - { - final double[] scaleFactors = request.getRequestedRasterScaleFactors(); - if(scaleFactors==null) - return 0; - requestedScaleFactorX=scaleFactors[0]; - requestedScaleFactorY=scaleFactors[1]; - } + return 0; +// { +// final double[] scaleFactors = request.getRequestedRasterScaleFactors(); +// if(scaleFactors==null) +// return 0; +// requestedScaleFactorX=scaleFactors[0]; +// requestedScaleFactorY=scaleFactors[1]; +// } final int leastReduceAxis = requestedScaleFactorX <= requestedScaleFactorY ? 0: 1; final double requestedScaleFactor = leastReduceAxis == 0 ? requestedScaleFactorX: requestedScaleFactorY; @@ -221,70 +220,64 @@ * @param requestedRes */ void performDecimation( - final int imageIndex, - final ImageReadParam readParameters, - final RasterLayerRequest request) { + final int imageIndex, + final ImageReadParam readParameters, + final RasterLayerRequest request) { + + // the read parameters cannot be null + Utils.ensureNonNull("readParameters", readParameters); + Utils.ensureNonNull("request", request); + + //get the requested resolution + final double[] requestedRes=request.getRequestedResolution(); + if(requestedRes==null) { - - // the read parameters cannot be null - Utils.ensureNonNull("readParameters", readParameters); - Utils.ensureNonNull("request", request); - - //get the requested resolution - final double[] requestedRes=request.getRequestedResolution(); - if(requestedRes==null) - { - // if there is no requested resolution we don't do any subsampling - readParameters.setSourceSubsampling(1, 1, 0, 0); - return; - } - final int rasterWidth, rasterHeight; - double selectedRes[] = new double[2]; - if (imageIndex == 0) { - // highest resolution - rasterWidth = spatialDomainManager.coverageRasterArea.width; - rasterHeight = spatialDomainManager.coverageRasterArea.height; - selectedRes[0] = spatialDomainManager.coverageFullResolution[0]; - selectedRes[1] = spatialDomainManager.coverageFullResolution[1]; - } else { - // work on overviews - final OverviewLevel level=overviewsController.resolutionsLevels.get(imageIndex - 1); - selectedRes[0] = level.resolutionX; - selectedRes[1] = level.resolutionY; - //TODO this is bad side effect of how the Overviews are managed right now. There are two problems here, - // first we are assuming that we are working with LON/LAT, second is that we are getting just an approximation of - // raster dimensions. The solution is to have the rater dimensions on each level and to confront raster dimensions, - //which means working - rasterWidth = (int) Math.round(spatialDomainManager.coverageBBox.getSpan(0)/ selectedRes[0]); - rasterHeight = (int) Math.round(spatialDomainManager.coverageBBox.getSpan(1)/ selectedRes[1]); - - } - // ///////////////////////////////////////////////////////////////////// - // DECIMATION ON READING - // Setting subsampling factors with some checks - // 1) the subsampling factors cannot be zero - // 2) the subsampling factors cannot be such that the w or h are - // zero - // ///////////////////////////////////////////////////////////////////// - int subSamplingFactorX = (int) Math.floor(requestedRes[0]/ selectedRes[0]); - subSamplingFactorX = subSamplingFactorX == 0 ? 1: subSamplingFactorX; + // if there is no requested resolution we don't do any subsampling + readParameters.setSourceSubsampling(1, 1, 0, 0); + return; + } + + double selectedRes[] = new double[2]; + final OverviewLevel level=overviewsController.resolutionsLevels.get(imageIndex); + selectedRes[0] = level.resolutionX; + selectedRes[1] = level.resolutionY; + + final int rasterWidth, rasterHeight; + if (imageIndex == 0) { + // highest resolution + rasterWidth = spatialDomainManager.coverageRasterArea.width; + rasterHeight = spatialDomainManager.coverageRasterArea.height; + } else { + // work on overviews + //TODO this is bad side effect of how the Overviews are managed right now. There are two problems here, + // first we are assuming that we are working with LON/LAT, second is that we are getting just an approximation of + // raster dimensions. The solution is to have the rater dimensions on each level and to confront raster dimensions, + //which means working + rasterWidth = (int) Math.round(spatialDomainManager.coverageBBox.getSpan(0)/ selectedRes[0]); + rasterHeight = (int) Math.round(spatialDomainManager.coverageBBox.getSpan(1)/ selectedRes[1]); - while (rasterWidth / subSamplingFactorX <= 0 && subSamplingFactorX >= 0) - subSamplingFactorX--; - subSamplingFactorX = subSamplingFactorX <= 0 ? 1: subSamplingFactorX; - - int subSamplingFactorY = (int) Math.floor(requestedRes[1]/ selectedRes[1]); - subSamplingFactorY = subSamplingFactorY == 0 ? 1: subSamplingFactorY; - - while (rasterHeight / subSamplingFactorY <= 0 && subSamplingFactorY >= 0)subSamplingFactorY--; - subSamplingFactorY = subSamplingFactorY <= 0 ? 1: subSamplingFactorY; - - readParameters.setSourceSubsampling(subSamplingFactorX,subSamplingFactorY, 0, 0); - - } + // ///////////////////////////////////////////////////////////////////// + // DECIMATION ON READING + // Setting subsampling factors with some checks + // 1) the subsampling factors cannot be zero + // 2) the subsampling factors cannot be such that the w or h are zero + // ///////////////////////////////////////////////////////////////////// + int subSamplingFactorX = (int) Math.floor(requestedRes[0]/ selectedRes[0]); + subSamplingFactorX = subSamplingFactorX == 0 ? 1: subSamplingFactorX; + + while (rasterWidth / subSamplingFactorX <= 0 && subSamplingFactorX >= 0) + subSamplingFactorX--; + subSamplingFactorX = subSamplingFactorX <= 0 ? 1: subSamplingFactorX; + + int subSamplingFactorY = (int) Math.floor(requestedRes[1]/ selectedRes[1]); + subSamplingFactorY = subSamplingFactorY == 0 ? 1: subSamplingFactorY; + + while (rasterHeight / subSamplingFactorY <= 0 && subSamplingFactorY >= 0)subSamplingFactorY--; + subSamplingFactorY = subSamplingFactorY <= 0 ? 1: subSamplingFactorY; + + readParameters.setSourceSubsampling(subSamplingFactorX, subSamplingFactorY, 0, 0); } - } /** @@ -360,7 +353,7 @@ */ private void setBaseParameters() { this.coverageEnvelope = RasterManager.this.getCoverageEnvelope().clone(); - this.coverageRasterArea =(( GeneralGridEnvelope)RasterManager.this.getCoverageGridrange()).toRectangle(); + this.coverageRasterArea =((GridEnvelope2D)RasterManager.this.getCoverageGridrange()); this.coverageCRS = RasterManager.this.getCoverageCRS(); this.coverageGridToWorld2D = (MathTransform2D) RasterManager.this.getRaster2Model(); this.coverageFullResolution = new double[2]; @@ -390,7 +383,7 @@ /** The hints to be used to produce this coverage */ private Hints hints; private URL inputURL; - private int numberOfOvervies; + private int numberOfOverviews; private double[][] overviewsResolution; // //////////////////////////////////////////////////////////////////////// // @@ -425,7 +418,7 @@ //resolution values highestRes= reader.getHighestRes(); - numberOfOvervies=reader.getNumberOfOvervies(); + numberOfOverviews=reader.getNumberOfOvervies(); overviewsResolution=reader.getOverviewsResolution(); //instantiating controller for subsampling and overviews @@ -453,22 +446,16 @@ * {@link Hints#VALUE_OVERVIEW_POLICY_SPEED}, {@link Hints#VALUE_OVERVIEW_POLICY_QUALITY}. * Default is {@link Hints#VALUE_OVERVIEW_POLICY_NEAREST}. */ - @SuppressWarnings("deprecation") private OverviewPolicy extractOverviewPolicy() { - // check if a policy was provided using hints (check even the - // deprecated one) if (this.hints != null) if (this.hints.containsKey(Hints.OVERVIEW_POLICY)) overviewPolicy = (OverviewPolicy) this.hints.get(Hints.OVERVIEW_POLICY); - else if (this.hints.containsKey(Hints.IGNORE_COVERAGE_OVERVIEW)) - overviewPolicy = ((Boolean) this.hints - .get(Hints.IGNORE_COVERAGE_OVERVIEW)).booleanValue() ? OverviewPolicy.IGNORE - : OverviewPolicy.QUALITY; // use default if not provided. Default is nearest if (overviewPolicy == null) - overviewPolicy = OverviewPolicy.NEAREST; + overviewPolicy = OverviewPolicy.getDefaultPolicy(); + assert overviewPolicy != null; return overviewPolicy; } @@ -480,7 +467,9 @@ // create a request final RasterLayerRequest request= new RasterLayerRequest(params,this); if(request.isEmpty()){ - throw new DataSourceException("The provided request resulted in no area to load"); + if(LOGGER.isLoggable(Level.FINE)) + LOGGER.log(Level.FINE,"Request is empty: "+request.toString()); + return Collections.emptyList(); } // create a response for the provided request Modified: trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/ReadType.java =================================================================== --- trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/ReadType.java 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/ReadType.java 2009-11-13 15:58:51 UTC (rev 34375) @@ -15,6 +15,7 @@ import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; +import javax.imageio.spi.ImageReaderSpi; import javax.imageio.stream.ImageInputStream; import javax.media.jai.ImageLayout; import javax.media.jai.JAI; @@ -38,7 +39,8 @@ final int imageIndex, final File rasterFile, final Rectangle readDimension, - final Dimension tileDimension // we just ignore in this case + final Dimension tileDimension, // we just ignore in this case + final ImageReaderSpi spi )throws IOException{ // // Using ImageReader to load the data directly @@ -50,7 +52,7 @@ if(inStream==null) return null; - reader=Utils.getReader( inStream); + reader=spi.createReaderInstance(); if(reader==null) { if (LOGGER.isLoggable(Level.WARNING)) @@ -103,7 +105,8 @@ final int imageIndex, final File rasterFile, final Rectangle readDimension, - final Dimension tileDimension + final Dimension tileDimension, + final ImageReaderSpi spi ) throws IOException{ /// @@ -117,7 +120,7 @@ if(inStream==null) return null; // get a reader - reader = Utils.getReader(inStream); + reader=spi.createReaderInstance(); if(reader==null) { if (LOGGER.isLoggable(Level.WARNING)) @@ -169,7 +172,7 @@ pbjImageRead.add(null); pbjImageRead.add(null); pbjImageRead.add(readP); - pbjImageRead.add(null); + pbjImageRead.add(spi.createReaderInstance()); final RenderedOp raster; if(tileDimension!=null){ //build a proper layout @@ -193,7 +196,8 @@ final int imageIndex, final File rasterFile, final Rectangle readDimension, - final Dimension tileDimension + final Dimension tileDimension, + final ImageReaderSpi spi ) throws IOException{ /// @@ -207,7 +211,7 @@ if(inStream==null) return null; // get a reader - reader = Utils.getReader(inStream); + reader=spi.createReaderInstance(); if(reader==null) { if (LOGGER.isLoggable(Level.WARNING)) @@ -259,7 +263,7 @@ pbjImageRead.add(null); pbjImageRead.add(null); pbjImageRead.add(readP); - pbjImageRead.add(null); + pbjImageRead.add(spi.createReaderInstance()); final RenderedOp raster; if(tileDimension!=null){ //build a proper layout @@ -284,7 +288,8 @@ final int imageIndex, final File rasterFile, final Rectangle readDimension, - final Dimension tileDimension + final Dimension tileDimension, + final ImageReaderSpi spi )throws IOException{ throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1,"read")); } @@ -329,7 +334,8 @@ final int imageIndex, final File rasterFile, final Rectangle readDimension, - final Dimension tileDimension + final Dimension tileDimension, + final ImageReaderSpi spi ) throws IOException; }; Modified: trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java =================================================================== --- trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java 2009-11-13 15:12:21 UTC (rev 34374) +++ trunk/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java 2009-11-13 15:58:51 UTC (rev 34375) @@ -413,4 +413,40 @@ return false; return true; } + + public static double bytes2double (final byte[] bytes, final int start) { + int i = 0; + final int length = 8; + int count = 0; + final byte[] tmp = new byte[length]; + for (i = start; i < (start + length); i++) { + tmp[count] = bytes[i]; + count++; + } + long accum = 0; + i = 0; + for ( int shiftBy = 0; shiftBy < 64; shiftBy += 8 ) { + accum |= ( (long)( tmp[i] & 0xff ) ) << shiftBy; + i++; + } + return Double.longBitsToDouble(accum); + } + + public static long bytes2long (final byte[] bytes, final int start) { + int i = 0; + final int length = 4; + int count = 0; + final byte[] tmp = new byte[length]; + for (i = start; i < (start + length); i++) { + tmp[count] = bytes[i]; + count++; + } + long accum = 0; + i = 0; + for ( int shiftBy = 0; shiftBy < 32; shiftBy += 8 ) { + accum |= ( (long)( tmp[i] & 0xff ) ) << shiftBy; + i++; + } + return accum; + } } ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ GeoTools-commits mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/geotools-commits |
||||||||||||||||
| Free Embeddable Forum Powered by Nabble | Help |