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 }