001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/model/coverage/grid/ImageGridCoverage.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: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@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: 9343 $, $Date: 2007-12-27 05:30:32 -0800 (Thu, 27 Dec 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,
085: Envelope envelope, 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,
097: Envelope envelope, 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,
111: Envelope envelope, CoordinateSystem crs,
112: boolean isEditable, BufferedImage image) {
113: super (coverageOffering, envelope, crs, isEditable);
114: this .image = image;
115: }
116:
117: /**
118: *
119: * @param coverageOffering
120: * @param envelope
121: * @param sources
122: */
123: public ImageGridCoverage(CoverageOffering coverageOffering,
124: Envelope envelope, ImageGridCoverage[] sources) {
125: super (coverageOffering, envelope, sources);
126: }
127:
128: /**
129: * The number of sample dimensions in the coverage. For grid coverages, a sample dimension is a
130: * band.
131: *
132: * @return The number of sample dimensions in the coverage.
133: */
134: public int getNumSampleDimensions() {
135: if (image != null) {
136: return image.getData().getNumBands();
137: }
138: return sources[0].getNumSampleDimensions();
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,
162: IndexOutOfBoundsException {
163: if (image != null) {
164: if (xAxis > 0 && yAxis > 0) {
165: Rectangle rect = new Rectangle(xAxis, yAxis);
166: RenderableGraphics rg = new RenderableGraphics(rect);
167: rg.drawImage(image, 0, 0, xAxis, yAxis, null);
168: return rg;
169: }
170: Rectangle rect = new Rectangle(image.getWidth(), image
171: .getHeight());
172: RenderableGraphics rg = new RenderableGraphics(rect);
173: rg.drawImage(image, 0, 0, null);
174: return rg;
175: }
176: // TODO if multi images -> sources.length > 0
177: return null;
178: }
179:
180: /**
181: * this is a deegree convenience method which returns the source image of an
182: * <tt>ImageGridCoverage</tt>. In procipal the same can be done with the
183: * getRenderableImage(int xAxis, int yAxis) method. but creating a <tt>RenderableImage</tt>
184: * image is very slow. I xAxis or yAxis <= 0 then the size of the returned image will be
185: * calculated from the source images of the coverage.
186: *
187: * @param xAxis
188: * Dimension to use for the <var>x</var> axis.
189: * @param yAxis
190: * Dimension to use for the <var>y</var> axis.
191: * @return the source image of an <tt>ImageGridCoverage</tt>.
192: */
193: public BufferedImage getAsImage(int xAxis, int yAxis) {
194:
195: if (xAxis <= 0 || yAxis <= 0) {
196: // get default size if passed target size is <= 0
197: Rectangle rect = calculateOriginalSize();
198: xAxis = rect.width;
199: yAxis = rect.height;
200: }
201: BufferedImage bi = null;
202: if (image != null) {
203: if (xAxis == image.getWidth() && yAxis == image.getHeight()) {
204: bi = image;
205: } else {
206: // it's a simple ImageGridCoverage just made up of one image
207: ParameterBlock pb = new ParameterBlock();
208: pb.addSource(image);
209: pb.add(xAxis / (float) image.getWidth()); // The xScale
210: pb.add(yAxis / (float) image.getHeight()); // The yScale
211: pb.add(0.0F); // The x translation
212: pb.add(0.0F); // The y translation
213: Interpolation interpolation = new InterpolationNearest();
214: pb.add(interpolation); // The interpolation
215: // Create the scale operation
216: RenderedOp ro = JAI.create("scale", pb, null);
217: bi = ro.getAsBufferedImage();
218: }
219: } else {
220: String natFrm = coverageOffering.getSupportedFormats()
221: .getNativeFormat().getCode();
222: if ("jpg".equalsIgnoreCase(natFrm)
223: || "jpeg".equalsIgnoreCase(natFrm)
224: || "bmp".equalsIgnoreCase(natFrm)) {
225: bi = new BufferedImage(xAxis, yAxis,
226: BufferedImage.TYPE_INT_RGB);
227: } else {
228: bi = new BufferedImage(xAxis, yAxis,
229: BufferedImage.TYPE_INT_ARGB);
230: }
231: // it's a complex ImageGridCoverage made up of different
232: // source coverages
233: if (sources == null || sources.length == 0) {
234: return bi;
235: }
236:
237: for (int i = 0; i < sources.length; i++) {
238: PT_Envelope env = sources[i].getEnvelope();
239: Envelope sourceEnv = GeometryFactory.createEnvelope(
240: env.minCP.ord[0], env.minCP.ord[1],
241: env.maxCP.ord[0], env.maxCP.ord[1], null);
242: env = this .getEnvelope();
243: Envelope targetEnv = GeometryFactory.createEnvelope(
244: env.minCP.ord[0], env.minCP.ord[1],
245: env.maxCP.ord[0], env.maxCP.ord[1], null);
246:
247: BufferedImage sourceImg = ((ImageGridCoverage) sources[i])
248: .getAsImage(-1, -1);
249: bi = paintImage(bi, targetEnv, sourceImg, sourceEnv);
250: }
251: }
252:
253: return bi;
254: }
255:
256: /**
257: * calculates the original size of a gridcoverage based on its resolution and the envelope(s) of
258: * its source(s).
259: *
260: * @return
261: */
262: private Rectangle calculateOriginalSize() {
263: if (image != null) {
264: return new Rectangle(image.getWidth(), image.getHeight());
265: }
266: BufferedImage bi = ((ImageGridCoverage) sources[0]).getAsImage(
267: -1, -1);
268: PT_Envelope env = sources[0].getEnvelope();
269: double dx = (env.maxCP.ord[0] - env.minCP.ord[0])
270: / bi.getWidth();
271: double dy = (env.maxCP.ord[1] - env.minCP.ord[1])
272: / bi.getHeight();
273: env = this .getEnvelope();
274: int w = (int) Math.round((env.maxCP.ord[0] - env.minCP.ord[0])
275: / dx);
276: int h = (int) Math.round((env.maxCP.ord[1] - env.minCP.ord[1])
277: / dy);
278: return new Rectangle(w, h);
279: }
280:
281: }
|