001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wms/GetMapServiceInvokerForNL.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2008 by:
006 EXSE, Department of Geography, University of Bonn
007 http://www.giub.uni-bonn.de/deegree/
008 lat/lon GmbH
009 http://www.lat-lon.de
010
011 This library is free software; you can redistribute it and/or
012 modify it under the terms of the GNU Lesser General Public
013 License as published by the Free Software Foundation; either
014 version 2.1 of the License, or (at your option) any later version.
015
016 This library is distributed in the hope that it will be useful,
017 but WITHOUT ANY WARRANTY; without even the implied warranty of
018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019 Lesser General Public License for more details.
020
021 You should have received a copy of the GNU Lesser General Public
022 License along with this library; if not, write to the Free Software
023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024
025 Contact:
026
027 Andreas Poth
028 lat/lon GmbH
029 Aennchenstr. 19
030 53177 Bonn
031 Germany
032 E-Mail: poth@lat-lon.de
033
034 Prof. Dr. Klaus Greve
035 Department of Geography
036 University of Bonn
037 Meckenheimer Allee 166
038 53115 Bonn
039 Germany
040 E-Mail: greve@giub.uni-bonn.de
041
042 ---------------------------------------------------------------------------*/
043 package org.deegree.ogcwebservices.wms;
044
045 import java.awt.Color;
046 import java.awt.Graphics;
047 import java.awt.image.BufferedImage;
048 import java.io.StringReader;
049 import java.net.URI;
050 import java.util.ArrayList;
051 import java.util.Iterator;
052 import java.util.List;
053 import java.util.Map;
054 import java.util.concurrent.Callable;
055 import java.util.concurrent.CancellationException;
056
057 import org.deegree.datatypes.QualifiedName;
058 import org.deegree.datatypes.Types;
059 import org.deegree.framework.concurrent.DoServiceTask;
060 import org.deegree.framework.concurrent.Executor;
061 import org.deegree.framework.log.ILogger;
062 import org.deegree.framework.log.LoggerFactory;
063 import org.deegree.framework.util.CharsetUtils;
064 import org.deegree.framework.util.IDGenerator;
065 import org.deegree.framework.xml.XMLFragment;
066 import org.deegree.framework.xml.XMLTools;
067 import org.deegree.graphics.MapFactory;
068 import org.deegree.graphics.Theme;
069 import org.deegree.graphics.sld.NamedLayer;
070 import org.deegree.graphics.sld.StyleUtils;
071 import org.deegree.graphics.sld.UserStyle;
072 import org.deegree.i18n.Messages;
073 import org.deegree.model.coverage.grid.GridCoverage;
074 import org.deegree.model.coverage.grid.ImageGridCoverage;
075 import org.deegree.model.crs.CRSFactory;
076 import org.deegree.model.crs.CRSTransformationException;
077 import org.deegree.model.crs.GeoTransformer;
078 import org.deegree.model.crs.UnknownCRSException;
079 import org.deegree.model.feature.Feature;
080 import org.deegree.model.feature.FeatureCollection;
081 import org.deegree.model.feature.FeatureProperty;
082 import org.deegree.model.feature.schema.FeatureType;
083 import org.deegree.model.feature.schema.PropertyType;
084 import org.deegree.model.filterencoding.ComplexFilter;
085 import org.deegree.model.filterencoding.FeatureFilter;
086 import org.deegree.model.filterencoding.FeatureId;
087 import org.deegree.model.filterencoding.Filter;
088 import org.deegree.model.spatialschema.Envelope;
089 import org.deegree.model.spatialschema.GMLGeometryAdapter;
090 import org.deegree.model.spatialschema.Geometry;
091 import org.deegree.model.spatialschema.GeometryException;
092 import org.deegree.model.spatialschema.WKTAdapter;
093 import org.deegree.ogcbase.PropertyPath;
094 import org.deegree.ogcbase.PropertyPathFactory;
095 import org.deegree.ogcwebservices.InconsistentRequestException;
096 import org.deegree.ogcwebservices.OGCWebService;
097 import org.deegree.ogcwebservices.OGCWebServiceException;
098 import org.deegree.ogcwebservices.OGCWebServiceRequest;
099 import org.deegree.ogcwebservices.wcs.WCSException;
100 import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage;
101 import org.deegree.ogcwebservices.wcs.getcoverage.ResultCoverage;
102 import org.deegree.ogcwebservices.wfs.RemoteWFService;
103 import org.deegree.ogcwebservices.wfs.WFService;
104 import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
105 import org.deegree.ogcwebservices.wfs.capabilities.WFSFeatureType;
106 import org.deegree.ogcwebservices.wfs.operation.FeatureResult;
107 import org.deegree.ogcwebservices.wfs.operation.GetFeature;
108 import org.deegree.ogcwebservices.wfs.operation.Query;
109 import org.deegree.ogcwebservices.wms.configuration.AbstractDataSource;
110 import org.deegree.ogcwebservices.wms.configuration.LocalWCSDataSource;
111 import org.deegree.ogcwebservices.wms.configuration.LocalWFSDataSource;
112 import org.deegree.ogcwebservices.wms.configuration.RemoteWMSDataSource;
113 import org.deegree.ogcwebservices.wms.operation.GetMap;
114 import org.deegree.ogcwebservices.wms.operation.GetMapResult;
115 import org.w3c.dom.Document;
116
117 /**
118 * Class for accessing the data of one layers datasource and creating a <tt>Theme</tt> from it.
119 *
120 * @version $Revision: 14370 $
121 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
122 * @author last edited by: $Author: aschmitz $
123 *
124 * @version 1.0. $Revision: 14370 $, $Date: 2008-10-21 16:32:54 +0200 (Di, 21. Okt 2008) $
125 *
126 * @since 2.0
127 */
128 public class GetMapServiceInvokerForNL extends GetMapServiceInvoker implements Callable<Object> {
129
130 private static final ILogger LOG = LoggerFactory.getLogger( GetMapServiceInvokerForNL.class );
131
132 private final GetMap request;
133
134 private NamedLayer layer = null;
135
136 private UserStyle style = null;
137
138 private AbstractDataSource datasource = null;
139
140 /**
141 * Creates a new ServiceInvokerForNL object.
142 *
143 * @param handler
144 * @param layer
145 * @param datasource
146 * @param style
147 * @param index
148 */
149 GetMapServiceInvokerForNL( DefaultGetMapHandler handler, NamedLayer layer, AbstractDataSource datasource,
150 UserStyle style, double scale ) {
151
152 super( handler, scale );
153
154 this.layer = layer;
155 this.request = handler.getRequest();
156 this.style = style;
157 this.datasource = datasource;
158 }
159
160 public Object call() {
161
162 Object response = null;
163 if ( datasource != null ) {
164 OGCWebServiceRequest request = null;
165 try {
166 int type = datasource.getType();
167 switch ( type ) {
168 case AbstractDataSource.LOCALWFS:
169 case AbstractDataSource.REMOTEWFS: {
170 request = createGetFeatureRequest( (LocalWFSDataSource) datasource );
171 break;
172 }
173 case AbstractDataSource.LOCALWCS:
174 case AbstractDataSource.REMOTEWCS: {
175 request = createGetCoverageRequest( datasource, this.request );
176 break;
177 }
178 case AbstractDataSource.REMOTEWMS: {
179 String styleName = null;
180
181 if ( style != null ) {
182 styleName = style.getName();
183 }
184
185 request = GetMap.createGetMapRequest( datasource, handler.getRequest(), styleName, layer.getName() );
186 LOG.logDebug( "GetMap request: " + request.toString() );
187 break;
188 }
189 }
190 } catch ( Exception e ) {
191 e.printStackTrace();
192 OGCWebServiceException exce = new OGCWebServiceException( getClass().getName(),
193 Messages.getMessage( "WMS_ERRORQUERYCREATE",
194 e ) );
195 // exception can't be re-thrown because responsible GetMapHandler
196 // must collect all responses of all datasources
197 response = exce;
198 LOG.logError( e.getMessage(), e );
199 }
200
201 try {
202 // start reading data with a limited time frame. The time limit
203 // readed from the datasource muts be multiplied by 1000 because
204 // the method expects milliseconds as timelimit
205 Executor executor = Executor.getInstance();
206 DoServiceTask<Object> task = new DoServiceTask<Object>( datasource.getOGCWebService(), request );
207 Object o = executor.performSynchronously( task, datasource.getRequestTimeLimit() * 1000 );
208 response = handleResponse( o );
209 } catch ( CancellationException e ) {
210 // exception can't be re-thrown because responsible GetMapHandler
211 // must collect all responses of all datasources
212 String s = Messages.getMessage( "WMS_TIMEOUTDATASOURCE", new Integer( datasource.getRequestTimeLimit() ) );
213 LOG.logError( s, e );
214 if ( datasource.isFailOnException() ) {
215 OGCWebServiceException exce = new OGCWebServiceException( getClass().getName(), s );
216 response = exce;
217 } else {
218 response = null;
219 }
220 } catch ( Throwable e ) {
221 // exception can't be re-thrown because responsible GetMapHandler
222 // must collect all responses of all datasources
223 String s = Messages.getMessage( "WMS_ERRORDOSERVICE", e.getMessage() );
224 LOG.logError( s, e );
225 if ( datasource.isFailOnException() ) {
226 OGCWebServiceException exce = new OGCWebServiceException( getClass().getName(), s );
227 response = exce;
228 } else {
229 response = null;
230 }
231 }
232 }
233
234 LOG.logDebug( "Layer " + layer.getName() + " returned." );
235
236 return response;
237 }
238
239 /**
240 * creates a getFeature request considering the getMap request and the filterconditions defined in the submitted
241 * <tt>DataSource</tt> object. The request will be encapsualted within a <tt>OGCWebServiceEvent</tt>.
242 *
243 * @param ds
244 * @return GetFeature request object
245 * @throws Exception
246 */
247 private GetFeature createGetFeatureRequest( LocalWFSDataSource ds )
248 throws Exception {
249
250 Envelope bbox = transformBBOX( ds );
251
252 List<PropertyPath> pp = null;
253 if ( style != null ) {
254 List<UserStyle> styleList = new ArrayList<UserStyle>();
255 styleList.add( style );
256 pp = StyleUtils.extractRequiredProperties( styleList, scaleDen );
257 } else {
258 pp = new ArrayList<PropertyPath>();
259 }
260 PropertyPath geomPP = PropertyPathFactory.createPropertyPath( ds.getGeometryProperty() );
261 if ( !pp.contains( geomPP ) ) {
262 pp.add( geomPP );
263 }
264
265 LOG.logDebug( "required properties: ", pp );
266 Map<String, URI> namesp = extractNameSpaceDef( pp );
267
268 // no filter condition has been defined
269 StringBuffer sb = new StringBuffer( 5000 );
270 sb.append( "<?xml version='1.0' encoding='" + CharsetUtils.getSystemCharset() + "'?>" );
271 sb.append( "<GetFeature xmlns='http://www.opengis.net/wfs' " );
272 sb.append( "xmlns:ogc='http://www.opengis.net/ogc' " );
273 sb.append( "xmlns:gml='http://www.opengis.net/gml' " );
274 sb.append( "xmlns:" ).append( ds.getName().getPrefix() ).append( '=' );
275 sb.append( "'" ).append( ds.getName().getNamespace() ).append( "' " );
276 Iterator<String> iter = namesp.keySet().iterator();
277 while ( iter.hasNext() ) {
278 String pre = iter.next();
279 URI nsp = namesp.get( pre );
280 if ( !pre.equals( "xmlns" ) && !pre.equals( ds.getName().getPrefix() ) ) {
281 sb.append( "xmlns:" ).append( pre ).append( "='" );
282 sb.append( nsp.toASCIIString() ).append( "' " );
283 }
284 }
285
286 sb.append( "service='WFS' version='1.1.0' " );
287 if ( ds.getType() == AbstractDataSource.LOCALWFS ) {
288 sb.append( "outputFormat='FEATURECOLLECTION'>" );
289 } else {
290 sb.append( "outputFormat='text/xml; subtype=gml/3.1.1'>" );
291 }
292 sb.append( "<Query typeName='" + ds.getName().getPrefixedName() + "'>" );
293
294 for ( int j = 0; j < pp.size(); j++ ) {
295 if ( !pp.get( j ).getAsString().endsWith( "$SCALE" ) ) {
296 // $SCALE is a dynamicly created property of each feature
297 // and can not be requested
298 sb.append( "<PropertyName>" ).append( pp.get( j ).getAsString() );
299 sb.append( "</PropertyName>" );
300 }
301 }
302
303 Query query = ds.getQuery();
304 if ( query == null ) {
305 sb.append( "<ogc:Filter><ogc:BBOX>" );
306 sb.append( "<PropertyName>" );
307 sb.append( ds.getGeometryProperty().getPrefixedName() );
308 sb.append( "</PropertyName>" );
309 sb.append( GMLGeometryAdapter.exportAsBox( bbox ) );
310 sb.append( "</ogc:BBOX>" );
311 sb.append( "</ogc:Filter></Query></GetFeature>" );
312 } else {
313 Filter filter = query.getFilter();
314 sb.append( "<ogc:Filter>" );
315 if ( filter instanceof ComplexFilter ) {
316 sb.append( "<ogc:And>" );
317 sb.append( "<ogc:BBOX>" );
318 sb.append( "<PropertyName>" );
319 sb.append( ds.getGeometryProperty().getPrefixedName() );
320 sb.append( "</PropertyName>" );
321 sb.append( GMLGeometryAdapter.exportAsBox( bbox ) );
322 sb.append( "</ogc:BBOX>" );
323
324 // add filter as defined in the layers datasource description
325 // to the filter expression
326 org.deegree.model.filterencoding.Operation op = ( (ComplexFilter) filter ).getOperation();
327 sb.append( op.toXML() ).append( "</ogc:And>" );
328 } else {
329 ArrayList<FeatureId> featureIds = ( (FeatureFilter) filter ).getFeatureIds();
330 if ( featureIds.size() > 1 ) {
331 sb.append( "<ogc:And>" );
332 }
333 for ( int i = 0; i < featureIds.size(); i++ ) {
334 FeatureId fid = featureIds.get( i );
335 sb.append( fid.toXML() );
336 }
337 if ( featureIds.size() > 1 ) {
338 sb.append( "</ogc:And>" );
339 }
340 }
341 sb.append( "</ogc:Filter></Query></GetFeature>" );
342 }
343
344 // create dom representation of the request
345 Document doc = XMLTools.parse( new StringReader( sb.toString() ) );
346
347 LOG.logDebug( "GetFeature request: " + new XMLFragment( doc, "http://www.systemid.org" ).getAsPrettyString() );
348
349 // create OGCWebServiceEvent object
350 IDGenerator idg = IDGenerator.getInstance();
351 GetFeature gfr = GetFeature.create( "" + idg.generateUniqueID(), doc.getDocumentElement() );
352
353 return gfr;
354 }
355
356 /**
357 * transforms the requested BBOX into the DefaultSRS of the assigend feature type
358 *
359 * @param ds
360 * @return the envelope
361 * @throws OGCWebServiceException
362 * @throws CRSTransformationException
363 * @throws UnknownCRSException
364 */
365 private Envelope transformBBOX( LocalWFSDataSource ds )
366 throws OGCWebServiceException, CRSTransformationException, UnknownCRSException {
367 Envelope bbox = request.getBoundingBox();
368 // transform request bounding box to the coordinate reference
369 // system the WFS holds the data if requesting CRS and WFS-Data
370 // crs are different
371 OGCWebService service = ds.getOGCWebService();
372 WFSCapabilities capa;
373 if ( service instanceof RemoteWFService ) {
374 RemoteWFService wfs = (RemoteWFService) service;
375 capa = wfs.getWFSCapabilities();
376 } else {
377 WFService wfs = (WFService) service;
378 capa = wfs.getCapabilities();
379 }
380 // WFSCapabilities capa = (WFSCapabilities)wfs.getWFSCapabilities();
381 QualifiedName gn = ds.getName();
382 WFSFeatureType ft = capa.getFeatureTypeList().getFeatureType( gn );
383
384 if ( ft == null ) {
385 throw new OGCWebServiceException( Messages.getMessage( "WMS_UNKNOWNFT", ds.getName() ) );
386 }
387
388 // enable different formatations of the crs encoding for GML geometries
389 String GML_SRS = "http://www.opengis.net/gml/srs/";
390 String old_gml_srs = ft.getDefaultSRS().toASCIIString();
391 String old_srs;
392 if ( old_gml_srs.startsWith( GML_SRS ) ) {
393 old_srs = old_gml_srs.substring( 31 ).replace( '#', ':' ).toUpperCase();
394 } else {
395 old_srs = old_gml_srs;
396 }
397
398 String new_srs = request.getSrs();
399 String new_gml_srs;
400 if ( old_gml_srs.startsWith( GML_SRS ) ) {
401 new_gml_srs = GML_SRS + new_srs.replace( ':', '#' ).toLowerCase();
402 } else {
403 new_gml_srs = new_srs;
404 }
405
406 if ( !( old_srs.equalsIgnoreCase( new_gml_srs ) ) ) {
407 GeoTransformer transformer = new GeoTransformer( CRSFactory.create( old_srs ) );
408 bbox = transformer.transform( bbox, this.handler.getRequestCRS() );
409 }
410 return bbox;
411 }
412
413 /**
414 * creates a getCoverage request considering the getMap request and the filterconditions defined in the submitted
415 * <tt>DataSource</tt> object The request will be encapsualted within a <tt>OGCWebServiceEvent</tt>.
416 *
417 * @param ds
418 * @return GetCoverage request object
419 * @throws InconsistentRequestException
420 */
421 protected static GetCoverage createGetCoverageRequest( AbstractDataSource ds, GetMap request )
422 throws InconsistentRequestException {
423
424 Envelope bbox = request.getBoundingBox();
425
426 GetCoverage gcr = ( (LocalWCSDataSource) ds ).getGetCoverageRequest();
427
428 String crs = request.getSrs();
429 // if (gcr != null && gcr.getDomainSubset().getRequestSRS() != null) {
430 // crs = gcr.getDomainSubset().getRequestSRS().getCode();
431 // }
432 String format = request.getFormat();
433 int pos = format.indexOf( '/' );
434 if ( pos > -1 )
435 format = format.substring( pos + 1, format.length() );
436 if ( gcr != null && !"%default%".equals( gcr.getOutput().getFormat().getCode() ) ) {
437 format = gcr.getOutput().getFormat().getCode();
438 }
439 if ( format.indexOf( "svg" ) > -1 ) {
440 format = "tiff";
441 }
442
443 String version = "1.0.0";
444 if ( gcr != null && gcr.getVersion() != null ) {
445 version = gcr.getVersion();
446 }
447 String lay = ds.getName().getPrefixedName();
448 if ( gcr != null && !"%default%".equals( gcr.getSourceCoverage() ) ) {
449 lay = gcr.getSourceCoverage();
450 }
451 String ipm = null;
452 if ( gcr != null && gcr.getInterpolationMethod() != null ) {
453 ipm = gcr.getInterpolationMethod().value;
454 }
455
456 // TODO
457 // handle rangesets e.g. time and elevation
458 StringBuffer sb = new StringBuffer( 1000 );
459 sb.append( "service=WCS&request=GetCoverage" );
460 sb.append( "&version=" ).append( version );
461 sb.append( "&COVERAGE=" ).append( lay );
462 sb.append( "&crs=" ).append( crs );
463 sb.append( "&response_crs=" ).append( crs );
464 sb.append( "&BBOX=" ).append( bbox.getMin().getX() ).append( ',' );
465 sb.append( bbox.getMin().getY() ).append( ',' ).append( bbox.getMax().getX() );
466 sb.append( ',' ).append( bbox.getMax().getY() );
467 sb.append( "&WIDTH=" ).append( request.getWidth() );
468 sb.append( "&HEIGHT=" ).append( request.getHeight() );
469 sb.append( "&FORMAT=" ).append( format );
470 sb.append( "&INTERPOLATIONMETHOD=" ).append( ipm );
471 try {
472 IDGenerator idg = IDGenerator.getInstance();
473 gcr = GetCoverage.create( "id" + idg.generateUniqueID(), sb.toString() );
474 } catch ( WCSException e ) {
475 throw new InconsistentRequestException( e.getMessage() );
476 } catch ( org.deegree.ogcwebservices.OGCWebServiceException e ) {
477 throw new InconsistentRequestException( e.getMessage() );
478 }
479
480 LOG.logDebug( "GetCoverage request: " + sb.toString() );
481
482 return gcr;
483
484 }
485
486 /**
487 *
488 * @param result
489 * @return the response objects
490 * @throws Exception
491 */
492 private Object handleResponse( Object result )
493 throws Exception {
494
495 Object theme = null;
496 if ( result instanceof ResultCoverage ) {
497 theme = handleGetCoverageResponse( (ResultCoverage) result );
498 } else if ( result instanceof FeatureResult ) {
499 theme = handleGetFeatureResponse( (FeatureResult) result );
500 } else if ( result instanceof GetMapResult ) {
501 theme = handleGetMapResponse( (GetMapResult) result );
502 } else {
503 String s = Messages.getMessage( "WMS_UNKNOWNRESPONSEFORMAT" );
504 if ( datasource.isFailOnException() ) {
505 OGCWebServiceException exce = new OGCWebServiceException( getClass().getName(), s );
506 theme = exce;
507 } else {
508 theme = null;
509 }
510 }
511 return theme;
512 }
513
514 /**
515 * replaces all pixels within the passed image having a color that is defined to be transparent within their
516 * datasource with a transparent color.
517 *
518 * @param img
519 * @return modified image
520 */
521 private BufferedImage setTransparentColors( BufferedImage img ) {
522
523 Color[] colors = null;
524 if ( datasource.getType() == AbstractDataSource.LOCALWCS ) {
525 LocalWCSDataSource ds = (LocalWCSDataSource) datasource;
526 colors = ds.getTransparentColors();
527 } else {
528 RemoteWMSDataSource ds = (RemoteWMSDataSource) datasource;
529 colors = ds.getTransparentColors();
530 }
531
532 if ( colors != null && colors.length > 0 ) {
533
534 int[] clrs = new int[colors.length];
535 for ( int i = 0; i < clrs.length; i++ ) {
536 clrs[i] = colors[i].getRGB();
537 }
538
539 if ( img.getType() != BufferedImage.TYPE_INT_ARGB ) {
540 // if the incoming image does not allow transparency
541 // it must be copyed to a image of ARGB type
542 BufferedImage tmp = new BufferedImage( img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB );
543 Graphics g = tmp.getGraphics();
544 g.drawImage( img, 0, 0, null );
545 g.dispose();
546 img = tmp;
547 }
548
549 // TODO
550 // should be replaced by a JAI operation
551 int w = img.getWidth();
552 int h = img.getHeight();
553 for ( int i = 0; i < w; i++ ) {
554 for ( int j = 0; j < h; j++ ) {
555 int col = img.getRGB( i, j );
556 if ( shouldBeTransparent( colors, col ) ) {
557 img.setRGB( i, j, 0x00FFFFFF );
558 }
559 }
560 }
561
562 }
563
564 return img;
565 }
566
567 /**
568 * @return true if the distance between the image color and at least of the colors to be truned to be transparent is
569 * less than 3 in an int RGB cube
570 *
571 * @param colors
572 * @param color
573 */
574 private boolean shouldBeTransparent( Color[] colors, int color ) {
575 Color c2 = new Color( color );
576 int r = c2.getRed();
577 int g = c2.getGreen();
578 int b = c2.getBlue();
579 for ( int i = 0; i < colors.length; i++ ) {
580 int r1 = colors[i].getRed();
581 int g1 = colors[i].getGreen();
582 int b1 = colors[i].getBlue();
583 if ( Math.sqrt( ( r1 - r ) * ( r1 - r ) + ( g1 - g ) * ( g1 - g ) + ( b1 - b ) * ( b1 - b ) ) < 3 ) {
584 return true;
585 }
586 }
587 return false;
588 }
589
590 /**
591 * handles the response of a cascaded WMS and calls a factory to create <tt>DisplayElement</tt> and a <tt>Theme</tt>
592 * from it
593 *
594 * @param response
595 * @return the response objects
596 * @throws Exception
597 */
598 private Object handleGetMapResponse( GetMapResult response )
599 throws Exception {
600
601 BufferedImage bi = (BufferedImage) response.getMap();
602
603 bi = setTransparentColors( bi );
604 GridCoverage gc = new ImageGridCoverage( null, request.getBoundingBox(), bi );
605 org.deegree.graphics.Layer rl = MapFactory.createRasterLayer( layer.getName(), gc );
606 Theme theme = MapFactory.createTheme( datasource.getName().getPrefixedName(), rl, new UserStyle[] { style } );
607 return theme;
608
609 }
610
611 /**
612 * handles the response of a WFS and calls a factory to create <tt>DisplayElement</tt> and a <tt>Theme</tt> from it
613 *
614 * @param response
615 * @return the response objects
616 * @throws Exception
617 */
618 private Object handleGetFeatureResponse( FeatureResult response )
619 throws Exception {
620
621 FeatureCollection fc = null;
622
623 Object o = response.getResponse();
624 if ( o instanceof FeatureCollection ) {
625 fc = (FeatureCollection) o;
626 } else {
627 throw new Exception( Messages.getMessage( "WMS_UNKNOWNDATAFORMATFT" ) );
628 }
629 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
630 LOG.logDebug( "result: " + fc );
631 for ( int i = 0; i < fc.size(); ++i ) {
632 outputGeometries( fc.getFeature( i ) );
633 }
634 }
635
636 org.deegree.graphics.Layer fl = MapFactory.createFeatureLayer( layer.getName(), this.handler.getRequestCRS(),
637 fc );
638
639 return MapFactory.createTheme( datasource.getName().getPrefixedName(), fl, new UserStyle[] { style } );
640 }
641
642 private void outputGeometries( Feature feature ) {
643 if ( feature == null ) {
644 return;
645 }
646 FeatureType ft = feature.getFeatureType();
647 PropertyType[] propertyTypes = ft.getProperties();
648 for ( PropertyType pt : propertyTypes ) {
649 if ( pt.getType() == Types.FEATURE ) {
650 FeatureProperty[] fp = feature.getProperties( pt.getName() );
651 if ( fp != null ) {
652 for ( int i = 0; i < fp.length; i++ ) {
653 outputGeometries( (Feature) fp[i].getValue() );
654 }
655 }
656 } else if ( pt.getType() == Types.GEOMETRY ) {
657 Geometry g = feature.getDefaultGeometryPropertyValue();
658 if ( g != null ) {
659 try {
660 LOG.logDebug( "geometrie: " + WKTAdapter.export( g ).toString() );
661 } catch ( GeometryException e ) {
662 LOG.logDebug( "Geometry couldn't be converted to Well Known Text: " + g );
663 }
664 }
665 }
666 }
667 }
668
669 /**
670 * handles the response of a WCS and calls a factory to create <tt>DisplayElement</tt> and a <tt>Theme</tt> from it
671 *
672 * @param response
673 * @return the response objects
674 * @throws Exception
675 */
676 private Object handleGetCoverageResponse( ResultCoverage response )
677 throws Exception {
678 ImageGridCoverage gc = (ImageGridCoverage) response.getCoverage();
679 Object ro = null;
680 if ( gc != null ) {
681 BufferedImage bi = gc.getAsImage( -1, -1 );
682
683 bi = setTransparentColors( bi );
684
685 gc = new ImageGridCoverage( null, request.getBoundingBox(), bi );
686
687 org.deegree.graphics.Layer rl = MapFactory.createRasterLayer( layer.getName(), gc );
688
689 ro = MapFactory.createTheme( datasource.getName().getPrefixedName(), rl, new UserStyle[] { style } );
690 } else {
691 throw new OGCWebServiceException( getClass().getName(), Messages.getMessage( "WMS_NOCOVERAGE",
692 datasource.getName() ) );
693 }
694 return ro;
695 }
696
697 }