001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/model/coverage/grid/FloatGridCoverage.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.model.coverage.grid;
037
038 import java.awt.Graphics;
039 import java.awt.Rectangle;
040 import java.awt.image.BufferedImage;
041 import java.awt.image.DataBuffer;
042 import java.awt.image.Raster;
043 import java.awt.image.renderable.RenderableImage;
044
045 import org.deegree.model.spatialschema.Envelope;
046 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering;
047
048 /**
049 *
050 *
051 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
052 * @author last edited by: $Author: mschneider $
053 *
054 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $
055 */
056 public class FloatGridCoverage extends AbstractGridCoverage {
057
058 private static final long serialVersionUID = -3642652899429594623L;
059
060 private float[][][] data = null;
061
062 /**
063 * @param coverageOffering
064 * @param envelope
065 * @param data
066 */
067 public FloatGridCoverage( CoverageOffering coverageOffering, Envelope envelope, float[][][] data ) {
068 this( coverageOffering, envelope, false, data );
069 }
070
071 /**
072 * @param coverageOffering
073 * @param envelope
074 * @param isEditable
075 * @param data
076 */
077 public FloatGridCoverage( CoverageOffering coverageOffering, Envelope envelope, boolean isEditable, float[][][] data ) {
078 super( coverageOffering, envelope, isEditable );
079 this.data = data;
080 }
081
082 /**
083 * @param coverageOffering
084 * @param envelope
085 * @param sources
086 */
087 public FloatGridCoverage( CoverageOffering coverageOffering, Envelope envelope, FloatGridCoverage[] sources ) {
088 super( coverageOffering, envelope, sources );
089 }
090
091 /**
092 * The number of sample dimensions in the coverage. For grid coverages, a sample dimension is a band.
093 *
094 * @return The number of sample dimensions in the coverage.
095 * @UML mandatory numSampleDimensions
096 */
097 public int getNumSampleDimensions() {
098 if ( data != null ) {
099 return data.length;
100 }
101 return sources[0].getNumSampleDimensions();
102 }
103
104 /**
105 * Returns 2D view of this coverage as a renderable image. This optional operation allows interoperability with <A
106 * HREF="http://java.sun.com/products/java-media/2D/">Java2D</A>. If this coverage is a
107 * {@link "org.opengis.coverage.grid.GridCoverage"} backed by a {@link java.awt.image.RenderedImage}, the underlying
108 * image can be obtained with:
109 *
110 * <code>getRenderableImage(0,1).{@linkplain RenderableImage#createDefaultRendering()
111 * createDefaultRendering()}</code>
112 *
113 * @param xAxis
114 * Dimension to use for the <var>x</var> axis.
115 * @param yAxis
116 * Dimension to use for the <var>y</var> axis.
117 * @return A 2D view of this coverage as a renderable image.
118 * @throws UnsupportedOperationException
119 * if this optional operation is not supported.
120 * @throws IndexOutOfBoundsException
121 * if <code>xAxis</code> or <code>yAxis</code> is out of bounds.
122 */
123 @Override
124 public RenderableImage getRenderableImage( int xAxis, int yAxis )
125 throws UnsupportedOperationException, IndexOutOfBoundsException {
126 if ( data != null ) {
127
128 return null;
129 }
130 // TODO if multi images -> sources.length > 0
131 return null;
132 }
133
134 /**
135 * this is a deegree convenience method which returns the source image of an <tt>ImageGridCoverage</tt>. In procipal
136 * the same can be done with the getRenderableImage(int xAxis, int yAxis) method. but creating a
137 * <tt>RenderableImage</tt> image is very slow. I xAxis or yAxis <= 0 then the size of the returned image will be
138 * calculated from the source images of the coverage.
139 *
140 * @param xAxis
141 * Dimension to use for the <var>x</var> axis.
142 * @param yAxis
143 * Dimension to use for the <var>y</var> axis.
144 * @return the image
145 */
146 @Override
147 public BufferedImage getAsImage( int xAxis, int yAxis ) {
148
149 if ( xAxis <= 0 || yAxis <= 0 ) {
150 // get default size if passed target size is <= 0
151 Rectangle rect = calculateOriginalSize();
152 xAxis = rect.width;
153 yAxis = rect.height;
154 }
155
156 BufferedImage bi = new BufferedImage( xAxis, yAxis, BufferedImage.TYPE_INT_ARGB );
157
158 if ( data != null ) {
159 BufferedImage img = new BufferedImage( data[0][0].length, data[0].length, BufferedImage.TYPE_INT_ARGB );
160 Raster raster = img.getData();
161 DataBuffer buf = raster.getDataBuffer();
162 for ( int i = 0; i < data[0][0].length; i++ ) {
163 for ( int j = 0; j < data[0].length; j++ ) {
164 buf.setElem( j * data[0][0].length + i, Float.floatToIntBits( data[0][j][i] ) );
165 }
166 }
167 img.setData( raster );
168 if ( img.getWidth() != bi.getWidth() || img.getHeight() != bi.getHeight() ) {
169 // just resize if source image size is different from
170 // target image size
171 Graphics g = bi.getGraphics();
172 g.drawImage( img, 0, 0, bi.getWidth(), bi.getHeight(), null );
173 g.dispose();
174 }
175 } else {
176 // it's a complex FloatGridCoverage made up of different
177 // source coverages
178 for ( int i = 0; i < sources.length; i++ ) {
179 BufferedImage sourceImg = ( (AbstractGridCoverage) sources[i] ).getAsImage( -1, -1 );
180
181 bi = paintImage( bi, this.getEnvelope(), sourceImg, sources[i].getEnvelope() );
182 }
183 }
184
185 return bi;
186 }
187
188 /**
189 * calculates the original size of a gridcoverage based on its resolution and the envelope(s) of its source(s).
190 *
191 * @return the size
192 */
193 private Rectangle calculateOriginalSize() {
194 if ( data != null ) {
195 return new Rectangle( data[0][0].length, data[0].length );
196 }
197 BufferedImage bi = ( (ImageGridCoverage) sources[0] ).getAsImage( -1, -1 );
198 Envelope env = sources[0].getEnvelope();
199 double dx = env.getWidth() / bi.getWidth();
200 double dy = env.getHeight() / bi.getHeight();
201 env = this.getEnvelope();
202 int w = (int) Math.round( env.getWidth() / dx );
203 int h = (int) Math.round( env.getHeight() / dy );
204 return new Rectangle( w, h );
205 }
206 }