001 /*---------------------------------------------------------------------------- 002 This file is part of BfS WPS WebApplication project 003 004 Contact information: 005 006 lat/lon GmbH 007 Aennchenstr. 19, 53177 Bonn 008 Germany 009 http://lat-lon.de/ 010 011 ----------------------------------------------------------------------------*/ 012 package org.deegree.enterprise.servlet; 013 014 import java.awt.BasicStroke; 015 import java.awt.Color; 016 import java.awt.Graphics; 017 import java.awt.Graphics2D; 018 import java.awt.Rectangle; 019 import java.awt.TexturePaint; 020 import java.awt.geom.GeneralPath; 021 import java.awt.image.BufferedImage; 022 import java.io.File; 023 import java.io.IOException; 024 import java.io.InputStream; 025 import java.io.OutputStream; 026 import java.io.PrintWriter; 027 import java.net.URL; 028 import java.util.Map; 029 import java.util.Properties; 030 031 import javax.servlet.ServletException; 032 import javax.servlet.http.HttpServlet; 033 import javax.servlet.http.HttpServletRequest; 034 import javax.servlet.http.HttpServletResponse; 035 import javax.servlet.http.HttpSession; 036 037 import org.deegree.framework.log.ILogger; 038 import org.deegree.framework.log.LoggerFactory; 039 import org.deegree.framework.util.GeometryUtils; 040 import org.deegree.framework.util.ImageUtils; 041 import org.deegree.framework.util.KVP2Map; 042 import org.deegree.framework.util.StringTools; 043 import org.deegree.graphics.transformation.GeoTransform; 044 import org.deegree.graphics.transformation.WorldToScreenTransform; 045 import org.deegree.model.spatialschema.Curve; 046 import org.deegree.model.spatialschema.Envelope; 047 import org.deegree.model.spatialschema.Geometry; 048 import org.deegree.model.spatialschema.GeometryException; 049 import org.deegree.model.spatialschema.MultiPrimitive; 050 import org.deegree.model.spatialschema.Point; 051 import org.deegree.model.spatialschema.Position; 052 import org.deegree.model.spatialschema.Surface; 053 import org.deegree.model.spatialschema.SurfacePatch; 054 import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic; 055 import org.deegree.ogcwebservices.wms.operation.GetMap; 056 057 /** 058 * This servlet realizes a OGC:WMS that just offers one layer ('highlight') reading a geometry form session of 059 * requesting user. The geometry to be painted must be stored in a session attribute named 'TEMP_WMS_GEOMETRY'. 060 * Following init parameters ars upported: 061 * <ul> 062 * <li>FILL: fill color for polygons (optional) 063 * <li>STROKE: stroke color for lines (optional) 064 * <li>PATTERN: fill pattern/image for polygon (if available FILL will be ignored) (optional) 065 * <li>SYMBOL: symbol image for points (optional) 066 * </ul> 067 * 068 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 069 * 070 * @author last edited by: $Author: apoth $ 071 * 072 * @version $Revision: 30359 $, $Date: 2011-04-04 21:23:10 +0200 (Mon, 04 Apr 2011) $ 073 * 074 */ 075 public class SessionWMS extends HttpServlet { 076 077 private static final long serialVersionUID = 7263960291096038482L; 078 079 private static final ILogger LOG = LoggerFactory.getLogger( SessionWMS.class ); 080 081 private static Color fillColor = new Color( 1f, 1f, 1f, 0.5f ); 082 083 private static Color lineColor = Color.BLACK; 084 085 private static float polyStrokeWidth = 1; 086 087 private static float strokeStrokeWidth = 1; 088 089 private static BufferedImage fillPattern; 090 091 private static BufferedImage symbol; 092 093 private static String capa; 094 095 @Override 096 public void init() 097 throws ServletException { 098 // TODO Auto-generated method stub 099 super.init(); 100 if ( getInitParameter( "FILL" ) != null ) { 101 fillColor = Color.decode( getInitParameter( "FILL" ) ); 102 } 103 if ( getInitParameter( "STROKE" ) != null ) { 104 lineColor = Color.decode( getInitParameter( "STROKE" ) ); 105 } 106 if ( getInitParameter( "STROKEWIDTH" ) != null ) { 107 strokeStrokeWidth = Float.parseFloat( getInitParameter( "STROKEWIDTH" ) ); 108 } 109 if ( getInitParameter( "FILLSTROKEWIDTH" ) != null ) { 110 polyStrokeWidth = Float.parseFloat( getInitParameter( "FILLSTROKEWIDTH" ) ); 111 } 112 if ( getInitParameter( "PATTERN" ) != null ) { 113 File pattern = new File( getInitParameter( "PATTERN" ) ); 114 if ( !pattern.isAbsolute() ) { 115 String s = getServletContext().getRealPath( getInitParameter( "PATTERN" ) ); 116 pattern = new File( s ); 117 } 118 try { 119 fillPattern = ImageUtils.loadImage( pattern ); 120 } catch ( IOException e ) { 121 LOG.logError( e ); 122 throw new ServletException( e ); 123 } 124 } 125 if ( getInitParameter( "SYMBOL" ) != null ) { 126 File pattern = new File( getInitParameter( "SYMBOL" ) ); 127 if ( !pattern.isAbsolute() ) { 128 String s = getServletContext().getRealPath( getInitParameter( "SYMBOL" ) ); 129 pattern = new File( s ); 130 } 131 try { 132 symbol = ImageUtils.loadImage( pattern ); 133 } catch ( IOException e ) { 134 LOG.logError( e ); 135 throw new ServletException( e ); 136 } 137 } else { 138 symbol = new BufferedImage( 9, 9, BufferedImage.TYPE_INT_ARGB ); 139 Graphics g = symbol.getGraphics(); 140 g.setColor( Color.RED ); 141 g.fillOval( 0, 0, 9, 9 ); 142 g.dispose(); 143 } 144 Properties prop = new Properties(); 145 InputStream is = SessionWMS.class.getResourceAsStream( "session-wms.properties" ); 146 try { 147 prop.load( is ); 148 is.close(); 149 } catch ( IOException e ) { 150 LOG.logError( e ); 151 throw new ServletException( e ); 152 } 153 capa = prop.getProperty( "capabilities" ); 154 155 } 156 157 @Override 158 protected void doGet( HttpServletRequest req, HttpServletResponse resp ) 159 throws ServletException, IOException { 160 Map<String, String> param = KVP2Map.toMap( req ); 161 param.put( "ID", "1" ); 162 resp.setHeader( "Cache-Control", "no-cache, no-store" ); 163 resp.setHeader( "Pragma", "no-cache" ); 164 165 if ( "GetCapabilities".equals( param.get( "REQUEST" ) ) ) { 166 PrintWriter pw = resp.getWriter(); 167 String s = StringTools.replace( capa, "§URL§", req.getRequestURL().toString(), true ); 168 pw.write( s ); 169 pw.close(); 170 } else if ( "GetMap".equals( param.get( "REQUEST" ) ) ) { 171 getMap( req, resp, param ); 172 } else if ( "GetLegendGraphic".equals( param.get( "REQUEST" ) ) ) { 173 getLegendGraphic( req, resp, param ); 174 } 175 176 } 177 178 private void getMap( HttpServletRequest req, HttpServletResponse resp, Map<String, String> param ) { 179 try { 180 GetMap getMap = GetMap.create( param ); 181 HttpSession session = req.getSession(); 182 Geometry geometry = (Geometry) session.getAttribute( "TEMP_WMS_GEOMETRY" ); 183 if ( geometry != null ) { 184 BufferedImage bi = new BufferedImage( getMap.getWidth(), getMap.getHeight(), 185 BufferedImage.TYPE_INT_ARGB ); 186 // set background to white 187 Graphics g = bi.getGraphics(); 188 g.setColor( new Color( 0, 0, 0, 0f ) ); 189 g.fillRect( 0, 0, bi.getWidth(), bi.getHeight() ); 190 191 Envelope bbox = getMap.getBoundingBox(); 192 GeoTransform gt = new WorldToScreenTransform( bbox.getMin().getX(), bbox.getMin().getY(), 193 bbox.getMax().getX(), bbox.getMax().getY(), 0, 0, 194 getMap.getWidth() - 1, getMap.getHeight() - 1 ); 195 if ( geometry instanceof MultiPrimitive ) { 196 Geometry[] geometries = ( (MultiPrimitive) geometry ).getAll(); 197 for ( Geometry geom : geometries ) { 198 drawGeometry( geom, (Graphics2D) g, gt ); 199 } 200 } else { 201 drawGeometry( geometry, (Graphics2D) g, gt ); 202 } 203 204 g.dispose(); 205 resp.setContentType( getMap.getFormat() ); 206 int idx = getMap.getFormat().lastIndexOf( "/" ); 207 OutputStream os = resp.getOutputStream(); 208 ImageUtils.saveImage( bi, resp.getOutputStream(), getMap.getFormat().substring( idx + 1 ), 0.99f ); 209 os.flush(); 210 os.close(); 211 } 212 } catch ( Exception e ) { 213 LOG.logError( e ); 214 } 215 } 216 217 private void drawGeometry( Geometry geometry, Graphics2D g, GeoTransform gt ) 218 throws GeometryException { 219 if ( geometry instanceof Point ) { 220 int x = (int) Math.round( gt.getDestX( ( (Point) geometry ).getX() ) ); 221 int y = (int) Math.round( gt.getDestY( ( (Point) geometry ).getY() ) ); 222 x += symbol.getWidth() / 2 + 1; 223 y += symbol.getHeight() / 2 + 1; 224 g.drawImage( symbol, x, y, null ); 225 } else if ( geometry instanceof Curve ) { 226 GeneralPath path = createPath( (Curve) geometry, gt ); 227 g.setColor( lineColor ); 228 g.setStroke( new BasicStroke( strokeStrokeWidth ) ); 229 g.draw( path ); 230 } else if ( geometry instanceof Surface ) { 231 GeneralPath path = createPath( (Surface) geometry, gt ); 232 if ( fillColor != null && fillPattern == null ) { 233 g.setColor( fillColor ); 234 } else { 235 Rectangle anchor = new Rectangle( 0, 0, fillPattern.getWidth(), fillPattern.getHeight() ); 236 ( (Graphics2D) g ).setPaint( new TexturePaint( fillPattern, anchor ) ); 237 } 238 g.fill( path ); 239 if ( lineColor != null ) { 240 g.setStroke( new BasicStroke( polyStrokeWidth ) ); 241 g.setColor( lineColor ); 242 g.draw( path ); 243 } 244 } 245 } 246 247 private GeneralPath createPath( Curve curve, GeoTransform gt ) 248 throws GeometryException { 249 250 GeneralPath path = new GeneralPath(); 251 252 Position[] pos = curve.getAsLineString().getPositions(); 253 appendPositionsToPath( path, pos, gt ); 254 255 return path; 256 } 257 258 private GeneralPath createPath( Surface surface, GeoTransform gt ) { 259 260 GeneralPath path = new GeneralPath(); 261 262 SurfacePatch patch = null; 263 try { 264 patch = surface.getSurfacePatchAt( 0 ); 265 } catch ( GeometryException e ) { 266 LOG.logError( e.getMessage(), e ); 267 } 268 appendPositionsToPath( path, patch.getExteriorRing(), gt ); 269 270 Position[][] inner = patch.getInteriorRings(); 271 if ( inner != null ) { 272 for ( int i = 0; i < inner.length; i++ ) { 273 appendPositionsToPath( path, inner[i], gt ); 274 } 275 } 276 277 return path; 278 } 279 280 private void appendPositionsToPath( GeneralPath path, Position[] pos, GeoTransform gt ) { 281 282 Position p = gt.getDestPoint( pos[0] ); 283 float xx = (float) p.getX(); 284 float yy = (float) p.getY(); 285 path.moveTo( xx, yy ); 286 for ( int i = 1; i < pos.length; i++ ) { 287 p = gt.getDestPoint( pos[i] ); 288 float xx_ = (float) p.getX(); 289 float yy_ = (float) p.getY(); 290 if ( GeometryUtils.distance( xx, yy, xx_, yy_ ) > 5 || i == pos.length - 1 ) { 291 path.lineTo( xx_, yy_ ); 292 xx = xx_; 293 yy = yy_; 294 } 295 } 296 297 } 298 299 /** 300 * 301 * @param req 302 * @param resp 303 * @param param 304 */ 305 @SuppressWarnings("unchecked") 306 private void getLegendGraphic( HttpServletRequest req, HttpServletResponse resp, Map<String, String> param ) { 307 try { 308 GetLegendGraphic getLegendGraphic = GetLegendGraphic.create( param ); 309 HttpSession session = req.getSession(); 310 Map<String, String> imageURLs = (Map<String, String>) session.getAttribute( "legendURLs" ); 311 BufferedImage bi = null; 312 String layer = getLegendGraphic.getLayer(); 313 if ( imageURLs != null && imageURLs.get( layer ) != null ) { 314 String s = imageURLs.get( layer ); 315 bi = ImageUtils.loadImage( new URL( s ) ); 316 resp.setContentType( getLegendGraphic.getFormat() ); 317 int idx = getLegendGraphic.getFormat().lastIndexOf( "/" ); 318 ImageUtils.saveImage( bi, resp.getOutputStream(), getLegendGraphic.getFormat().substring( idx + 1 ), 319 0.99f ); 320 } else { 321 if ( "image/png".equals( getLegendGraphic.getFormat() ) 322 || "image/gif".equals( getLegendGraphic.getFormat() ) ) { 323 bi = new BufferedImage( 100, 100, BufferedImage.TYPE_INT_ARGB ); 324 } else { 325 bi = new BufferedImage( 100, 100, BufferedImage.TYPE_INT_RGB ); 326 } 327 // set background to white and draw error message 328 Graphics g = bi.getGraphics(); 329 g.setColor( Color.WHITE ); 330 g.fillRect( 0, 0, bi.getWidth(), bi.getHeight() ); 331 g.setColor( Color.RED ); 332 g.drawString( "no legend symbol", 10, 10 ); 333 g.drawString( "available for layer:", 10, 40 ); 334 g.drawString( layer, 10, 70 ); 335 g.dispose(); 336 } 337 resp.setContentType( getLegendGraphic.getFormat() ); 338 int idx = getLegendGraphic.getFormat().lastIndexOf( "/" ); 339 OutputStream os = resp.getOutputStream(); 340 ImageUtils.saveImage( bi, os, getLegendGraphic.getFormat().substring( idx + 1 ), 0.99f ); 341 os.flush(); 342 os.close(); 343 } catch ( Exception e ) { 344 e.printStackTrace(); 345 } 346 } 347 348 @Override 349 protected void doPost( HttpServletRequest req, HttpServletResponse resp ) 350 throws ServletException, IOException { 351 super.doGet( req, resp ); 352 } 353 354 }