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 }