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 }