001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/coverage/grid/FloatGridCoverage.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 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: Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: klaus.greve@uni-bonn.de
041:
042:
043: ---------------------------------------------------------------------------*/
044: package org.deegree.model.coverage.grid;
045:
046: import java.awt.Graphics;
047: import java.awt.Rectangle;
048: import java.awt.image.BufferedImage;
049: import java.awt.image.DataBuffer;
050: import java.awt.image.Raster;
051: import java.awt.image.renderable.RenderableImage;
052:
053: import org.deegree.model.spatialschema.Envelope;
054: import org.deegree.model.spatialschema.GeometryFactory;
055: import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering;
056: import org.opengis.pt.PT_Envelope;
057:
058: /**
059: *
060: *
061: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
062: * @author last edited by: $Author: apoth $
063: *
064: * @version $Revision: 9343 $, $Date: 2007-12-27 05:30:32 -0800 (Thu, 27 Dec 2007) $
065: */
066: public class FloatGridCoverage extends AbstractGridCoverage {
067:
068: private static final long serialVersionUID = -3642652899429594623L;
069:
070: private float[][][] data = null;
071:
072: /**
073: * @param coverageOffering
074: * @param envelope
075: * @param data
076: */
077: public FloatGridCoverage(CoverageOffering coverageOffering,
078: Envelope envelope, float[][][] data) {
079: this (coverageOffering, envelope, false, data);
080: }
081:
082: /**
083: * @param coverageOffering
084: * @param envelope
085: * @param isEditable
086: * @param data
087: */
088: public FloatGridCoverage(CoverageOffering coverageOffering,
089: Envelope envelope, boolean isEditable, float[][][] data) {
090: super (coverageOffering, envelope, isEditable);
091: this .data = data;
092: }
093:
094: /**
095: * @param coverageOffering
096: * @param envelope
097: * @param sources
098: */
099: public FloatGridCoverage(CoverageOffering coverageOffering,
100: Envelope envelope, FloatGridCoverage[] sources) {
101: super (coverageOffering, envelope, sources);
102: }
103:
104: /**
105: * The number of sample dimensions in the coverage. For grid coverages, a sample dimension is a
106: * band.
107: *
108: * @return The number of sample dimensions in the coverage.
109: * @UML mandatory numSampleDimensions
110: */
111: public int getNumSampleDimensions() {
112: if (data != null) {
113: return data.length;
114: }
115: return sources[0].getNumSampleDimensions();
116: }
117:
118: /**
119: * Returns 2D view of this coverage as a renderable image. This optional operation allows
120: * interoperability with <A HREF="http://java.sun.com/products/java-media/2D/">Java2D</A>. If
121: * this coverage is a {@link "org.opengis.coverage.grid.GridCoverage"} backed by a
122: * {@link java.awt.image.RenderedImage}, the underlying image can be obtained with:
123: *
124: * <code>getRenderableImage(0,1).{@linkplain RenderableImage#createDefaultRendering()
125: * createDefaultRendering()}</code>
126: *
127: * @param xAxis
128: * Dimension to use for the <var>x</var> axis.
129: * @param yAxis
130: * Dimension to use for the <var>y</var> axis.
131: * @return A 2D view of this coverage as a renderable image.
132: * @throws UnsupportedOperationException
133: * if this optional operation is not supported.
134: * @throws IndexOutOfBoundsException
135: * if <code>xAxis</code> or <code>yAxis</code> is out of bounds.
136: */
137: public RenderableImage getRenderableImage(int xAxis, int yAxis)
138: throws UnsupportedOperationException,
139: IndexOutOfBoundsException {
140: if (data != null) {
141:
142: return null;
143: }
144: // TODO if multi images -> sources.length > 0
145: return null;
146: }
147:
148: /**
149: * this is a deegree convenience method which returns the source image of an
150: * <tt>ImageGridCoverage</tt>. In procipal the same can be done with the
151: * getRenderableImage(int xAxis, int yAxis) method. but creating a <tt>RenderableImage</tt>
152: * image is very slow. I xAxis or yAxis <= 0 then the size of the returned image will be
153: * calculated from the source images of the coverage.
154: *
155: * @param xAxis
156: * Dimension to use for the <var>x</var> axis.
157: * @param yAxis
158: * Dimension to use for the <var>y</var> axis.
159: * @return
160: */
161: public BufferedImage getAsImage(int xAxis, int yAxis) {
162:
163: if (xAxis <= 0 || yAxis <= 0) {
164: // get default size if passed target size is <= 0
165: Rectangle rect = calculateOriginalSize();
166: xAxis = rect.width;
167: yAxis = rect.height;
168: }
169:
170: BufferedImage bi = new BufferedImage(xAxis, yAxis,
171: BufferedImage.TYPE_INT_ARGB);
172:
173: if (data != null) {
174: BufferedImage img = new BufferedImage(data[0][0].length,
175: data[0].length, BufferedImage.TYPE_INT_ARGB);
176: Raster raster = img.getData();
177: DataBuffer buf = raster.getDataBuffer();
178: for (int i = 0; i < data[0][0].length; i++) {
179: for (int j = 0; j < data[0].length; j++) {
180: buf.setElem(j * data[0][0].length + i, Float
181: .floatToIntBits(data[0][j][i]));
182: }
183: }
184: img.setData(raster);
185: if (img.getWidth() != bi.getWidth()
186: || img.getHeight() != bi.getHeight()) {
187: // just resize if source image size is different from
188: // target image size
189: Graphics g = bi.getGraphics();
190: g.drawImage(img, 0, 0, bi.getWidth(), bi.getHeight(),
191: null);
192: g.dispose();
193: }
194: } else {
195: // it's a complex FloatGridCoverage made up of different
196: // source coverages
197: for (int i = 0; i < sources.length; i++) {
198: PT_Envelope env = sources[i].getEnvelope();
199: Envelope sourceEnv = GeometryFactory.createEnvelope(
200: env.minCP.ord[0], env.minCP.ord[1],
201: env.maxCP.ord[0], env.maxCP.ord[1], null);
202: BufferedImage sourceImg = ((AbstractGridCoverage) sources[i])
203: .getAsImage(-1, -1);
204: env = this .getEnvelope();
205: Envelope targetEnv = GeometryFactory.createEnvelope(
206: env.minCP.ord[0], env.minCP.ord[1],
207: env.maxCP.ord[0], env.maxCP.ord[1], null);
208:
209: bi = paintImage(bi, targetEnv, sourceImg, sourceEnv);
210: }
211: }
212:
213: return bi;
214: }
215:
216: /**
217: * calculates the original size of a gridcoverage based on its resolution and the envelope(s) of
218: * its source(s).
219: *
220: * @return
221: */
222: private Rectangle calculateOriginalSize() {
223: if (data != null) {
224: return new Rectangle(data[0][0].length, data[0].length);
225: }
226: BufferedImage bi = ((ImageGridCoverage) sources[0]).getAsImage(
227: -1, -1);
228: PT_Envelope env = sources[0].getEnvelope();
229: double dx = (env.maxCP.ord[0] - env.minCP.ord[0])
230: / bi.getWidth();
231: double dy = (env.maxCP.ord[1] - env.minCP.ord[1])
232: / bi.getHeight();
233: env = this .getEnvelope();
234: int w = (int) Math.round((env.maxCP.ord[0] - env.minCP.ord[0])
235: / dx);
236: int h = (int) Math.round((env.maxCP.ord[1] - env.minCP.ord[1])
237: / dy);
238: return new Rectangle(w, h);
239: }
240: }
|