|
|
|
svn_geotools
|
Author: danieleromagnoli
Date: 2009-11-04 11:32:24 -0500 (Wed, 04 Nov 2009) New Revision: 34326 Modified: branches/2.6.x/modules/unsupported/jp2kakadu/pom.xml branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java Log: Porting improvements from mosaic's plugin computations Modified: branches/2.6.x/modules/unsupported/jp2kakadu/pom.xml =================================================================== --- branches/2.6.x/modules/unsupported/jp2kakadu/pom.xml 2009-11-04 13:35:29 UTC (rev 34325) +++ branches/2.6.x/modules/unsupported/jp2kakadu/pom.xml 2009-11-04 16:32:24 UTC (rev 34326) @@ -90,7 +90,7 @@ <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> Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java =================================================================== --- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java 2009-11-04 13:35:29 UTC (rev 34325) +++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java 2009-11-04 16:32:24 UTC (rev 34326) @@ -16,6 +16,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 +326,8 @@ final Map<Integer,Level> granuleLevels= Collections.synchronizedMap(new HashMap<Integer,Level>()); AffineTransform baseGridToWorld; + + ImageReaderSpi cachedSPI; public Granule(BoundingBox granuleBBOX, File granuleFile) { super(); @@ -342,14 +345,18 @@ // 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); + 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.toString()); - } + 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); @@ -395,7 +402,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 +425,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,8 +459,8 @@ 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)) @@ -497,27 +510,26 @@ // 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()) { @@ -528,7 +540,7 @@ // 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 +559,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) { @@ -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); Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java =================================================================== --- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java 2009-11-04 13:35:29 UTC (rev 34325) +++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java 2009-11-04 16:32:24 UTC (rev 34326) @@ -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: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java =================================================================== --- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java 2009-11-04 13:35:29 UTC (rev 34325) +++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java 2009-11-04 16:32:24 UTC (rev 34326) @@ -23,6 +23,7 @@ import java.awt.Rectangle; import java.awt.geom.AffineTransform; +import java.awt.image.DataBufferByte; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; @@ -32,6 +33,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 +43,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 +62,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 +92,20 @@ /** 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[] geoJp2UUID = new short[] { 0xb1, 0x4b, 0xf8, 0xbd, 0x08, + 0x3d, 0x4b, 0x43, 0xa5, 0xae, 0x8c, 0xd7, 0xd5, 0xa6, 0xce, 0x03 }; + + private final static short[] msigWorldFileBoxUUID = new short[] { 0x96, 0xa9, 0xf1, 0xf1, + 0xdc, 0x98, 0x40, 0x2d, 0xa7, 0xae, 0xd6, 0x8e, 0x34, 0x45, 0x18, 0x09 }; /** + * 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. * @@ -124,41 +136,81 @@ int hrHeight = reader.getHeight(0); final Rectangle actualDim = new Rectangle(0, 0, hrWidth, hrHeight); - this.originalGridRange = new GeneralGridRange(actualDim); + 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, geoJp2UUID); + } + + private boolean isWorldBox(final byte[] id) { + return isSameUUID(id, msigWorldFileBoxUUID); + } + + 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{ + 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 +221,152 @@ // 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); + 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)) { + getGeoJP2(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; - } - - } 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. - } + + // // + // + // Without a proper crs, the World Box is useless + // + // // + if (crs != null) + if (isWorldBox(id)){ + getWorldBox(uuid); + } } - } + } } } + + 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; + 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); + + final AffineTransform tempTransform = new AffineTransform( + xScale, yRotation, xRotation, + yScale, xUpperLeft, yUpperLeft); + this.raster2Model = ProjectiveTransform.create(tempTransform); + tempTransform.translate(-0.5, -0.5); + + try { + 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); + } + + } + 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); + 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; + } + 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 due to an unsupported CRS", 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 +489,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()); @@ -518,13 +647,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 +685,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 +701,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: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java =================================================================== --- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java 2009-11-04 13:35:29 UTC (rev 34325) +++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java 2009-11-04 16:32:24 UTC (rev 34326) @@ -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: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java =================================================================== --- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java 2009-11-04 13:35:29 UTC (rev 34325) +++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java 2009-11-04 16:32:24 UTC (rev 34326) @@ -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; @@ -352,6 +354,8 @@ private String location; + private MathTransform baseGridToWorld; + /** * Construct a {@code RasterLayerResponse} given a specific * {@link RasterLayerRequest}, a {@code GridCoverageFactory} to produce @@ -386,6 +390,7 @@ coverageEnvelope = rasterManager.getCoverageEnvelope(); this.coverageFactory = rasterManager.getCoverageFactory(); this.rasterManager = rasterManager; + baseGridToWorld=rasterManager.getRaster2Model(); transparentColor=request.getInputTransparentColor(); useMultithreading = request.isUseMultithreading(); @@ -494,21 +499,30 @@ //compute final world to grid - OverviewLevel level = rasterManager.overviewsController.resolutionsLevels.get(imageChoice); - finalGridToWorldCorner = new AffineTransform2D( - level.resolutionX*baseReadParameters.getSourceXSubsampling(), + // 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); + + //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 final GranuleWorker worker = new GranuleWorker(); - worker.init(bbox); + worker.init(new ReferencedEnvelope(coverageEnvelope)); worker.produce(); // Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java =================================================================== --- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java 2009-11-04 13:35:29 UTC (rev 34325) +++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java 2009-11-04 16:32:24 UTC (rev 34326) @@ -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; @@ -101,7 +102,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 +148,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; @@ -238,19 +240,19 @@ readParameters.setSourceSubsampling(1, 1, 0, 0); return; } - final int rasterWidth, rasterHeight; + 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; - 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, @@ -360,7 +362,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 +392,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 +427,7 @@ //resolution values highestRes= reader.getHighestRes(); - numberOfOvervies=reader.getNumberOfOvervies(); + numberOfOverviews=reader.getNumberOfOvervies(); overviewsResolution=reader.getOverviewsResolution(); //instantiating controller for subsampling and overviews @@ -456,19 +458,14 @@ @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 +477,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: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java =================================================================== --- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java 2009-11-04 13:35:29 UTC (rev 34325) +++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java 2009-11-04 16:32:24 UTC (rev 34326) @@ -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 |