/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
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:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.portal.standard.wms.control;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.deegree.enterprise.control.FormEvent;
import org.deegree.enterprise.control.RPCMember;
import org.deegree.enterprise.control.RPCMethodCall;
import org.deegree.enterprise.control.RPCParameter;
import org.deegree.enterprise.control.RPCStruct;
import org.deegree.enterprise.control.RPCWebEvent;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.framework.util.Debug;
import org.deegree.framework.util.IDGenerator;
import org.deegree.framework.util.ImageUtils;
import org.deegree.graphics.Encoders;
import org.deegree.ogcwebservices.InconsistentRequestException;
import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
import org.deegree.portal.context.GeneralExtension;
import org.deegree.portal.context.IOSettings;
import org.deegree.portal.context.ViewContext;
/**
* will be called if the client forces a dynamic legend.
* <p>-------------------------------------------------------</p>
*
* @author <a href="mailto:lupp@lat-lon.de">Katharina Lupp</a>
* @version $Revision: 1.7 $ $Date: 2006/08/29 19:54:13 $
*/
public class LegendListener extends AbstractMapListener {
private static final ILogger LOG = LoggerFactory.getLogger( LegendListener.class );
/**
* the method will be called if a zoomout action/event occurs.
*/
public void actionPerformed( FormEvent event ) {
Debug.debugMethodBegin();
super.actionPerformed( event );
RPCWebEvent rpc = (RPCWebEvent) event;
RPCMethodCall mc = rpc.getRPCMethodCall();
RPCParameter[] para = mc.getParameters();
RPCStruct struct = (RPCStruct) para[0].getValue();
HttpSession session = ( (HttpServletRequest) this.getRequest() ).getSession( true );
ViewContext vc = (ViewContext) session.getAttribute( "DefaultMapContext" );
HashMap[] model = createWMSRequestModel( struct );
try {
GetLegendGraphic legendParam = getLegendRequestParameter();
HashMap symbols = setLegend( legendParam, model );
Rectangle rect = calcLegendSize( symbols );
BufferedImage bi = new BufferedImage( rect.width + 30, rect.height + 50,
BufferedImage.TYPE_INT_RGB );
bi = drawSymbolsToBI( symbols, bi );
saveImage( vc, bi );
} catch ( Exception e ) {
LOG.logError( "Error occurred in PrintListener: ", e );
}
Debug.debugMethodEnd();
}
private Rectangle calcLegendSize( HashMap map ) {
String[] layers = (String[]) map.get( "NAMES" );
BufferedImage[] legs = (BufferedImage[]) map.get( "IMAGES" );
int w = 0;
int h = 0;
for ( int i = 0; i < layers.length; i++ ) {
h += legs[i].getHeight() + 6;
Graphics g = legs[i].getGraphics();
Rectangle2D rect = g.getFontMetrics().getStringBounds( layers[i], g );
g.dispose();
if ( rect.getWidth() > w ) {
w = (int) rect.getWidth();
}
}
w += 50;
return new Rectangle( w, h );
}
private BufferedImage drawSymbolsToBI( HashMap map, BufferedImage bi ) {
Graphics g = bi.getGraphics();
g.setColor( Color.WHITE );
g.fillRect( 1, 1, bi.getWidth() - 2, bi.getHeight() - 2 );
String[] layers = (String[]) map.get( "NAMES" );
BufferedImage[] legs = (BufferedImage[]) map.get( "IMAGES" );
int h = 5;
for ( int i = layers.length - 1; i >= 0; i-- ) {
g.drawImage( legs[i], 20, h, null );
g.setColor( Color.BLACK );
if ( legs[i].getHeight() < 50 ) {
g.drawString( layers[i], 30 + legs[i].getWidth(),
h + (int) ( legs[i].getHeight() / 1.2 ) );
}
h += legs[i].getHeight() + 5;
}
g.dispose();
return bi;
}
private HashMap[] createWMSRequestModel( RPCStruct struct ) {
RPCMember[] member = struct.getMembers();
String request = "";
HashMap[] getMR = new HashMap[member.length];
for ( int i = 0; i < member.length; i++ ) {
request = (String) member[i].getValue();
getMR[i] = toMap( request );
StringTokenizer st = new StringTokenizer( request, "?" );
getMR[i].put( "URL", st.nextToken() );
}
return getMR;
}
private void saveImage( ViewContext vc, BufferedImage bg ) {
GeneralExtension ge = vc.getGeneral().getExtension();
IOSettings ios = ge.getIOSettings();
String dir = ios.getPrintDirectory().getDirectoryName();
String format = "jpeg";
long l = IDGenerator.getInstance().generateUniqueID();
String file = "legend" + l + "." + format;
try {
FileOutputStream fos = new FileOutputStream( dir + "/" + file );
if ( format.equals( "jpeg" ) ) {
Encoders.encodeJpeg( fos, bg, 1 );
} else if ( format.equals( "gif" ) ) {
Encoders.encodeGif( fos, bg );
} else if ( format.equals( "bmp" ) ) {
Encoders.encodeBmp( fos, bg );
} else if ( format.equals( "png" ) ) {
Encoders.encodePng( fos, bg );
} else if ( format.equals( "tiff" ) ) {
Encoders.encodeTiff( fos, bg );
}
fos.close();
} catch ( Exception e ) {
LOG.logError( "Error occurred in saving legend image: ", e );
}
int pos = dir.lastIndexOf( '/' );
String access = "./" + dir.substring( pos + 1, dir.length() ) + "/" + file;
this.getRequest().setAttribute( "DYNLEGENDIMAGE", access );
}
private GetLegendGraphic getLegendRequestParameter()
throws InconsistentRequestException {
HashMap legend = toMap( "VERSION=1.1.1&REQUEST=GetLegendGraphic&FORMAT=image/jpeg&WIDTH=50&HEIGHT=50&"
+ "EXCEPTIONS=application/vnd.ogc.se_inimage&LAYER=europe:major_rivers&STYLE=default&"
+ "SLD=file:///styles.xml" );
legend.put( "ID", "1" );
return GetLegendGraphic.create( legend );
}
/**
* creates legend
*/
private HashMap setLegend( GetLegendGraphic glr, HashMap[] model )
throws MalformedURLException, IOException {
Debug.debugMethodBegin( this, "setScaleBarURL" );
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
StringTokenizer st = null;
String format = glr.getFormat();
if ( format.equals( "image/jpg" ) )
format = "image/jpeg";
String legendURL = "";
int lgHeight = 0;
for ( int i = 0; i < model.length; i++ ) {
String style = (String) model[i].get( "STYLE" );
if ( style != null ) {
st = new StringTokenizer( style, "," );
style = st.nextToken();
} else
style = "default";
st = new StringTokenizer( (String) model[i].get( "LAYERS" ), "," );
while ( st.hasMoreTokens() ) {
String layer = st.nextToken();
legendURL = setLegendURL( layer, style, format, glr, model[0] );
lgHeight = lgHeight + 30;
BufferedImage legendGraphic = ImageUtils.loadImage( new URL( legendURL ) );
list1.add( layer );
list2.add( legendGraphic );
}
}
Debug.debugMethodEnd();
String[] layers = (String[]) list1.toArray( new String[list1.size()] );
BufferedImage[] legs = (BufferedImage[]) list2.toArray( new BufferedImage[list2.size()] );
HashMap map = new HashMap();
map.put( "NAMES", layers );
map.put( "IMAGES", legs );
return map;
}
private String setLegendURL( String layer, String style, String format, GetLegendGraphic glr,
HashMap model ) {
StringBuffer sb = new StringBuffer( 500 );
sb.append( model.get( "URL" ) ).append( '?' );
sb.append( "&VERSION=" ).append( glr.getVersion() );
sb.append( "&REQUEST=GetLegendGraphic" );
sb.append( "&FORMAT=" ).append( format );
sb.append( "&WIDTH=15" );
sb.append( "&HEIGHT=15&EXCEPTIONS=application/vnd.ogc.se_inimage" );
sb.append( "&LAYER=" ).append( layer );
sb.append( "&STYLE=" ).append( style );
return sb.toString();
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: LegendListener.java,v $
Revision 1.7 2006/08/29 19:54:13 poth
footer corrected
Revision 1.6 2006/08/07 14:37:22 poth
never used parameters and methods removed
Revision 1.5 2006/07/12 14:46:18 poth
comment footer added
********************************************************************** */