001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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 }