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