    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/tools/raster/Rescaler.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
    037    package org.deegree.tools.raster;
    038
    039    import java.awt.image.BufferedImage;
    040    import java.awt.image.renderable.ParameterBlock;
    041    import java.io.File;
    042    import java.net.URI;
    043    import java.util.ArrayList;
    044    import java.util.List;
    045    import java.util.Properties;
    046
    047    import javax.media.jai.Interpolation;
    048    import javax.media.jai.InterpolationBilinear;
    049    import javax.media.jai.JAI;
    050    import javax.media.jai.RenderedOp;
    051
    052    import org.deegree.datatypes.QualifiedName;
    053    import org.deegree.framework.log.ILogger;
    054    import org.deegree.framework.log.LoggerFactory;
    055    import org.deegree.framework.util.ConvenienceFileFilter;
    056    import org.deegree.framework.util.ImageUtils;
    057    import org.deegree.io.dbaseapi.DBaseFile;
    058    import org.deegree.model.coverage.grid.WorldFile;
    059    import org.deegree.ogcbase.CommonNamespaces;
    060
    061    /**
    062     *
    063     *
    064     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
    065     * @author last edited by: $Author: mschneider $
    066     *
    067     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    068     */
    069    public class Rescaler {
    070
    071        private static final ILogger LOG = LoggerFactory.getLogger( Rescaler.class );
    072
    073        private static final URI DEEGREEAPP = CommonNamespaces.buildNSURI( "http://www.deegree.org/app" );
    074
    075        private static final String APP_PREFIX = "app";
    076
    077        private String outDir;
    078
    079        private String format;
    080
    081        private Interpolation interpolation = new InterpolationBilinear();
    082
    083        private List<String> fileList;
    084
    085        private double resolution = 0;
    086
    087        /**
    088         *
    089         * @param resolution
    090         * @param rootDir
    091         * @param outDir
    092         * @param format
    093         * @param subDirs
    094         */
    095        Rescaler( double resolution, String rootDir, String outDir, String format, boolean subDirs ) {
    096            this.resolution = resolution;
    097            this.outDir = outDir;
    098            this.format = format;
    099            fileList = getFileList( rootDir, subDirs );
    100        }
    101
    102        /**
    103         *
    104         * @param resolution
    105         * @param rootDir
    106         * @param outDir
    107         * @param dBase
    108         * @param format
    109         * @param fileColumn
    110         * @throws Exception
    111         */
    112        Rescaler( double resolution, String rootDir, String outDir, String dBase, String format, String fileColumn )
    113                                throws Exception {
    114            this.resolution = resolution;
    115            this.outDir = outDir;
    116            this.format = format;
    117            fileList = getFileList( dBase, fileColumn, rootDir );
    118        }
    119
    120        /**
    121         * returns the list of image map files to consider read from a dbase file defined by the dbase parameter
    122         *
    123         * @param dbaseFile
    124         *            name of the dbase file
    125         * @param fileColumn
    126         *            name of the column containing the image map files names
    127         * @param baseDir
    128         *            name of the directory where the image map files are stored if this parameter is <code>null</code> it
    129         *            is assumed that the image map files are full referenced within the dbase
    130         * @return the list of image map files to consider read from a dbase file defined by the dbase parameter
    131         * @throws Exception
    132         */
    133        private static List<String> getFileList( String dBaseFile, String fileColumn, String baseDir )
    134                                throws Exception {
    135
    136            // handle dbase file extension and file location/reading problems
    137            if ( dBaseFile.endsWith( ".dbf" ) ) {
    138                dBaseFile = dBaseFile.substring( 0, dBaseFile.lastIndexOf( "." ) );
    139            }
    140            DBaseFile dbf = new DBaseFile( dBaseFile );
    141
    142            // sort dbase file contents chronologicaly (oldest first)
    143            int cnt = dbf.getRecordNum();
    144
    145            Object[] mapItems = new Object[cnt];
    146            QualifiedName fileC = new QualifiedName( APP_PREFIX, fileColumn.toUpperCase(), DEEGREEAPP );
    147
    148            for ( int i = 0; i < cnt; i++ ) {
    149                // name of map file
    150                mapItems[i] = dbf.getFRow( i + 1 ).getDefaultProperty( fileC ).getValue();
    151            }
    152
    153            // extract names of image files from dBase file and attach them to rootDir
    154            if ( baseDir == null ) {
    155                baseDir = "";
    156            } else if ( !baseDir.endsWith( "/" ) && !baseDir.endsWith( "\\" ) ) {
    157                baseDir = baseDir + '/';
    158            }
    159            List<String> imageFiles = new ArrayList<String>( mapItems.length );
    160            for ( int i = 0; i < mapItems.length; i++ ) {
    161                if ( mapItems[i] != null ) {
    162                    imageFiles.add( baseDir + mapItems[i] );
    163                }
    164            }
    165
    166            return imageFiles;
    167        }
    168
    169        /**
    170         * returns the list of image map files to consider read from a defined root directory.
    171         *
    172         * @param rootDir
    173         *            root directory where to read image map files
    174         * @param subdirs
    175         *            true if subdirectories of the root directory shall be parsed for image maps too
    176         * @return the list of image map files to consider read from a defined root directory.
    177         */
    178        private static List<String> getFileList( String rootDir, boolean subdirs ) {
    179            List<String> list = new ArrayList<String>( 10000 );
    180            File file = new File( rootDir );
    181            List<String> extensions = new ArrayList<String>();
    182            extensions.add( "JPEG" );
    183            extensions.add( "JPG" );
    184            extensions.add( "BMP" );
    185            extensions.add( "PNG" );
    186            extensions.add( "GIF" );
    187            extensions.add( "TIF" );
    188            extensions.add( "TIFF" );
    189            extensions.add( "GEOTIFF" );
    190            ConvenienceFileFilter cff = new ConvenienceFileFilter( extensions, true );
    191            String[] entries = file.list( cff );
    192            if ( entries != null ) {
    193                for ( int i = 0; i < entries.length; i++ ) {
    194                    File entry = new File( rootDir + '/' + entries[i] );
    195                    if ( entry.isDirectory() && subdirs ) {
    196                        list = readSubDirs( entry, list, cff );
    197                    } else {
    198                        list.add( rootDir + '/' + entries[i] );
    199                    }
    200                }
    201            }
    202            return list;
    203        }
    204
    205        /**
    206         *
    207         * @param file
    208         * @param list
    209         * @return a list of strings
    210         */
    211        private static List<String> readSubDirs( File file, List<String> list, ConvenienceFileFilter cff ) {
    212
    213            String[] entries = file.list( cff );
    214            if ( entries != null ) {
    215                for ( int i = 0; i < entries.length; i++ ) {
    216                    File entry = new File( file.getAbsolutePath() + '/' + entries[i] );
    217                    if ( entry.isDirectory() ) {
    218                        list = readSubDirs( entry, list, cff );
    219                    } else {
    220                        list.add( file.getAbsolutePath() + '/' + entries[i] );
    221                    }
    222                }
    223            }
    224            return list;
    225        }
    226
    227        /**
    228         *
    229         * @throws Exception
    230         */
    231        public void process()
    232                                throws Exception {
    233            for ( int i = 0; i < fileList.size(); i++ ) {
    234                System.out.print( fileList.get( i ) + "\r" );
    235                File file = new File( fileList.get( i ) );
    236                BufferedImage image = ImageUtils.loadImage( file );
    237                WorldFile wf = WorldFile.readWorldFile( fileList.get( i ), WorldFile.TYPE.CENTER, image.getWidth(),
    238                                                        image.getHeight() );
    239                float qx = (float) ( wf.getResx() / resolution );
    240                float qy = (float) ( wf.getResy() / resolution );
    241
    242                ParameterBlock pb = new ParameterBlock();
    243                pb.addSource( image );
    244                pb.add( qx ); // The xScale
    245                pb.add( qy ); // The yScale
    246                pb.add( 0.0F ); // The x translation
    247                pb.add( 0.0F ); // The y translation
    248                pb.add( interpolation ); // The interpolation
    249                // Create the scale operation
    250                RenderedOp ro = JAI.create( "scale", pb, null );
    251                try {
    252                    image = ro.getAsBufferedImage();
    253                } catch ( Exception e ) {
    254                    e.printStackTrace();
    255                }
    256
    257                wf = new WorldFile( resolution, resolution, 0, 0, wf.getEnvelope() );
    258                int p = file.getName().lastIndexOf( '.' );
    259                String fileBaseName = file.getName().substring( 0, p );
    260                ImageUtils.saveImage( image, outDir + fileBaseName + '.' + format, 1 );
    261                WorldFile.writeWorldFile( wf, outDir + fileBaseName );
    262                System.gc();
    263            }
    264        }
    265
    266        private static void printHelp() {
    267            System.out.println();
    268            System.out.println( "Parameter description for RasterSplitter:" );
    269            System.out.println( "-res : desired raster resolution" );
    270            System.out.println( "-format : desired image format of result images (mandatory)" );
    271            System.out.println( "-outDir : directory where result images shall be stored (mandatory)" );
    272
    273            System.out.println( "-rootDir : directory from where images to split will be read (mandatory)" );
    274            System.out.println( "-subDirs : (true|false). If 'true' all sub directories of the 'rootDir' " );
    275            System.out.println( "            will be searched for images too (optional; default = false)" );
    276        }
    277
    278        private static boolean validate( Properties map ) {
    279            if ( map.getProperty( "-res" ) == null ) {
    280                System.out.println( "-res must be set!" );
    281                return false;
    282            }
    283            if ( map.getProperty( "-format" ) == null ) {
    284                System.out.println( "-format must be set!" );
    285                return false;
    286            }
    287            if ( map.getProperty( "-outDir" ) == null ) {
    288                System.out.println( "-outDir must be set!" );
    289                return false;
    290            }
    291            if ( map.getProperty( "-rootDir" ) == null ) {
    292                System.out.println( "-rootDir must be set!" );
    293                return false;
    294            }
    295            if ( map.getProperty( "-subDirs" ) != null && !"true".equals( map.getProperty( "-subDirs" ) )
    296                 && !"false".equals( map.getProperty( "-subDirs" ) ) ) {
    297                System.out.println( "if -subDirs is set it must be true or false!" );
    298                return false;
    299            }
    300            return true;
    301        }
    302
    303        /**
    304         * @param args
    305         * @throws Exception
    306         */
    307        public static void main( String[] args )
    308                                throws Exception {
    309            Properties map = new Properties();
    310            for ( int i = 0; i < args.length; i += 2 ) {
    311                map.put( args[i], args[i + 1] );
    312            }
    313            if ( !validate( map ) ) {
    314                printHelp();
    315                return;
    316            }
    317
    318            String format = map.getProperty( "-format" );
    319            String outDir = map.getProperty( "-outDir" );
    320            double res = Double.parseDouble( map.getProperty( "-res" ) );
    321            Rescaler rescaler = null;
    322            if ( map.get( "-dbaseFile" ) != null ) {
    323                String dBaseFile = map.getProperty( "-dbaseFile" );
    324                String fileColum = map.getProperty( "-fileColumn" );
    325                String baseDir = map.getProperty( "-baseDir" );
    326                if ( baseDir == null ) {
    327                    baseDir = map.getProperty( "-rootDir" );
    328                }
    329                rescaler = new Rescaler( res, baseDir, outDir, dBaseFile, format, fileColum );
    330            } else if ( map.get( "-rootDir" ) != null ) {
    331                String rootDir = map.getProperty( "-rootDir" );
    332                boolean subDirs = "true".equals( map.get( "-subDirs" ) );
    333                rescaler = new Rescaler( res, rootDir, outDir, format, subDirs );
    334            } else {
    335                LOG.logInfo( map.toString() );
    336                System.out.println( "-rootDir or -dbaseFile parameter must be defined" );
    337                return;
    338            }
    339            rescaler.process();
    340
    341        }
    342
    343    }