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