ECW support update 3

1 message Options
Embed this post
Permalink
stutte

ECW support update 3

Reply Threaded More More options
Print post
Permalink
Find enclosed the RasterDisplayElement bugfix.

//$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/graphics/displayelements/RasterDisplayElement.java $
/*----------------------------------------------------------------------------
 This file is part of deegree, http://deegree.org/
 Copyright (C) 2001-2009 by:
   Department of Geography, University of Bonn
 and
   lat/lon GmbH

 This library is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free
 Software Foundation; either version 2.1 of the License, or (at your option)
 any later version.
 This library is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 details.
 You should have received a copy of the GNU Lesser General Public License
 along with this library; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

 Contact information:

 lat/lon GmbH
 Aennchenstr. 19, 53177 Bonn
 Germany
 http://lat-lon.de/

 Department of Geography, University of Bonn
 Prof. Dr. Klaus Greve
 Postfach 1147, 53001 Bonn
 Germany
 http://www.geographie.uni-bonn.de/deegree/

 e-mail: [hidden email]
----------------------------------------------------------------------------*/
package org.deegree.graphics.displayelements;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;

import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.Pair;
import org.deegree.graphics.sld.Categorize;
import org.deegree.graphics.sld.Interpolate;
import org.deegree.graphics.sld.RasterSymbolizer;
import org.deegree.graphics.transformation.GeoTransform;
import org.deegree.model.coverage.grid.GridCoverage;
import org.deegree.model.coverage.grid.ImageGridCoverage;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.ogcwebservices.wms.operation.DimensionValues;
import org.deegree.ogcwebservices.wms.operation.GetMap;
import org.deegree.processing.raster.converter.Image2RawData;

/**
 *
 *
 *
 * @version $Revision: 18234 $
 * @author <a href="mailto:[hidden email]">Andreas Poth</a>
 * @author last edited by: $Author: apoth $
 *
 * @version 1.0. $Revision: 18234 $, $Date: 2009-06-23 15:40:38 +0200 (mar, 23 giu 2009) $
 *
 * @since 2.0
 */
public class RasterDisplayElement extends AbstractDisplayElement {

    private static final long serialVersionUID = -5195730721807600940L;

    private static ILogger LOG = LoggerFactory.getLogger( RasterDisplayElement.class );

    private RasterSymbolizer symbolizer = null;

    private GridCoverage gc = null;

    private GetMap request;

    /**
     * Creates a new RasterDisplayElement_Impl object.
     *
     * @param gc
     *            raster
     */
    RasterDisplayElement( GridCoverage gc ) {
        setRaster( gc );
        symbolizer = new RasterSymbolizer();
    }

    /**
     * Creates a new RasterDisplayElement_Impl object.
     *
     * @param gc
     *            raster
     * @param symbolizer
     */
    RasterDisplayElement( GridCoverage gc, RasterSymbolizer symbolizer ) {
        setRaster( gc );
        this.symbolizer = symbolizer;
    }

    RasterDisplayElement( GridCoverage gc, RasterSymbolizer symbolizer, GetMap request ) {
        this.request = request;
        setRaster( gc );
        this.symbolizer = symbolizer;
    }

