001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/portlet/modules/map/actions/portlets/MapWindowPortletPerform.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 package org.deegree.portal.portlet.modules.map.actions.portlets; 037 038 import java.net.MalformedURLException; 039 import java.net.URL; 040 import java.util.ArrayList; 041 import java.util.Arrays; 042 import java.util.List; 043 044 import javax.servlet.ServletContext; 045 import javax.servlet.http.HttpServletRequest; 046 047 import org.apache.jetspeed.portal.Portlet; 048 import org.apache.jetspeed.portal.PortletException; 049 import org.deegree.datatypes.QualifiedName; 050 import org.deegree.framework.log.ILogger; 051 import org.deegree.framework.log.LoggerFactory; 052 import org.deegree.framework.util.StringTools; 053 import org.deegree.model.spatialschema.Envelope; 054 import org.deegree.model.spatialschema.GeometryFactory; 055 import org.deegree.model.spatialschema.Point; 056 import org.deegree.portal.PortalException; 057 import org.deegree.portal.context.ContextException; 058 import org.deegree.portal.context.DefaultMapModelAccess; 059 import org.deegree.portal.context.Layer; 060 import org.deegree.portal.context.LayerList; 061 import org.deegree.portal.context.MapModelAccess; 062 import org.deegree.portal.context.Server; 063 import org.deegree.portal.context.ViewContext; 064 import org.deegree.portal.portlet.modules.actions.AbstractPortletPerform; 065 import org.deegree.portal.portlet.modules.actions.IGeoPortalPortletPerform; 066 067 /** 068 * 069 * 070 * @version $Revision: 18195 $ 071 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 072 * @author last edited by: $Author: mschneider $ 073 * 074 * @version 1.0. $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $ 075 * 076 * @since 2.0 077 */ 078 public class MapWindowPortletPerform extends IGeoPortalPortletPerform { 079 080 private static final ILogger LOG = LoggerFactory.getLogger( MapWindowPortletPerform.class ); 081 082 // init parameter of the portlet 083 static String INIT_INITAL_GETMAP = "initialGETMAP"; 084 085 static String INIT_PANBUTTONS = "panButtons"; 086 087 static String INIT_HOMEBBOX = "homeBoundingBox"; 088 089 static String INIT_SCALEMAPTOPORTLETSIZE = "scaleMapToPortletSize"; 090 091 static String INIT_FEATUREINFOTARGETPORTLET = "featureInfoTargetPortlet"; 092 093 // known request parameter 094 static String PARAM_WIDTH = "WIDTH"; 095 096 static String PARAM_HEIGHT = "HEIGHT"; 097 098 static String PARAM_CLICKPOINT = "CLICKPOINT"; 099 100 static String PARAM_MAPPOINT = "MAPPOINT"; 101 102 static String PARAM_FACTOR = "FACTOR"; 103 104 static String PARAM_PANDIRECTION = "DIRECTIONCODE"; 105 106 static String PARAM_CURRENTFILAYER = "CURRENTFILAYER"; 107 108 /** 109 * private constructor 110 * 111 * @param request 112 * @param portlet 113 */ 114 MapWindowPortletPerform( HttpServletRequest request, Portlet portlet, ServletContext sc ) { 115 super( request, portlet, sc ); 116 } 117 118 @Override 119 public void buildNormalContext() 120 throws PortalException { 121 super.buildNormalContext(); 122 init(); 123 setBoundingBoxFromBBOXParam(); 124 setMapWindowAttributes(); 125 ViewContext vc = getCurrentViewContext( portlet.getID() ); 126 setCurrentMapContext( vc, portlet.getID() ); 127 } 128 129 /** 130 * initializes the portlet by reading the assigned map context and storing it into the users 131 * session 132 * 133 * @throws PortletException 134 */ 135 private void init() { 136 137 List<Envelope> history = (List<Envelope>) request.getSession().getAttribute( SESSION_HISTORY ); 138 if ( history == null ) { 139 int maxHistorySize = 1000; 140 if ( getInitParam( "MaxHistorySize" ) != null ) { 141 maxHistorySize = Integer.parseInt( getInitParam( "MaxHistorySize" ) ); 142 } 143 history = new ArrayList<Envelope>( maxHistorySize ); 144 for ( int i = 0; i < maxHistorySize; i++ ) { 145 history.add( null ); 146 } 147 request.getSession().setAttribute( SESSION_HISTORY, history ); 148 request.getSession().setAttribute( SESSION_HISTORYPOSITION, 0 ); 149 } 150 151 } 152 153 /** 154 * writes the passed values into the attributes of the passed 155 * 156 * @see HttpServletRequest to be read by the JSP page assigned to the 157 * iGeoPortal:MapWindowPortlet 158 * 159 */ 160 private void setAttributes( ArrayList panButtons ) { 161 request.setAttribute( "PANBUTTONS", panButtons ); 162 request.setAttribute( "PORTLETID", portlet.getID() ); 163 request.setAttribute( "FEATUREINFOTARGETPORTLET", getInitParam( INIT_FEATUREINFOTARGETPORTLET ) ); 164 } 165 166 /** 167 * sets all request attributes required by a map from the passed ViewContext 168 * 169 * @param vc 170 */ 171 private void setMapWindowAttributes() { 172 173 String tmp = getInitParam( INIT_PANBUTTONS ); 174 ArrayList<String> pB = new ArrayList<String>( 20 ); 175 if ( tmp != null ) { 176 String[] panButtons = StringTools.toArray( tmp, ",;", true ); 177 List<String> list = Arrays.asList( panButtons ); 178 pB.addAll( list ); 179 } 180 181 setAttributes( pB ); 182 } 183 184 /** 185 * sets a new bounding box of the map read from the the request object passed when initialized 186 * an instance of <code>MapWindowPortletPerfom</code> 187 */ 188 void setHomeBoundingbox() { 189 190 Envelope env = (Envelope) request.getSession().getAttribute( AbstractPortletPerform.SESSION_HOME ); 191 setBoundingBox( env ); 192 193 } 194 195 /** 196 * sets a new size of the map read from the request 197 * 198 * @throws PortalException 199 */ 200 void setMapSize() 201 throws PortalException { 202 String tmp = parameter.get( PARAM_WIDTH ); 203 if ( tmp == null ) { 204 throw new PortalException( "request does not contain a WIDTH parameter!" ); 205 } 206 int width = Integer.parseInt( tmp ); 207 208 tmp = request.getParameter( PARAM_HEIGHT ); 209 if ( tmp == null ) { 210 throw new PortalException( "request does not contain a HEIGHT parameter!" ); 211 } 212 int height = Integer.parseInt( tmp ); 213 214 ViewContext vc = getCurrentViewContext( portlet.getID() ); 215 MapModelAccess mma = new DefaultMapModelAccess( vc ); 216 vc = mma.setMapSize( width, height ); 217 // if the request contains a BBOX parameter the current bounding box 218 // will be updated too 219 setBoundingBox( parameter.get( PARAM_BBOX ) ); 220 setCurrentMapContext( vc, portlet.getID() ); 221 } 222 223 /** 224 * zooms the current map by a factor and recenters it to the point the user has clicked to. 225 * 226 * @throws PortalException 227 * @throws ContextException 228 */ 229 void zoom() 230 throws PortalException, ContextException { 231 232 ViewContext vc = getCurrentViewContext( portlet.getID() ); 233 MapModelAccess mma = new DefaultMapModelAccess( vc ); 234 235 String tmp = parameter.get( PARAM_FACTOR ); 236 if ( tmp == null ) { 237 throw new PortalException( "FACTOR must be set for zoom operation!" ); 238 } 239 double factor = Double.parseDouble( tmp ); 240 241 tmp = parameter.get( PARAM_CLICKPOINT ); 242 if ( tmp != null ) { 243 // zoom by pixel coordinates 244 double coords[] = StringTools.toArrayDouble( tmp, "," ); 245 java.awt.Point point = new java.awt.Point( (int) coords[0], (int) coords[1] ); 246 vc = mma.zoom( point, factor ); 247 } else { 248 // zoom by map coordinates 249 tmp = parameter.get( PARAM_MAPPOINT ); 250 if ( tmp == null ) { 251 throw new PortalException( "at least a CLICKPOINT or a MAPPOINT must be defined for zoom operation!" ); 252 } 253 double coords[] = StringTools.toArrayDouble( tmp, "," ); 254 Point point = GeometryFactory.createPoint( coords[0], coords[1], null ); 255 vc = mma.zoom( point, factor ); 256 } 257 setCurrentMapContext( vc, portlet.getID() ); 258 } 259 260 /** 261 * pan the map with a set factor to one of eight possible directions 262 * 263 * @throws PortalException 264 * @throws ContextException 265 */ 266 void pan() 267 throws PortalException, ContextException { 268 269 String tmp = parameter.get( PARAM_FACTOR ); 270 if ( tmp == null ) { 271 throw new PortalException( "FACTOR must be set for pan operation!" ); 272 } 273 double factor = Double.parseDouble( tmp ); 274 275 tmp = parameter.get( PARAM_PANDIRECTION ); 276 if ( tmp == null ) { 277 throw new PortalException( "DIRECTION must be set for pan operation!" ); 278 } 279 boolean isnumber = true; 280 try { 281 Double.parseDouble( tmp ); 282 } catch ( Exception e ) { 283 isnumber = false; 284 } 285 286 ViewContext vc = getCurrentViewContext( portlet.getID() ); 287 MapModelAccess mma = new DefaultMapModelAccess( vc ); 288 if ( isnumber ) { 289 // use value as direction in degree 290 vc = mma.pan( Double.parseDouble( tmp ), factor ); 291 } else { 292 int dir = 0; 293 if ( tmp.equals( "N" ) ) { 294 dir = MapModelAccess.PAN_NORTH; 295 } else if ( tmp.equals( "NW" ) ) { 296 dir = MapModelAccess.PAN_NORTHWEST; 297 } else if ( tmp.equals( "NE" ) ) { 298 dir = MapModelAccess.PAN_NORTHEAST; 299 } else if ( tmp.equals( "W" ) ) { 300 dir = MapModelAccess.PAN_WEST; 301 } else if ( tmp.equals( "E" ) ) { 302 dir = MapModelAccess.PAN_EAST; 303 } else if ( tmp.equals( "SW" ) ) { 304 dir = MapModelAccess.PAN_SOUTHWEST; 305 } else if ( tmp.equals( "S" ) ) { 306 dir = MapModelAccess.PAN_SOUTH; 307 } else if ( tmp.equals( "SE" ) ) { 308 dir = MapModelAccess.PAN_SOUTHEAST; 309 } else { 310 throw new PortalException( "unknown pan direction: " + tmp ); 311 } 312 vc = mma.pan( dir, factor ); 313 } 314 setCurrentMapContext( vc, portlet.getID() ); 315 } 316 317 /** 318 * recenters the current map to the point the user has clicked to 319 * 320 * @throws PortalException 321 * @throws ContextException 322 */ 323 void recenter() 324 throws PortalException, ContextException { 325 326 ViewContext vc = getCurrentViewContext( portlet.getID() ); 327 MapModelAccess mma = new DefaultMapModelAccess( vc ); 328 329 String tmp = parameter.get( PARAM_CLICKPOINT ); 330 if ( tmp != null ) { 331 // zoom by pixel coordinates 332 double coords[] = StringTools.toArrayDouble( tmp, "," ); 333 java.awt.Point point = new java.awt.Point( (int) coords[0], (int) coords[1] ); 334 vc = mma.recenterMap( point ); 335 } else { 336 // zoom by map coordinates 337 tmp = parameter.get( PARAM_MAPPOINT ); 338 if ( tmp == null ) { 339 throw new PortalException( "at least a CLICKPOINT or a MAPPOINT " 340 + "must be defined for zoom operation!" ); 341 } 342 double coords[] = StringTools.toArrayDouble( tmp, "," ); 343 Point point = GeometryFactory.createPoint( coords[0], coords[1], null ); 344 vc = mma.recenterMap( point ); 345 } 346 setCurrentMapContext( vc, portlet.getID() ); 347 } 348 349 /** 350 * sets the name of the the layers that are activated for feature info requests in the uses WMC 351 */ 352 void setCurrentFILayer() { 353 String tmp = parameter.get( PARAM_CURRENTFILAYER ); 354 String[] fiLayer = StringTools.toArray( tmp, ",", false ); 355 if ( fiLayer != null ) { 356 List<String> list = Arrays.asList( fiLayer ); 357 list = new ArrayList<String>( list ); 358 359 ViewContext vc = getCurrentViewContext( portlet.getID() ); 360 LayerList layerList = vc.getLayerList(); 361 Layer[] layers = layerList.getLayers(); 362 for ( int i = 0; i < layers.length; i++ ) { 363 try { 364 if ( list.contains( layers[i].getName() ) ) { 365 layers[i].getExtension().setSelectedForQuery( true ); 366 } else { 367 layers[i].getExtension().setSelectedForQuery( false ); 368 } 369 } catch ( Exception e ) { 370 // TODO: handle exception 371 LOG.logError( e.getMessage(), e ); 372 } 373 } 374 } 375 } 376 377 /** 378 * moves the layer passed through by the HTTP request up for one position 379 * 380 * @throws PortalException 381 */ 382 void moveUp() 383 throws PortalException { 384 385 ViewContext vc = getCurrentViewContext( portlet.getID() ); 386 387 String tmp = parameter.get( PARAM_LAYER ); 388 String[] s = StringTools.toArray( tmp, "|", false ); 389 LOG.logDebug( StringTools.concat( 150, "moving layer: ", s[0], " map model: ", portlet.getID(), " up" ) ); 390 MapModelAccess mma = new DefaultMapModelAccess( vc ); 391 try { 392 vc = mma.swapLayers( new QualifiedName( null, s[0], null ), new URL( s[1] ), "OGC:WMS", true ); 393 } catch ( MalformedURLException e ) { 394 throw new PortalException( "no valid URL", e ); 395 } 396 setCurrentMapContext( vc, portlet.getID() ); 397 } 398 399 /** 400 * moves the layer passed through by the HTTP request down for one position 401 * 402 * @throws PortalException 403 */ 404 void moveDown() 405 throws PortalException { 406 407 ViewContext vc = getCurrentViewContext( portlet.getID() ); 408 String tmp = parameter.get( PARAM_LAYER ); 409 String[] s = StringTools.toArray( tmp, "|", false ); 410 LOG.logDebug( StringTools.concat( 150, "moving layer: ", s[0], " map model: ", portlet.getID(), " down" ) ); 411 MapModelAccess mma = new DefaultMapModelAccess( vc ); 412 try { 413 vc = mma.swapLayers( new QualifiedName( null, s[0], null ), new URL( s[1] ), "OGC:WMS", false ); 414 } catch ( MalformedURLException e ) { 415 throw new PortalException( "no valid URL", e ); 416 } 417 setCurrentMapContext( vc, portlet.getID() ); 418 } 419 420 /** 421 * move the map view (just bounding box) to the next entry in the history 422 */ 423 void doHistoryforward() { 424 List<Envelope> history = (List<Envelope>) request.getSession().getAttribute( SESSION_HISTORY ); 425 int p = (Integer) request.getSession().getAttribute( SESSION_HISTORYPOSITION ); 426 if ( p < history.size() - 1 ) { 427 Envelope env = history.get( ++p ); 428 if ( env != null ) { 429 LOG.logDebug( "Stepping forward in history to position: " + ( p + 1 ) ); 430 setBoundingBox( env ); 431 request.getSession().setAttribute( SESSION_HISTORYPOSITION, p ); 432 } else { 433 LOG.logDebug( "No envelope found at position: " + ( p + 1 ) ); 434 } 435 436 } 437 } 438 439 /** 440 * move the map view (just bounding box) to the previous entry in the history 441 */ 442 void doHistorybackward() { 443 List<Envelope> history = (List<Envelope>) request.getSession().getAttribute( SESSION_HISTORY ); 444 int p = (Integer) request.getSession().getAttribute( SESSION_HISTORYPOSITION ); 445 if ( p > 0 ) { 446 Envelope env = history.get( --p ); 447 if ( env != null ) { 448 LOG.logDebug( "Stepping backward in history to position: " + ( p - 1 ) ); 449 setBoundingBox( env ); 450 request.getSession().setAttribute( SESSION_HISTORYPOSITION, p ); 451 } else { 452 LOG.logDebug( "No envelope found at position: " + ( p - 1 ) ); 453 } 454 } 455 } 456 457 /** 458 * adds a new OWS to one of the WMC available a MapWindow TODO 459 */ 460 void doAddows() { 461 System.out.println( parameter ); 462 ViewContext vc = getCurrentViewContext( portlet.getID() ); 463 Layer layer = vc.getLayerList().getLayers()[0]; 464 parameter.get( "FORMAT" ); 465 // TODO 466 } 467 468 /** 469 * removes an OWS from a MapWindow 470 * 471 */ 472 void doRemoveows() { 473 System.out.println( parameter ); 474 String title = parameter.get( "TITLE" ); 475 ViewContext vc = getCurrentViewContext( portlet.getID() ); 476 Layer[] layers = vc.getLayerList().getLayers(); 477 for ( int i = 0; i < layers.length; i++ ) { 478 Server server = layers[i].getServer(); 479 if ( server.getTitle().equals( title ) ) { 480 vc.getLayerList().removeLayer( layers[i].getName() ); 481 } 482 } 483 } 484 485 }