//$$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/portal/standard/wms/control/ScaleSwitcherListener.java,v 1.14 2006/11/27 09:07:52 poth Exp $$
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
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
Aennchenstraße 19
53177 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.util.ResourceBundle;
import javax.servlet.ServletRequest;
import org.deegree.enterprise.control.FormEvent;
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.MapUtils;
import org.deegree.model.crs.CRSFactory;
import org.deegree.model.crs.CoordinateSystem;
import org.deegree.model.crs.UnknownCRSException;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.model.spatialschema.GeometryFactory;
import org.deegree.portal.Constants;
import org.deegree.portal.PortalException;
/**
* The ScaleSwitcherListner handles switching the values of the scales from igeoportal
*
* @author <a href="mailto:ncho@lat-lon.de">Serge N'Cho</a>
* @author last edited by: $$Author: poth $$
*
* @version $$Revision: 1.14 $$, $$Date: 2006/11/27 09:07:52 $$
*/
public class ScaleSwitcherListener extends AbstractMapListener {
private static final ILogger LOG = LoggerFactory.getLogger( ScaleSwitcherListener.class );
private static double PIXEL_SIZE = 0.00028;
static {
final ResourceBundle bundle = ResourceBundle.getBundle( "org.deegree.portal.standard.wms.control.map_listener" ); //$NON-NLS-1$
String ps = bundle.getString( "ScaleSwitcher.pixelSize" );
if ( ps != null ) {
PIXEL_SIZE = Double.valueOf( ps );
}
}
/**
* Constant for "taskFromListener"
*/
public static final String TASK_FROM_LISTENER = "taskFromListener";
/**
* Constant for "BBOX"
*/
public static final String BBOX = "BBOX";
/**
* Constant for "zoomToFullExtent"
*/
public static final String FULL_EXTENT = "zoomToFullExtent";
/**
* Constant for "scaleValue"
*/
public static final String SCALE_VALUE = "scaleValue";
/**
* Constant for "newScaleValue"
*/
public static final String NEW_SCALE_VALUE = "newScaleValue";
/**
* Constant for "newBBox"
*/
public static final String NEW_BBOX = "newBBox";
/**
* Constant for "crs"
*/
private static final String CRS = "crs";
/**
* Constant for "mapWidth"
*/
private static final String MAP_WIDTH = "mapWidth";
/**
* Constant for "mapHeight"
*/
private static final String MAP_HEIGHT = "mapHeight";
/**
* Constant for "taskFromJSObject"
*/
private static final String JS_TAK = "taskFromJSObject";
/**
* Constant for "requestedScale"
*/
private static final String REQUESTED_SCALE = "requestedScale";
/**
* Constant for "getNewBBOX"
*/
private static final String GET_NEW_BBOX = "getNewBBOX";
/**
* Constant for "savedScaleValue"
*/
private static final String SAVED_SCALE = "savedScaleValue";
/**
* Constant for "getActualScaleValue"
*/
private static final String GET_ACTUAL_SCALE = "getActualScaleValue";
/**
* @see org.deegree.enterprise.control
* .WebListener#actionPerformed(org.deegree.enterprise.control.FormEvent)
*/
public void actionPerformed( FormEvent event ) {
LOG.entering();
RPCWebEvent rpc = (RPCWebEvent) event;
RPCMethodCall mc = rpc.getRPCMethodCall();
RPCParameter param = mc.getParameters()[0];
RPCStruct struct = (RPCStruct) param.getValue();
double minx = (Double) struct.getMember( Constants.RPC_BBOXMINX ).getValue();
double miny = (Double) struct.getMember( Constants.RPC_BBOXMINY ).getValue();
double maxx = (Double) struct.getMember( Constants.RPC_BBOXMAXX ).getValue();
double maxy = (Double) struct.getMember( Constants.RPC_BBOXMAXY ).getValue();
String crs = struct.getMember( CRS ).getValue().toString();
CoordinateSystem cs;
try {
cs = CRSFactory.create( crs );
} catch ( UnknownCRSException e1 ) {
gotoErrorPage( e1.getMessage() );
return;
}
Envelope actualBBox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, cs );
double mapWidth = (Double) struct.getMember( MAP_WIDTH ).getValue();
double mapHeight = (Double) struct.getMember( MAP_HEIGHT ).getValue();
String taskFromJSObject = struct.getMember( JS_TAK ).getValue().toString();
ServletRequest request = this.getRequest();
try {
double actualScalValue = MapUtils.calcScale( (int) mapWidth, (int) mapHeight,
actualBBox,
actualBBox.getCoordinateSystem(),
PIXEL_SIZE );
if ( GET_NEW_BBOX.equals( taskFromJSObject ) ) {
String scaleRequestString = struct.getMember( REQUESTED_SCALE ).getValue().toString();
double requestedScale = Double.parseDouble( scaleRequestString.substring(
2,
scaleRequestString.length() ) );
double savedScaleValue = (Double) struct.getMember( SAVED_SCALE ).getValue();
Envelope newBbox = calcNewBBox( actualBBox, requestedScale, actualScalValue,
savedScaleValue );
double[] bbox = { newBbox.getMin().getX(), newBbox.getMin().getY(),
newBbox.getMax().getX(), newBbox.getMax().getY() };
Integer scaleValue = new Integer( (int) ( requestedScale ) );
request.setAttribute( SCALE_VALUE, scaleValue );
request.setAttribute( BBOX, bbox );
request.setAttribute( TASK_FROM_LISTENER, NEW_BBOX );
} else if ( GET_ACTUAL_SCALE.equals( taskFromJSObject ) ) {
Integer scaleValue = new Integer( (int) actualScalValue );
request.setAttribute( SCALE_VALUE, scaleValue );
request.setAttribute( TASK_FROM_LISTENER, NEW_SCALE_VALUE );
} else {
String message = "Unknown task from ScaleSwitcher module" + taskFromJSObject;
throw new PortalException( message );
}
} catch ( PortalException e ) {
request.setAttribute( TASK_FROM_LISTENER, FULL_EXTENT );
} catch ( Exception e ) {
e.printStackTrace();
}
LOG.exiting();
}
/**
* The methode <code>calcNewBBox</code> calculates a new boundingbox for a requested scale. It
* will either zoom in or zoom out of the <code>actualBBOX<code> depending
* on the ratio of the <code>requestedScale</code> to the <code>actualScale</code>
* @param actualBBOX
* @param crs
* @param requestedScale
* @return
*/
private Envelope calcNewBBox( Envelope actualBBOX, double requestedScale, double actualScale,
double savedScaleValue )
throws Exception {
LOG.entering();
Envelope newBBox = null;
double ratio = requestedScale / actualScale;
// NaN ration will return a null Envelope
if ( Double.isNaN( ratio ) ) {
// FIXME when does this occurs? and how should this be handle?
throw new PortalException( "ratio is not a number" );
}
if ( Double.isInfinite( ratio ) ) {// infinite ratio will return infinite Envelope
// the actualScale calculated was probably 0: use the saveScaleValue
if ( savedScaleValue > 1 ) {
ratio = requestedScale / savedScaleValue;
}
if ( Double.isInfinite( ratio ) ) {
throw new PortalException( "ratio is infinite" );
}
}
double newWidth = actualBBOX.getWidth() * ratio;
double newHeight = actualBBOX.getHeight() * ratio;
double midX = actualBBOX.getMin().getX() + ( actualBBOX.getWidth() / 2d );
double midY = actualBBOX.getMin().getY() + ( actualBBOX.getHeight() / 2d );
double minx = midX - newWidth / 2d;
double maxx = midX + newWidth / 2d;
double miny = midY - newHeight / 2d;
double maxy = midY + newHeight / 2d;
newBBox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy,
actualBBOX.getCoordinateSystem() );
LOG.exiting();
return newBBox;
}
}
/***************************************************************************************************
* Changes to this class. What the people have been up to: $$Log: ScaleSwitcherListener.java,v $
* Changes to this class. What the people have been up to: $Revision 1.14 2006/11/27 09:07:52 poth
* Changes to this class. What the people have been up to: $JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code.
* Changes to this class. What the people have been up to: $
* Changes to this class. What the people have been up to: $Revision 1.13 2006/10/17 20:31:17 poth
* Changes to this class. What the people have been up to: $*** empty log message ***
* Changes to this class. What the people have been up to: $
* Changes to this class. What the people have been up to: $Revision 1.12 2006/09/25 12:47:00 poth
* Changes to this class. What the people have been up to: $bug fixes - map scale calculation
* Changes to this class. What the people have been up to: $
* Changes to this class. What the people have been up to: $Revision 1.11 2006/08/24 06:43:39 poth
* Changes to this class. What the people have been up to: $File header corrected
* Changes to this class. What the people have been up to: $
* Changes to this class. What the people have been up to: $Revision 1.10 2006/08/16 14:01:36 ncho
* Changes to this class. What the people have been up to: $removed irrelevant parameters mapWidth and mapHeight from method signature of calcNewBBox
* Changes to this class. What the people have been up to: $
* $Revision 1.9 2006/08/10 15:36:56 ncho $refactored, added constants and properties file for pixel
* size value $$
**************************************************************************************************/