// $Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/model/coverage/grid/AbstractGridCoverage.java,v 1.11 2006/12/03 21:19:53 poth Exp $ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53115 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.model.coverage.grid; import java.awt.image.BufferedImage; import java.awt.image.renderable.ParameterBlock; import javax.media.jai.InterpolationNearest; import javax.media.jai.JAI; import javax.media.jai.RenderedOp; import org.deegree.graphics.transformation.GeoTransform; import org.deegree.graphics.transformation.WorldToScreenTransform; import org.deegree.model.coverage.AbstractCoverage; import org.deegree.model.crs.CoordinateSystem; import org.deegree.model.spatialschema.Envelope; import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering; import org.opengis.coverage.Coverage; import org.opengis.coverage.grid.GridCoverage; import org.opengis.coverage.grid.GridGeometry; import org.opengis.coverage.grid.GridPacking; /** * Represent the basic implementation which provides access to grid coverage data. * A <code>GC_GridCoverage</code> implementation may provide the ability to update * grid values. * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @version 2.11.2002 */ public abstract class AbstractGridCoverage extends AbstractCoverage implements GridCoverage { private GridGeometry gridGeometry = null; private GridPacking gridPacking = null; private GridGeometry[] overviewGridGeometry = null; private GridCoverage[] overviews = null; private boolean isEditable = false; /** * @param coverageOffering * @param envelope */ public AbstractGridCoverage( CoverageOffering coverageOffering, Envelope envelope ) { super( coverageOffering, envelope ); } /** * @param coverageOffering * @param sources * @param envelope */ public AbstractGridCoverage( CoverageOffering coverageOffering, Envelope envelope, Coverage[] sources ) { super( coverageOffering, envelope, sources ); } /** * * @param coverageOffering * @param envelope * @param isEditable */ public AbstractGridCoverage( CoverageOffering coverageOffering, Envelope envelope, boolean isEditable ) { super( coverageOffering, envelope ); this.isEditable = isEditable; } /** * * @param coverageOffering * @param envelope * @param isEditable */ public AbstractGridCoverage( CoverageOffering coverageOffering, Envelope envelope, CoordinateSystem crs, boolean isEditable ) { super( coverageOffering, envelope, null, crs ); this.isEditable = isEditable; } /** * * @param coverageOffering * @param envelope * @param sources * @param isEditable */ public AbstractGridCoverage( CoverageOffering coverageOffering, Envelope envelope, Coverage[] sources, boolean isEditable ) { super( coverageOffering, envelope, sources ); this.isEditable = isEditable; } /** * * @param coverageOffering * @param envelope * @param sources * @param crs * @param isEditable */ public AbstractGridCoverage( CoverageOffering coverageOffering, Envelope envelope, Coverage[] sources, CoordinateSystem crs, boolean isEditable ) { super( coverageOffering, envelope, sources, crs ); this.isEditable = isEditable; } /** * Returns <code>true</code> if grid data can be edited. * * @return <code>true</code> if grid data can be edited. */ public boolean isDataEditable() { return isEditable; } /** Return the grid geometry for an overview. * * @param overviewIndex Overview index for which to retrieve grid geometry. Indices start at 0. * @return the grid geometry for an overview. * */ public GridGeometry getOverviewGridGeometry( int overviewIndex ) throws IndexOutOfBoundsException { return overviewGridGeometry[overviewIndex]; } /** Returns a pre-calculated overview for a grid coverage. * The overview indices are numbered from 0 to <code>numberOverviews-1</code>. * The overviews are ordered from highest (index 0) * to lowest (numberOverviews -1) resolution. * Overview grid coverages will have overviews which are the overviews for * the grid coverage with lower resolution than the overview. * For example, a 1 meter grid coverage with 3, 9, and 27 meter overviews * will be ordered as follows: * * <table border=0 align="center"> * <tr> <td align="center">Index</td> <td align="center">resolution</td> </tr> * <tr> <td align="center"> 0 </td> <td align="center"> 3 </td> </tr> * <tr> <td align="center"> 1 </td> <td align="center"> 9 </td> </tr> * <tr> <td align="center"> 2 </td> <td align="center"> 27 </td> </tr> * </table><br><br> * * The 3 meter overview will have 2 overviews as follows: * <table border=0 align="center"> * <tr> <td align="center">Index</td> <td align="center">resolution</td> </tr> * <tr> <td align="center"> 0 </td> <td align="center"> 9 </td> </tr> * <tr> <td align="center"> 1 </td> <td align="center"> 27 </td> </tr> * </table> * * @param overviewIndex Index of grid coverage overview to retrieve. Indexes start at 0. * @return a pre-calculated overview for a grid coverage. * */ public GridCoverage getOverview( int overviewIndex ) { return overviews[overviewIndex]; } /** Number of predetermined overviews for the grid. * * @return the number of predetermined overviews for the grid. * */ public int getNumOverviews() { if ( overviews != null ) { return overviews.length; } return 0; } /** * Information for the packing of grid coverage values. * * @return the information for the packing of grid coverage values. * * @uml.property name="gridPacking" */ public GridPacking getGridPacking() { return gridPacking; } /** * Information for the grid coverage geometry. * Grid geometry includes the valid range of grid coordinates and the georeferencing. * * @return the information for the grid coverage geometry. * * @uml.property name="gridGeometry" */ public GridGeometry getGridGeometry() { return gridGeometry; } /** * this is a deegree convenience method which returns the source image * of an <tt>ImageGridCoverage</tt>. In procipal the same can be done * with the getRenderableImage(int xAxis, int yAxis) method. but creating * a <tt>RenderableImage</tt> image is very slow. * @param xAxis Dimension to use for the <var>x</var> axis. * @param yAxis Dimension to use for the <var>y</var> axis. * @return */ abstract public BufferedImage getAsImage( int xAxis, int yAxis ); /** * renders a source image onto the correct position of a target image * according to threir geographic extends (Envelopes). * @param targetImg * @param targetEnv * @param sourceImg * @param sourceEnv * @return targetImg with sourceImg rendered on */ protected BufferedImage paintImage( BufferedImage targetImg, Envelope targetEnv, BufferedImage sourceImg, Envelope sourceEnv ) { int w = targetImg.getWidth(); int h = targetImg.getHeight(); GeoTransform gt = new WorldToScreenTransform( targetEnv.getMin().getX(), targetEnv.getMin().getY(), targetEnv.getMax().getX(), targetEnv.getMax().getY(), 0, 0, w, h ); int x1 = (int) Math.round( gt.getDestX( sourceEnv.getMin().getX() ) ); int y1 = (int) Math.round( gt.getDestY( sourceEnv.getMax().getY() ) ); int x2 = (int) Math.round( gt.getDestX( sourceEnv.getMax().getX() ) ); int y2 = (int) Math.round( gt.getDestY( sourceEnv.getMin().getY() ) ); if ( Math.abs( x2 - x1 ) > 0 && Math.abs( y2 - y1 ) > 0 ) { float ww = sourceImg.getWidth(); float hh = sourceImg.getHeight(); if ( Math.abs( y2 - y1 ) / hh != 1.0 || Math.abs( x2 - x1 ) / ww != 1.0 ) { ParameterBlock pb = new ParameterBlock(); pb.addSource( sourceImg ); pb.add( Math.abs( x2 - x1 ) / ww ); // The xScale pb.add( Math.abs( y2 - y1 ) / hh ); // The yScale pb.add( 0.0F ); // The x translation pb.add( 0.0F ); // The y translation pb.add( new InterpolationNearest() ); // The interpolation // Create the scale operation RenderedOp ro = JAI.create( "scale", pb, null ); sourceImg = ro.getAsBufferedImage(); } for ( int i = 0; i < sourceImg.getWidth(); i++ ) { for ( int j = 0; j < sourceImg.getHeight(); j++ ) { if ( x1 + i < targetImg.getWidth() && y1 + j < targetImg.getHeight() ) { targetImg.setRGB( x1 + i, y1 + j, sourceImg.getRGB( i, j ) ); } } } } return targetImg; } } /* ******************************************************************** Changes to this class. What the people have been up to: $Log: AbstractGridCoverage.java,v $ Revision 1.11 2006/12/03 21:19:53 poth new constructor added Revision 1.10 2006/11/23 21:40:21 poth Bug fix - JAI does not like scaling with factor 1.0 Revision 1.9 2006/11/21 17:30:45 poth bug fix / code formatting Revision 1.8 2006/11/17 08:58:01 poth bug fixes - setting correct interpolation Revision 1.7 2006/11/16 21:02:37 poth bug fixes - rescaling images Revision 1.6 2006/04/06 20:25:26 poth *** empty log message *** Revision 1.5 2006/04/04 20:39:44 poth *** empty log message *** Revision 1.4 2006/03/30 21:20:26 poth *** empty log message *** Revision 1.3 2005/03/16 11:54:25 poth no message Revision 1.2 2005/01/18 22:08:54 poth no message Revision 1.5 2004/07/19 06:20:00 ap no message Revision 1.4 2004/07/14 15:34:37 ap no message Revision 1.3 2004/07/12 06:12:11 ap no message Revision 1.2 2004/06/28 06:39:45 ap no message Revision 1.1 2004/05/25 07:14:01 ap no message Revision 1.1 2004/05/24 06:51:31 ap no message ********************************************************************** */