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