001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/coverage/grid/ImageGridCoverage.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree
005 Copyright (C) 2001-2006 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library is distributed in the hope that it will be useful,
017 but WITHOUT ANY WARRANTY; without even the implied warranty of
018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstr. 19
030 53115 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: fitzke@giub.uni-bonn.de
041
042
043 ---------------------------------------------------------------------------*/
044 package org.deegree.model.coverage.grid;
045
046 import java.awt.Rectangle;
047 import java.awt.image.BufferedImage;
048 import java.awt.image.renderable.ParameterBlock;
049 import java.awt.image.renderable.RenderableImage;
050
051 import javax.media.jai.Interpolation;
052 import javax.media.jai.InterpolationNearest;
053 import javax.media.jai.JAI;
054 import javax.media.jai.RenderableGraphics;
055 import javax.media.jai.RenderedOp;
056
057 import org.deegree.model.crs.CoordinateSystem;
058 import org.deegree.model.spatialschema.Envelope;
059 import org.deegree.model.spatialschema.GeometryFactory;
060 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering;
061 import org.opengis.pt.PT_Envelope;
062
063 /**
064 * GridCoverage implementation for holding grids stored in an <tt>BufferedImage</tt> or in a set
065 * of <tt>ImageGridCoverage</tt>s
066 *
067 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
068 * @author last edited by: $Author: apoth $
069 *
070 * @version $Revision: 7842 $, $Date: 2007-07-25 09:44:14 +0200 (Mi, 25 Jul 2007) $
071 */
072 public class ImageGridCoverage extends AbstractGridCoverage {
073
074 private static final long serialVersionUID = -531939507044569726L;
075
076 private transient BufferedImage image = null;
077
078 /**
079 *
080 * @param coverageOffering
081 * @param envelope
082 * @param image
083 */
084 public ImageGridCoverage( CoverageOffering coverageOffering, Envelope envelope,
085 BufferedImage image ) {
086 this( coverageOffering, envelope, false, image );
087 }
088
089 /**
090 *
091 * @param coverageOffering
092 * @param envelope
093 * @param isEditable
094 * @param image
095 */
096 public ImageGridCoverage( CoverageOffering coverageOffering, Envelope envelope,
097 boolean isEditable, BufferedImage image ) {
098 super( coverageOffering, envelope, isEditable );
099 this.image = image;
100 }
101
102 /**
103 *
104 * @param coverageOffering
105 * @param envelope
106 * @param crs
107 * @param isEditable
108 * @param image
109 */
110 public ImageGridCoverage( CoverageOffering coverageOffering, Envelope envelope,
111 CoordinateSystem crs, boolean isEditable, BufferedImage image ) {
112 super( coverageOffering, envelope, crs, isEditable );
113 this.image = image;
114 }
115
116 /**
117 *
118 * @param coverageOffering
119 * @param envelope
120 * @param sources
121 */
122 public ImageGridCoverage( CoverageOffering coverageOffering, Envelope envelope,
123 ImageGridCoverage[] sources ) {
124 super( coverageOffering, envelope, sources );
125 }
126
127 /**
128 * The number of sample dimensions in the coverage. For grid coverages, a sample dimension is a
129 * band.
130 *
131 * @return The number of sample dimensions in the coverage.
132 */
133 public int getNumSampleDimensions() {
134 if ( image != null ) {
135 return image.getData().getNumBands();
136 }
137 return sources[0].getNumSampleDimensions();
138 }
139
140
141 /**
142 * Returns 2D view of this coverage as a renderable image. This optional operation allows
143 * interoperability with <A HREF="http://java.sun.com/products/java-media/2D/">Java2D</A>. If
144 * this coverage is a {@link "org.opengis.coverage.grid.GridCoverage"} backed by a
145 * {@link java.awt.image.RenderedImage}, the underlying image can be obtained with:
146 *
147 * <code>getRenderableImage(0,1).{@linkplain RenderableImage#createDefaultRendering()
148 * createDefaultRendering()}</code>
149 *
150 * @param xAxis
151 * Dimension to use for the <var>x</var> axis.
152 * @param yAxis
153 * Dimension to use for the <var>y</var> axis.
154 * @return A 2D view of this coverage as a renderable image.
155 * @throws UnsupportedOperationException
156 * if this optional operation is not supported.
157 * @throws IndexOutOfBoundsException
158 * if <code>xAxis</code> or <code>yAxis</code> is out of bounds.
159 */
160 public RenderableImage getRenderableImage( int xAxis, int yAxis )
161 throws UnsupportedOperationException, IndexOutOfBoundsException {
162 if ( image != null ) {
163 if ( xAxis > 0 && yAxis > 0 ) {
164 Rectangle rect = new Rectangle( xAxis, yAxis );
165 RenderableGraphics rg = new RenderableGraphics( rect );
166 rg.drawImage( image, 0, 0, xAxis, yAxis, null );
167 return rg;
168 }
169 Rectangle rect = new Rectangle( image.getWidth(), image.getHeight() );
170 RenderableGraphics rg = new RenderableGraphics( rect );
171 rg.drawImage( image, 0, 0, null );
172 return rg;
173 }
174 // TODO if multi images -> sources.length > 0
175 return null;
176 }
177
178 /**
179 * this is a deegree convenience method which returns the source image of an
180 * <tt>ImageGridCoverage</tt>. In procipal the same can be done with the
181 * getRenderableImage(int xAxis, int yAxis) method. but creating a <tt>RenderableImage</tt>
182 * image is very slow. I xAxis or yAxis <= 0 then the size of the returned image will be
183 * calculated from the source images of the coverage.
184 *
185 * @param xAxis
186 * Dimension to use for the <var>x</var> axis.
187 * @param yAxis
188 * Dimension to use for the <var>y</var> axis.
189 * @return the source image of an <tt>ImageGridCoverage</tt>.
190 */
191 public BufferedImage getAsImage( int xAxis, int yAxis ) {
192
193 if ( xAxis <= 0 || yAxis <= 0 ) {
194 // get default size if passed target size is <= 0
195 Rectangle rect = calculateOriginalSize();
196 xAxis = rect.width;
197 yAxis = rect.height;
198 }
199 BufferedImage bi = null;
200 if ( image != null ) {
201 if ( xAxis == image.getWidth() && yAxis == image.getHeight() ) {
202 bi = image;
203 } else {
204 // it's a simple ImageGridCoverage just made up of one image
205 ParameterBlock pb = new ParameterBlock();
206 pb.addSource( image );
207 pb.add( xAxis / (float) image.getWidth() ); // The xScale
208 pb.add( yAxis / (float) image.getHeight() ); // The yScale
209 pb.add( 0.0F ); // The x translation
210 pb.add( 0.0F ); // The y translation
211 Interpolation interpolation = new InterpolationNearest();
212 pb.add( interpolation ); // The interpolation
213 // Create the scale operation
214 RenderedOp ro = JAI.create( "scale", pb, null );
215 bi = ro.getAsBufferedImage();
216 }
217 } else {
218 String natFrm = coverageOffering.getSupportedFormats().getNativeFormat().getCode();
219 if ( "jpg".equalsIgnoreCase( natFrm ) || "jpeg".equalsIgnoreCase( natFrm )
220 || "bmp".equalsIgnoreCase( natFrm ) ) {
221 bi = new BufferedImage( xAxis, yAxis, BufferedImage.TYPE_INT_RGB );
222 } else {
223 bi = new BufferedImage( xAxis, yAxis, BufferedImage.TYPE_INT_ARGB );
224 }
225 // it's a complex ImageGridCoverage made up of different
226 // source coverages
227 if ( sources == null || sources.length == 0 ) {
228 return bi;
229 }
230
231 for ( int i = 0; i < sources.length; i++ ) {
232 PT_Envelope env = sources[i].getEnvelope();
233 Envelope sourceEnv = GeometryFactory.createEnvelope( env.minCP.ord[0],
234 env.minCP.ord[1],
235 env.maxCP.ord[0],
236 env.maxCP.ord[1], null );
237 env = this.getEnvelope();
238 Envelope targetEnv = GeometryFactory.createEnvelope( env.minCP.ord[0],
239 env.minCP.ord[1],
240 env.maxCP.ord[0],
241 env.maxCP.ord[1], null );
242
243 BufferedImage sourceImg = ( (ImageGridCoverage) sources[i] ).getAsImage( -1, -1 );
244 bi = paintImage( bi, targetEnv, sourceImg, sourceEnv );
245 }
246 }
247
248 return bi;
249 }
250
251 /**
252 * calculates the original size of a gridcoverage based on its resolution and the envelope(s) of
253 * its source(s).
254 *
255 * @return
256 */
257 private Rectangle calculateOriginalSize() {
258 if ( image != null ) {
259 return new Rectangle( image.getWidth(), image.getHeight() );
260 }
261 BufferedImage bi = ( (ImageGridCoverage) sources[0] ).getAsImage( -1, -1 );
262 PT_Envelope env = sources[0].getEnvelope();
263 double dx = ( env.maxCP.ord[0] - env.minCP.ord[0] ) / bi.getWidth();
264 double dy = ( env.maxCP.ord[1] - env.minCP.ord[1] ) / bi.getHeight();
265 env = this.getEnvelope();
266 int w = (int) Math.round( ( env.maxCP.ord[0] - env.minCP.ord[0] ) / dx );
267 int h = (int) Math.round( ( env.maxCP.ord[1] - env.minCP.ord[1] ) / dy );
268 return new Rectangle( w, h );
269 }
270
271 }
272 /***************************************************************************************************
273 * <code>
274 Changes to this class. What the people have been up to:
275
276 $Log$
277 Revision 1.19 2007/03/13 12:38:33 wanhoff
278 Fixed Javadoc (@link, @return)
279 Revision
280 1.18 2007/02/09 17:27:59 poth
281 *** empty log message ***
282
283 Revision 1.17 2007/01/10 15:26:41 poth
284 bug fixes handling raw data coverages
285
286 Revision 1.16 2007/01/05 10:54:43 poth
287 bug fix
288
289 Revision 1.15 2007/01/02 14:44:53 poth
290 bug fix
291
292 Revision 1.14 2006/12/14 16:59:28 poth
293 not necessary import statements removed
294
295 Revision 1.13 2006/12/13 16:08:06 poth
296 *** empty log message ***
297
298 Revision 1.12 2006/12/12 20:02:51 poth
299 use bilinear interpolation as default
300
301 Revision 1.11 2006/12/03 21:19:53 poth
302 new constructor added
303
304 Revision 1.10 2006/11/17 08:58:01 poth
305 bug fixes - setting correct interpolation
306
307 Revision 1.9 2006/11/16 21:02:37 poth
308 bug fixes - rescaling images
309
310 Revision 1.8 2006/11/15 14:19:54 poth
311 bug fix - cast scaling values to float
312
313 Revision 1.7 2006/11/14 14:08:25 poth
314 bug fix - scaling image
315
316 Revision 1.6 2006/04/06 20:25:26 poth
317 *** empty log message ***
318
319 Revision 1.5 2006/03/30 21:20:26 poth
320 *** empty log message ***
321
322 Revision 1.4 2006/03/01 19:50:38 poth
323 *** empty log message ***
324
325 Revision 1.3 2005/07/22 16:19:56 poth
326 no message
327
328 Revision 1.2 2005/03/16 11:54:25 poth
329 no message
330
331 Revision 1.15 2004/08/23 06:59:52 ap
332 no message
333
334 Revision 1.14 2004/08/09 06:43:50 ap
335 no message
336
337 Revision 1.13 2004/08/06 06:41:51 ap
338 grid coverage implementation extension
339
340 Revision 1.12 2004/07/30 06:29:29 ap
341 code optimization
342
343 Revision 1.11 2004/07/23 07:14:45 ap
344 no message
345
346 Revision 1.10 2004/07/22 15:20:41 ap
347 no message
348
349 Revision 1.9 2004/07/22 12:17:08 ap
350 no message
351
352 </code>
353 **************************************************************************************************/