001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/tools/legend/LegendElementCreator.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    
045    package org.deegree.tools.legend;
046    
047    import java.awt.Color;
048    import java.awt.Graphics;
049    import java.awt.image.BufferedImage;
050    import java.io.File;
051    import java.io.FileOutputStream;
052    import java.io.IOException;
053    import java.util.HashMap;
054    import java.util.Iterator;
055    import java.util.Map;
056    
057    import org.deegree.framework.log.ILogger;
058    import org.deegree.framework.log.LoggerFactory;
059    import org.deegree.framework.util.ImageUtils;
060    import org.deegree.framework.util.MimeTypeMapper;
061    import org.deegree.framework.xml.XMLParsingException;
062    import org.deegree.graphics.legend.LegendElement;
063    import org.deegree.graphics.legend.LegendException;
064    import org.deegree.graphics.legend.LegendFactory;
065    import org.deegree.graphics.sld.AbstractStyle;
066    import org.deegree.graphics.sld.NamedLayer;
067    import org.deegree.graphics.sld.SLDFactory;
068    import org.deegree.graphics.sld.StyledLayerDescriptor;
069    import org.deegree.graphics.sld.UserLayer;
070    import org.deegree.graphics.sld.UserStyle;
071    
072    /**
073     * This executable class is an application, which reads out an sld-document, creates the
074     * corresponding legend-elements and saves them as an image. The class can be executed from the
075     * console. 
076     * 
077     * 
078     * @author <a href="schaefer@lat-lon.de">Axel Schaefer</a>
079     * @author last edited by: $Author: apoth $
080     * 
081     * @version $Revision: 9346 $, $Date: 2007-12-27 17:39:07 +0100 (Do, 27 Dez 2007) $
082     */
083    public class LegendElementCreator {
084    
085        private static final ILogger LOG = LoggerFactory.getLogger( LegendElementCreator.class );
086    
087        String verbose_output = "";
088    
089        LecGUI lecgui = null;
090    
091        /**
092         * @param sldfile
093         * @param directory
094         * @param format
095         * @param color
096         * @param width
097         * @param height
098         * @param title
099         * @param lec
100         * @throws LegendException
101         * 
102         */
103        public LegendElementCreator( String sldfile, String directory, String format, Color color, int width, int height,
104                                     String title, LecGUI lec ) throws LegendException {
105    
106            this.lecgui = lec;
107    
108            StringBuffer sb = new StringBuffer( 100 );
109    
110            // read out the SLD
111            HashMap stylemap = null;
112            try {
113                stylemap = loadSLD( sldfile );
114            } catch ( IOException ioe ) {
115                throw new LegendException( "An error (IOException) occured in processing the SLD-File:\n" + sldfile + "\n"
116                                           + ioe );
117            } catch ( XMLParsingException xmlpe ) {
118                throw new LegendException( "An error (XMLParsingException) occured in parsing " + "the SLD-File:\n"
119                                           + sldfile + "\n" + xmlpe.getMessage() );
120            }
121    
122            // output
123            LegendFactory lf = new LegendFactory();
124            LegendElement le = null;
125            BufferedImage buffi = null;
126    
127            Iterator iterator = stylemap.entrySet().iterator();
128            String filename = null;
129            AbstractStyle style = null;
130            int i = 0;
131            while ( iterator.hasNext() ) {
132                i++;
133                Map.Entry entry = (Map.Entry) iterator.next();
134                filename = ( (String) entry.getKey() ).replace( ':', '_' );
135                style = (AbstractStyle) entry.getValue();
136    
137                try {
138                    le = lf.createLegendElement( style, width, height, title );
139                    buffi = le.exportAsImage( MimeTypeMapper.toMimeType( format ) );
140                    saveImage( buffi, directory, filename, format, color );
141                    sb.append( "- Image " + filename + "." + format + " in " + directory + " saved.\n" );
142                } catch ( LegendException lex ) {
143                    throw new LegendException( "An error (LegendException) occured during the creating\n"
144                                               + "of the LegendElement " + filename + ":\n" + lex );
145                } catch ( IOException ioex ) {
146                    throw new LegendException( "An error (IOException) occured during the creating/saving\n"
147                                               + "of the output-image " + filename + ":\n" + ioex );
148                } catch ( Exception ex ) {
149                    throw new LegendException( "A general error (Exception) occured during the creating/saving\n"
150                                               + "of the output-image " + filename + ":\n" + ex );
151                }
152    
153            }
154            setVerboseOutput( sb.toString() );
155        }
156    
157        /**
158         * 
159         * @return verbose_output
160         */
161        public String getVerboseOutput() {
162            return this.verbose_output;
163        }
164    
165        /**
166         * @param vo
167         */
168        public void setVerboseOutput( String vo ) {
169            if ( vo != null ) {
170                this.verbose_output = vo;
171            }
172        }
173    
174        /**
175         * loads the sld-document, parses it an returns a HashMap containing the different styles.
176         * 
177         * @param sldFile
178         *            the file containing the StyledLayerDescriptor
179         * @return HashMap containing the styles of the SLD.
180         * @throws IOException
181         *             if the SLD-document cant be read/found in the filesystem
182         * @throws XMLParsingException
183         *             if an error occurs during the parsing of the sld-document
184         */
185        static private HashMap loadSLD( String sldFile )
186                                throws IOException, XMLParsingException {
187            AbstractStyle[] styles = null;
188    
189            File file = new File( sldFile );
190            StyledLayerDescriptor sld = SLDFactory.createSLD( file.toURL() );
191    
192            HashMap<String,AbstractStyle> map = new HashMap<String,AbstractStyle>();
193    
194            // NAMED LAYER
195            NamedLayer[] namedlayers = sld.getNamedLayers();
196            for ( int i = 0; i < namedlayers.length; i++ ) {
197                styles = namedlayers[i].getStyles();
198                for ( int j = 0; j < styles.length; j++ ) {
199                    if ( styles[j] instanceof UserStyle ) {
200                        map.put( styles[j].getName(), styles[j] );
201                    }
202                }
203            }
204    
205            // USER LAYER
206            UserLayer[] userLayers = sld.getUserLayers();
207            for ( int k = 0; k < userLayers.length; k++ ) {
208                styles = userLayers[k].getStyles();
209                for ( int l = 0; l < styles.length; l++ ) {
210                    if ( styles[l] instanceof UserStyle ) {
211                        map.put( styles[l].getName(), styles[l] );
212                    }
213                }
214            }
215            return map;
216        }
217    
218        /**
219         * saves the resulting buffered Image from org.deegree.graphics.legend as an image.
220         * 
221         * @param bi
222         *            the BufferedImage from org.deegree.graphics.legend.*
223         * @param outdir
224         *            the output-directory (application-parameter)
225         * @param filename
226         *            the output-filename (from the styles of the SLD)
227         * @param graphicsformat
228         *            the output-graphicsformat (application-parameter)
229         * @throws IOException
230         *             if saving fails.
231         * @throws Exception
232         *             if the graphic-encoder can't be found.
233         */
234        private void saveImage( BufferedImage bi, String outdir, String filename, String graphicsformat, Color color )
235                                throws LegendException, IOException, Exception {
236    
237            File file = new File( outdir, filename + "." + graphicsformat );
238            FileOutputStream fos = new FileOutputStream( file );
239    
240            // PNG
241            if ( graphicsformat.equalsIgnoreCase( "PNG" ) ) {
242    
243                BufferedImage outbi = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB );
244                Graphics g = outbi.getGraphics();
245                g.drawImage( bi, 0, 0, color, null );
246                ImageUtils.saveImage( outbi, fos, "png", 1 );
247                // BMP
248            } else if ( graphicsformat.equalsIgnoreCase( "BMP" ) ) {
249                BufferedImage outbi = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_3BYTE_BGR );
250    
251                Graphics g = outbi.getGraphics();
252                // transparency
253                if ( color == null ) {
254                    this.lecgui.addDebugInformation( "BMP-NOTIFY:\n"
255                                                     + "Requested transparency (transp.) isn't available for BMP-images.\n"
256                                                     + "Using default background color WHITE.\n" );
257                    color = Color.WHITE;
258                }
259                g.drawImage( bi, 0, 0, color, null );
260                ImageUtils.saveImage( outbi, fos, "bmp", 1 );
261                // GIF
262            } else if ( graphicsformat.equalsIgnoreCase( "GIF" ) ) {
263                BufferedImage outbi = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB );
264                Graphics g = outbi.getGraphics();
265                g.drawImage( bi, 0, 0, color, null );
266                ImageUtils.saveImage( outbi, fos, "gif", 1 );
267                // JPEG
268            } else if ( graphicsformat.equalsIgnoreCase( "JPEG" ) || graphicsformat.equalsIgnoreCase( "JPG" ) ) {
269                BufferedImage outbi = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_RGB );
270                Graphics g = outbi.getGraphics();
271    
272                // transparency
273                if ( color == null ) {
274                    this.lecgui.addDebugInformation( "JPEG-NOTIFY:\n"
275                                                     + "Requested transparency (transp.) isn't available for JPG-images.\n"
276                                                     + "Using default background color WHITE.\n" );
277                    color = Color.WHITE;
278                }
279    
280                g.drawImage( bi, 0, 0, color, null );
281                ImageUtils.saveImage( outbi, fos, "jpeg", 1 );
282                // TIFF
283            } else if ( graphicsformat.equalsIgnoreCase( "TIFF" ) || graphicsformat.equalsIgnoreCase( "TIF" ) ) {
284                BufferedImage outbi = new BufferedImage( bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_BYTE_BINARY );
285                Graphics g = outbi.getGraphics();
286                g.drawImage( bi, 0, 0, color, null );
287                ImageUtils.saveImage( outbi, fos, "tif", 1 );
288            } else {
289                throw new Exception( "Can't save output image because no graphic-encoder found for:\n" + "filetype: '"
290                                     + graphicsformat + "' for file: '" + file + "'" );
291            }
292            LOG.logInfo( "-- " + file + " saved." );
293        }
294    
295        /**
296         * main-method for testing purposes
297         * 
298         * @param args
299         */
300        public static void main( String[] args ) {
301    
302            String sldfile = args[0];
303            String directory = args[1];
304            String format = "PNG";
305            Color color = Color.WHITE;
306            int width = 40;
307            int height = 40;
308            String title = "Mein Titel Platzhalter Texttexttext";
309            LecGUI lec = null;
310    
311            try {
312                new LegendElementCreator( sldfile, directory, format, color, width, height, title, lec );
313            } catch ( LegendException e ) {
314                e.printStackTrace();
315            }
316    
317            LOG.logInfo( "...finished" );
318        }
319    
320    }