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