    private void paintCoverage( Graphics2D g, float[][] data, int minx, int miny, int maxx, int maxy,
                                BufferedImage image ) {
        Categorize categorize = symbolizer == null ? null : symbolizer.getCategorize();
        Interpolate interpolate = symbolizer == null ? null : symbolizer.getInterpolate();

        LOG.logDebug( categorize == null ? "Not using categorization symbolizer." : "Using categorization symbolizer." );
        LOG.logDebug( interpolate == null ? "Not using interpolation symbolizer." : "Using interpolation symbolizer." );

        int opac = symbolizer == null ? 1 : ( (int) ( 255 * symbolizer.getOpacity() ) << 24 );

        int width = maxx - minx;
        int height = maxy - miny;

        BufferedImage img = new BufferedImage( data[0].length, data.length, BufferedImage.TYPE_INT_ARGB );

        DimensionValues vals = request == null ? null : request.getDimElev();

        for ( int x = 0; x < data[0].length; ++x ) {
            for ( int y = 0; y < data.length; ++y ) {
                float d = data[y][x];
                int val = 0;

                if ( ( vals != null && vals.includesValue( d ) ) || vals == null ) {
                    if ( categorize == null && interpolate == null ) {
                        val = image.getRGB( x, y );
                        val = val & 0xffffff + opac;
                    } else if ( categorize != null ) {
                        val = categorize.categorize( d, opac );
                    } else if ( interpolate != null ) {
                        val = interpolate.interpolate( d, opac );
                    }
                }

                img.setRGB( x, y, val );
            }
        }

        if ( symbolizer != null && symbolizer.getShaded() ) {
            BufferedImage old = img;

            Pair<Integer, float[]> pair = symbolizer.getShadeKernel();
            Kernel kernel = new Kernel( 3, 3, new float[] { -1, -1, -1, -1, 10, -1, -1, -1, -1 } );
            ConvolveOp op = new ConvolveOp( kernel );
            img = op.filter( img, null );
            kernel = new Kernel( pair.first, pair.first, pair.second );
            op = new ConvolveOp( kernel );
            img = op.filter( img, null );

            // this post processing is necessary to remove pixels that were filtered out by the
            // ELEVATION parameter
            // value and to fix up artifacts from the shade operations above
            for ( int y = 0; y < old.getHeight(); ++y ) {
                for ( int x = 0; x < old.getWidth(); ++x ) {
                    int oldVal = old.getRGB( x, y );
                    int newVal = img.getRGB( x, y );
                    if ( oldVal == 0 ) {
                        img.setRGB( x, y, 0 );
                    } else {
                        if ( ( newVal & 0xff000000 ) == 0 ) {
                            img.setRGB( x, y, oldVal );
                        } else if ( ( newVal & 0xffffff ) == 0xffffff ) {
                            img.setRGB( x, y, oldVal );
                        }
                    }
                }
            }

        }

        if ( symbolizer != null && symbolizer.getGamma() != 1 ) {
            Kernel kernel = new Kernel( 1, 1, new float[] { (float) symbolizer.getGamma() } );
            img = new ConvolveOp( kernel ).filter( img, null );
        }

        g.drawImage( img, minx, miny, width, height, null );
    }

    /**
     * renders the DisplayElement to the submitted graphic context
     *
     */
    public void paint( Graphics g, GeoTransform projection, double scale ) {
        synchronized ( symbolizer ) {
            try {
                if ( doesScaleConstraintApply( scale ) ) {
                    Envelope env = gc.getEnvelope();
                    // -----------------------------------------------------------------
                    // Jens Stutte (Planetek Italia s.r.l) 16/09/2009
                    // BUGFIX: Added Math.round to avoid blank pixels in some
                    // scaling factors of (ECW) coverages.
                    // Prior to this changes, for example a request for a 256x256 tile
                    // could result in some cases in a stretched painting into a
                    // 255x256 rectangle.
                    // TODO: Check if there are no side effects of this change !
                    int minx = (int) Math.round( ( projection.getDestX( env.getMin().getX() ) ) );
                    int maxy = (int) Math.round( ( projection.getDestY( env.getMin().getY() ) ) );
                    int maxx = (int) Math.round( ( projection.getDestX( env.getMax().getX() ) ) );
                    int miny = (int) Math.round( ( projection.getDestY( env.getMax().getY() ) ) );
                    LOG.logDebug("paint (minx,miny,maxx,maxy) : (" + minx + "," + miny + "," + maxx + "," + maxy + ")");

                    if ( gc instanceof ImageGridCoverage ) {
                        ImageGridCoverage igc = (ImageGridCoverage) gc;
                        Graphics2D g2 = (Graphics2D) g;
                        BufferedImage image = igc.getAsImage( -1, -1 );

                        if ( symbolizer.isDefault() && ( request == null || request.getDimElev() == null ) ) {
                            if ( symbolizer.getGamma() != 1 ) {
                                Kernel kernel = new Kernel( 1, 1, new float[] { (float) symbolizer.getGamma() } );
                                image = new ConvolveOp( kernel ).filter( image, null );
                            }
                            g2.drawImage( image, minx, miny, maxx - minx, maxy - miny, null );
                        } else {
                            if ( symbolizer.scaleValid( scale ) ) {
                                paintCoverage( g2, new Image2RawData( image ).parse(), minx, miny, maxx, maxy, image );
                            }
                        }
                    } else {
                        // TODO
                        // handle other grid coverages
                    }
                }
            } catch ( Exception e ) {
                LOG.logError( e.getMessage(), e );
                throw new RuntimeException( e.getMessage(), e );
            }
        }
    }

    /**
     * returns the content of the <code>RasterDisplayElement</code>
     *
     * @return gird coverage
     */
    public GridCoverage getRaster() {
        return gc;
    }

    /**
     * sets the grid coverage that represents the content of the <code>RasterDisplayElement</code>
     *
     * @param gc
     *
     */
    public void setRaster( GridCoverage gc ) {
        this.gc = gc;
    }

    @Override
    public boolean doesScaleConstraintApply( double scale ) {
        return symbolizer.scaleValid( scale );
    }

}

------------------------------------------------------------------------------
Come build with us! The BlackBerry® Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9-12, 2009. Register now!
http://p.sf.net/sfu/devconf
_______________________________________________
deegree-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/deegree-devel