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 }