    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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    }