001 // $HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wcs/WCService.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 53115 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.wcs; 044 045 import java.awt.image.BufferedImage; 046 import java.io.IOException; 047 import java.io.InputStream; 048 import java.net.URL; 049 import java.util.ArrayList; 050 import java.util.List; 051 import java.util.Properties; 052 053 import org.deegree.crs.exceptions.CRSException; 054 import org.deegree.datatypes.parameter.GeneralParameterValueIm; 055 import org.deegree.datatypes.parameter.OperationParameterIm; 056 import org.deegree.framework.log.ILogger; 057 import org.deegree.framework.log.LoggerFactory; 058 import org.deegree.framework.util.StringTools; 059 import org.deegree.io.JDBCConnection; 060 import org.deegree.io.oraclegeoraster.GeoRasterDescription; 061 import org.deegree.model.coverage.Coverage; 062 import org.deegree.model.coverage.grid.AbstractGridCoverage; 063 import org.deegree.model.coverage.grid.DatabaseIndexedGCMetadata; 064 import org.deegree.model.coverage.grid.Format; 065 import org.deegree.model.coverage.grid.GridCoverageExchange; 066 import org.deegree.model.coverage.grid.GridCoverageReader; 067 import org.deegree.model.coverage.grid.ImageGridCoverage; 068 import org.deegree.model.crs.CRSFactory; 069 import org.deegree.model.crs.CRSTransformationException; 070 import org.deegree.model.crs.GeoTransformer; 071 import org.deegree.model.crs.UnknownCRSException; 072 import org.deegree.model.spatialschema.Envelope; 073 import org.deegree.ogcwebservices.InvalidParameterValueException; 074 import org.deegree.ogcwebservices.OGCWebService; 075 import org.deegree.ogcwebservices.OGCWebServiceException; 076 import org.deegree.ogcwebservices.OGCWebServiceRequest; 077 import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities; 078 import org.deegree.ogcwebservices.wcs.configuration.DatabaseResolution; 079 import org.deegree.ogcwebservices.wcs.configuration.Directory; 080 import org.deegree.ogcwebservices.wcs.configuration.DirectoryResolution; 081 import org.deegree.ogcwebservices.wcs.configuration.Extension; 082 import org.deegree.ogcwebservices.wcs.configuration.File; 083 import org.deegree.ogcwebservices.wcs.configuration.FileResolution; 084 import org.deegree.ogcwebservices.wcs.configuration.OracleGeoRasterResolution; 085 import org.deegree.ogcwebservices.wcs.configuration.Resolution; 086 import org.deegree.ogcwebservices.wcs.configuration.Shape; 087 import org.deegree.ogcwebservices.wcs.configuration.ShapeResolution; 088 import org.deegree.ogcwebservices.wcs.configuration.WCSConfiguration; 089 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageDescription; 090 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering; 091 import org.deegree.ogcwebservices.wcs.describecoverage.DescribeCoverage; 092 import org.deegree.ogcwebservices.wcs.describecoverage.InvalidCoverageDescriptionExcpetion; 093 import org.deegree.ogcwebservices.wcs.getcapabilities.ContentMetadata; 094 import org.deegree.ogcwebservices.wcs.getcapabilities.WCSGetCapabilities; 095 import org.deegree.ogcwebservices.wcs.getcapabilities.WCSRequestValidator; 096 import org.deegree.ogcwebservices.wcs.getcoverage.GetCoverage; 097 import org.deegree.ogcwebservices.wcs.getcoverage.ResultCoverage; 098 import org.deegree.ogcwebservices.wcs.getcoverage.SpatialSubset; 099 import org.xml.sax.SAXException; 100 101 /** 102 * @version $Revision: 9593 $ 103 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth </a> 104 * @author last edited by: $Author: otonnhofer $ 105 * 106 * @version 1.0. $Revision: 9593 $, $Date: 2008-01-17 15:43:50 +0100 (Do, 17 Jan 2008) $ 107 * 108 * @since 2.0 109 */ 110 111 public class WCService implements OGCWebService { 112 113 private static final ILogger LOG = LoggerFactory.getLogger( WCService.class ); 114 115 private int nor = 5; 116 117 private int degree = 3; 118 119 /** 120 * 121 */ 122 private WCSConfiguration configuration = null; 123 124 /** 125 * creates a WCService from a configuration 126 * 127 * @param configuration 128 */ 129 public WCService( WCSConfiguration configuration ) { 130 this.configuration = configuration; 131 URL url = WCService.class.getResource( "crstransform.properties" ); 132 Properties props = new Properties(); 133 try { 134 InputStream is = url.openStream(); 135 props.load( is ); 136 is.close(); 137 nor = Integer.parseInt( props.getProperty( "number_of_reference_points" ) ); 138 degree = Integer.parseInt( props.getProperty( "degree" ) ); 139 } catch ( Exception e ) { 140 LOG.logError( e.getMessage(), e ); 141 LOG.logInfo( "could not load definiton for crs transformation parameters, use default values" ); 142 } 143 } 144 145 /** 146 * returns the capabilities of the WCS 147 * 148 * @return capabilities of the WCS 149 */ 150 public OGCCapabilities getCapabilities() { 151 return configuration; 152 } 153 154 /** 155 * @param request 156 * @return a CoverageDescription fitting the request 157 * @throws OGCWebServiceException 158 * if an exception occurs in the process of creating the description. 159 */ 160 private CoverageDescription describeCoverage( DescribeCoverage request ) 161 throws OGCWebServiceException { 162 163 WCSRequestValidator.validate( configuration, request ); 164 CoverageOffering[] co = null; 165 try { 166 co = getCoverageOfferings( request ); 167 } catch ( IOException ioe ) { 168 LOG.logError( StringTools.stackTraceToString( ioe ) ); 169 throw new OGCWebServiceException( ioe.getMessage() ); 170 } catch ( SAXException saxe ) { 171 LOG.logError( StringTools.stackTraceToString( saxe ) ); 172 throw new OGCWebServiceException( saxe.getMessage() ); 173 } 174 CoverageDescription cd = new CoverageDescription( co, request.getVersion() ); 175 return cd; 176 } 177 178 /** 179 * @param request 180 * @return a given Coverage for the request 181 * @throws OGCWebServiceException 182 * if any kind of exception occurs 183 */ 184 private Coverage getCoverage( GetCoverage request ) 185 throws OGCWebServiceException { 186 187 WCSRequestValidator.validate( configuration, request ); 188 Coverage cov = null; 189 if ( request.getOutput().getFormat().getCode().equals( "GML" ) ) { 190 CoverageOffering co; 191 try { 192 co = getCoverageOffering( request ); 193 } catch ( InvalidCoverageDescriptionExcpetion e ) { 194 LOG.logError( "CoverageDescription is not valid", e ); 195 throw new OGCWebServiceException( getClass().getName(), "CoverageDescription is not valid: " 196 + e.getMessage() ); 197 } catch ( IOException e ) { 198 LOG.logError( "could not read CoverageDescription", e ); 199 throw new OGCWebServiceException( getClass().getName(), "could not read CoverageDescription: " 200 + e.getMessage() ); 201 } catch ( SAXException e ) { 202 LOG.logError( "could not parse CoverageDescription", e ); 203 throw new OGCWebServiceException( getClass().getName(), "could not parse CoverageDescription: " 204 + e.getMessage() ); 205 } 206 Envelope env = request.getDomainSubset().getSpatialSubset().getEnvelope(); 207 BufferedImage bi = new BufferedImage( 2, 2, BufferedImage.TYPE_INT_ARGB ); 208 cov = new ImageGridCoverage( co, env, bi ); 209 } else { 210 cov = readCoverage( request ); 211 } 212 213 return cov; 214 } 215 216 /** 217 * method for event based request procrssing 218 * 219 * @param request 220 * object containing the request. 221 * @return depending on the request one of, {@link WCSGetCapabilities}, {@link GetCoverage} or 222 * {@link DescribeCoverage} 223 */ 224 public Object doService( OGCWebServiceRequest request ) 225 throws OGCWebServiceException { 226 227 Object response = null; 228 if ( request instanceof WCSGetCapabilities ) { 229 WCSRequestValidator.validate( configuration, request ); 230 response = getCapabilities(); 231 } else if ( request instanceof GetCoverage ) { 232 Coverage cov = getCoverage( (GetCoverage) request ); 233 response = new ResultCoverage( cov, cov.getClass(), ( (GetCoverage) request ).getOutput().getFormat(), 234 (GetCoverage) request ); 235 } else if ( request instanceof DescribeCoverage ) { 236 response = describeCoverage( (DescribeCoverage) request ); 237 } 238 return response; 239 } 240 241 /** 242 * returns the <code>CoverageOffering</code> s according to the coverages names contained in 243 * the passed request. If the request doesn't contain one or more named coverage 244 * <code>CoverageOffering</code> s for all coverages known by the WCS will be returned. 245 * 246 * @param request 247 * DescribeCoverage request 248 * @return the configured coverings 249 * @throws IOException 250 * @throws SAXException 251 * @throws InvalidCoverageDescriptionExcpetion 252 */ 253 private CoverageOffering[] getCoverageOfferings( DescribeCoverage request ) 254 throws IOException, SAXException, InvalidCoverageDescriptionExcpetion { 255 256 String[] coverages = request.getCoverages(); 257 CoverageOffering[] co = null; 258 ContentMetadata cm = configuration.getContentMetadata(); 259 if ( coverages.length == 0 ) { 260 // get descriptions of all coverages 261 CoverageOfferingBrief[] cob = cm.getCoverageOfferingBrief(); 262 co = new CoverageOffering[cob.length]; 263 for ( int i = 0; i < cob.length; i++ ) { 264 URL url = cob[i].getConfiguration(); 265 CoverageDescription cd = CoverageDescription.createCoverageDescription( url ); 266 co[i] = cd.getCoverageOffering( cob[i].getName() ); 267 } 268 } else { 269 // get descriptions of all requested coverages 270 co = new CoverageOffering[coverages.length]; 271 for ( int i = 0; i < coverages.length; i++ ) { 272 CoverageOfferingBrief cob = cm.getCoverageOfferingBrief( coverages[i] ); 273 URL url = cob.getConfiguration(); 274 CoverageDescription cd = CoverageDescription.createCoverageDescription( url ); 275 co[i] = cd.getCoverageOffering( cob.getName() ); 276 } 277 } 278 279 return co; 280 } 281 282 /** 283 * The method reads and returns the coverage described by the passed request. 284 * 285 * @param request 286 * @return a Coverage read from the given resolution 287 * @throws InvalidCoverageDescriptionExcpetion 288 */ 289 private Coverage readCoverage( GetCoverage request ) 290 throws InvalidCoverageDescriptionExcpetion, InvalidParameterValueException, 291 OGCWebServiceException { 292 293 Coverage result = null; 294 295 try { 296 CoverageOffering co = getCoverageOffering( request ); 297 298 Resolution[] resolutions = getResolutions( co, request ); 299 if ( resolutions == null || resolutions.length == 0 ) { 300 throw new InvalidParameterValueException( 301 "No data source defined the requested combination of spatial resolution and ranges" ); 302 } 303 GridCoverageReader reader = null; 304 305 LOG.logDebug( "getting responsible GridCoverageReader" ); 306 if ( resolutions[0] instanceof FileResolution ) { 307 reader = getFileReader( resolutions, co, request ); 308 } else if ( resolutions[0] instanceof ShapeResolution ) { 309 reader = getShapeReader( resolutions, co, request ); 310 } else if ( resolutions[0] instanceof DirectoryResolution ) { 311 reader = getDirectoryReader( resolutions, co, request ); 312 } else if ( resolutions[0] instanceof OracleGeoRasterResolution ) { 313 reader = getOracleGeoRasterReader( resolutions, co, request ); 314 } else if ( resolutions[0] instanceof DatabaseResolution ) { 315 reader = getDatabaseRasterReader( resolutions, co, request ); 316 } 317 318 LOG.logDebug( "resolution reader: " + resolutions[0] ); 319 LOG.logDebug( "found reader: " + reader.getClass() ); 320 List<GeneralParameterValueIm> list = new ArrayList<GeneralParameterValueIm>( 20 ); 321 322 Envelope gridSize = (Envelope) request.getDomainSubset().getSpatialSubset().getGrid(); 323 Envelope targetEnv = request.getDomainSubset().getSpatialSubset().getEnvelope(); 324 325 int width = (int)(gridSize.getWidth() + 1); 326 int height = (int)(gridSize.getHeight() + 1); 327 OperationParameterIm op = new OperationParameterIm( "width", null, new Integer( width ) ); 328 list.add( new GeneralParameterValueIm( op ) ); 329 op = new OperationParameterIm( "height", null, new Integer( height ) ); 330 list.add( new GeneralParameterValueIm( op ) ); 331 GeneralParameterValueIm[] gpvs = new GeneralParameterValueIm[list.size()]; 332 result = reader.read( list.toArray( gpvs ) ); 333 if ( result == null ) { 334 throw new InvalidCoverageDescriptionExcpetion( 335 "Couldn't read a coverage for the requested resolution and/or area" ); 336 } 337 LOG.logDebug( "found result: " + result ); 338 339 // transform Coverage into another CRS if required 340 String crs = request.getOutput().getCrs().getCode(); 341 if ( crs == null ) { 342 crs = request.getDomainSubset().getRequestSRS().getCode(); 343 } 344 if ( !crs.equalsIgnoreCase( co.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0] ) ) { 345 LOG.logDebug( "transforming coverage to " + crs ); 346 GeoTransformer gt = new GeoTransformer( crs ); 347 348 result = gt.transform( (AbstractGridCoverage) result, targetEnv, width, height, nor, degree, null ); 349 } 350 351 } catch ( IOException e ) { 352 LOG.logError( e.getMessage(), e ); 353 throw new OGCWebServiceException( e.getMessage() ); 354 } catch ( SAXException e ) { 355 LOG.logError( e.getMessage(), e ); 356 throw new OGCWebServiceException( e.getMessage() ); 357 } catch ( CRSTransformationException e ) { 358 LOG.logError( e.getMessage(), e ); 359 throw new OGCWebServiceException( e.getMessage() ); 360 } catch ( UnknownCRSException e ) { 361 LOG.logError( e.getMessage(), e ); 362 throw new OGCWebServiceException( e.getMessage() ); 363 } 364 return result; 365 } 366 367 /** 368 * returns the <code>CoverageOffering</code> describing the access to the data sources behind 369 * the requested coverage 370 * 371 * @param request 372 * GetCoverage request 373 * @return the Coverage Offering fitting the request 374 * @throws IOException 375 * @throws SAXException 376 * @throws InvalidCoverageDescriptionExcpetion 377 */ 378 private CoverageOffering getCoverageOffering( GetCoverage request ) 379 throws IOException, SAXException, InvalidCoverageDescriptionExcpetion { 380 381 ContentMetadata cm = configuration.getContentMetadata(); 382 CoverageOfferingBrief cob = cm.getCoverageOfferingBrief( request.getSourceCoverage() ); 383 URL url = cob.getConfiguration(); 384 CoverageDescription cd = CoverageDescription.createCoverageDescription( url ); 385 return cd.getCoverageOffering( request.getSourceCoverage() ); 386 } 387 388 /** 389 * returns the <code>Resolution</code> s matching the scale, region and range parameters of 390 * the passed request 391 * 392 * @param co 393 * @param request 394 * @return the <code>Resolution</code> s matching the scale, region and range parameters of 395 * the passed request 396 * @throws CRSException 397 * @throws CRSTransformationException 398 */ 399 private Resolution[] getResolutions( CoverageOffering co, GetCoverage request ) 400 throws UnknownCRSException, CRSTransformationException { 401 402 Extension extension = co.getExtension(); 403 Resolution[] res = extension.getResolutions( calcSpatialResolution( co, request ) ); 404 405 return res; 406 } 407 408 /** 409 * calculates the spatial resolution of the coverage described by a GetCoverage request 410 * 411 * @param co 412 * @param request 413 * @return 414 * @throws UnknownCRSException 415 * @throws CRSTransformationException 416 */ 417 private double calcSpatialResolution( CoverageOffering co, GetCoverage request ) 418 throws UnknownCRSException, CRSTransformationException { 419 420 SpatialSubset sps = request.getDomainSubset().getSpatialSubset(); 421 // determine resolution of the requested coverage 422 Envelope env = calculateRequestEnvelope( request, co.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0] ); 423 Envelope grid = (Envelope) sps.getGrid(); 424 double qx = env.getWidth() / grid.getWidth(); 425 double qy = env.getHeight() / grid.getHeight(); 426 double reso = qx; 427 // if x- and y-direction has different resolution in the GetCoverage 428 // request use the finest 429 if ( qy < qx ) { 430 reso = qy; 431 } 432 return reso; 433 } 434 435 /** 436 * returns a <code>GridCoverageReader</code> for accessing the data source of the target 437 * coverage of the passed GetCoverage request. The reader will be constructed from all 438 * <code>File</code> s matching the filter conditions defined in the passed GeCoverage 439 * request. <BR> 440 * At the moment just the first field of the passed <code>Resolution</code> array will be 441 * considered! 442 * 443 * @param resolutions 444 * <code>Resolution</code> to get a reader for 445 * @param co 446 * description of the requested coverage 447 * @param request 448 * @return <code>GridCoverageReader</code> 449 * @throws IOException 450 * @throws UnknownCRSException 451 * @throws CRSTransformationException 452 */ 453 private GridCoverageReader getFileReader( Resolution[] resolutions, CoverageOffering co, GetCoverage request ) 454 throws IOException, InvalidParameterValueException, UnknownCRSException, 455 CRSTransformationException { 456 457 String nativeCRS = co.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0]; 458 // calculates the envevole to be used by the created GridCoverageReader 459 Envelope envelope = calculateRequestEnvelope( request, nativeCRS ); 460 461 File[] files = ( (FileResolution) resolutions[0] ).getFiles(); 462 List<File> list = new ArrayList<File>(); 463 for ( int i = 0; i < files.length; i++ ) { 464 Envelope fileEnv = files[i].getEnvelope(); 465 if ( fileEnv.intersects( envelope ) ) { 466 list.add( files[i] ); 467 } 468 } 469 files = list.toArray( new File[list.size()] ); 470 471 GridCoverageExchange gce = new GridCoverageExchange( null ); 472 Format format = new Format( co.getSupportedFormats().getNativeFormat() ); 473 GridCoverageReader reader = gce.getReader( files, co, envelope, format ); 474 475 return reader; 476 } 477 478 /** 479 * returns a <code>GridCoverageReader</code> for accessing the data source of the target 480 * coverage of the passed GetCoverage request. The reader will be constructed from all 481 * <code>Shape</code> s matching the filter conditions defined in the passed GeCoverage 482 * request. At least this should be just one! <BR> 483 * At the moment just the first field of the passed <code>Resolution</code> array will be 484 * considered! 485 * 486 * @param resolutions 487 * @param co 488 * @param request 489 * @return a GridCoverageReader which is able to read shape files. 490 * @throws IOException 491 * @throws UnknownCRSException 492 * @throws CRSTransformationException 493 */ 494 private GridCoverageReader getShapeReader( Resolution[] resolutions, CoverageOffering co, GetCoverage request ) 495 throws IOException, InvalidParameterValueException, UnknownCRSException, 496 CRSTransformationException { 497 498 String nativeCRS = co.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0]; 499 // calculates the envevole to be used by the created GridCoverageReader 500 Envelope envelope = calculateRequestEnvelope( request, nativeCRS ); 501 502 Shape shape = ( (ShapeResolution) resolutions[0] ).getShape(); 503 504 GridCoverageExchange gce = new GridCoverageExchange( null ); 505 Format format = new Format( co.getSupportedFormats().getNativeFormat() ); 506 return gce.getReader( shape, co, envelope, format ); 507 508 } 509 510 /** 511 * returns a <code>GridCoverageReader</code> for accessing the data source of the target 512 * coverage of the passed GetCoverage request. The reader will be constructed from all 513 * <code>Directory</code> s matching the filter conditions defined in the passed GeCoverage 514 * request. At least this should be just one! <BR> 515 * At the moment just the first field of the passed <code>Resolution</code> array will be 516 * considered! 517 * 518 * @param resolutions 519 * @param co 520 * @param request 521 * @return the GridCoverageReader which reads directories 522 * @throws IOException 523 * @throws UnknownCRSException 524 * @throws CRSTransformationException 525 */ 526 private GridCoverageReader getDirectoryReader( Resolution[] resolutions, CoverageOffering co, GetCoverage request ) 527 throws IOException, InvalidParameterValueException, UnknownCRSException, 528 CRSTransformationException { 529 530 String nativeCRS = co.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0]; 531 // calculates the envevole to be used by the created GridCoverageReader 532 Envelope envelope = calculateRequestEnvelope( request, nativeCRS ); 533 534 Directory[] dirs = ( (DirectoryResolution) resolutions[0] ).getDirectories( envelope ); 535 536 GridCoverageExchange gce = new GridCoverageExchange( null ); 537 Format format = new Format( co.getSupportedFormats().getNativeFormat() ); 538 539 GridCoverageReader reader = gce.getReader( dirs, co, envelope, format ); 540 541 return reader; 542 } 543 544 /** 545 * 546 * @param resolutions 547 * @param co 548 * @param request 549 * @return 550 * @throws CRSTransformationException 551 * @throws UnknownCRSException 552 * @throws IOException 553 * @throws InvalidParameterValueException 554 */ 555 private GridCoverageReader getDatabaseRasterReader( Resolution[] resolutions, CoverageOffering co, 556 GetCoverage request ) 557 throws UnknownCRSException, CRSTransformationException, InvalidParameterValueException, 558 IOException { 559 560 String nativeCRS = co.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0]; 561 // calculates the envevole to be used by the created GridCoverageReader 562 Envelope envelope = calculateRequestEnvelope( request, nativeCRS ); 563 564 DatabaseResolution dr = (DatabaseResolution) resolutions[0]; 565 566 GridCoverageExchange gce = new GridCoverageExchange( null ); 567 Format format = new Format( co.getSupportedFormats().getNativeFormat() ); 568 double reso = calcSpatialResolution( co, request ); 569 DatabaseIndexedGCMetadata digcmd = new DatabaseIndexedGCMetadata( dr.getJDBCConnection(), (float) reso, 570 dr.getTable(), dr.getRootDir(), false ); 571 572 return gce.getReader( digcmd, co, envelope, format ); 573 } 574 575 /** 576 * returns a <code>GridCoverageReader</code> for accessing the data source of the target 577 * coverage of the passed GetCoverage request. The reader will be constructed from the JDBCV 578 * connnection defined in the CoverageDescription extension.<BR> 579 * At the moment just the first field of the passed <code>Resolution</code> array will be 580 * considered! 581 * 582 * @param resolutions 583 * @param co 584 * @param request 585 * @return a <code>GridCoverageReader</code>. 586 * @throws InvalidParameterValueException 587 * @throws IOException 588 * @throws UnknownCRSException 589 * @throws CRSTransformationException 590 */ 591 private GridCoverageReader getOracleGeoRasterReader( Resolution[] resolutions, CoverageOffering co, 592 GetCoverage request ) 593 throws InvalidParameterValueException, IOException, UnknownCRSException, 594 CRSTransformationException { 595 596 String nativeCRS = co.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0]; 597 // calculates the envevole to be used by the created GridCoverageReader 598 Envelope envelope = calculateRequestEnvelope( request, nativeCRS ); 599 600 JDBCConnection jdbc = ( (OracleGeoRasterResolution) resolutions[0] ).getJDBCConnection(); 601 String table = ( (OracleGeoRasterResolution) resolutions[0] ).getTable(); 602 String rdtTable = ( (OracleGeoRasterResolution) resolutions[0] ).getRdtTable(); 603 String column = ( (OracleGeoRasterResolution) resolutions[0] ).getColumn(); 604 String identification = ( (OracleGeoRasterResolution) resolutions[0] ).getIdentification(); 605 int level = ( (OracleGeoRasterResolution) resolutions[0] ).getLevel(); 606 GeoRasterDescription grd = new GeoRasterDescription( jdbc, table, rdtTable, column, identification, level ); 607 608 GridCoverageExchange gce = new GridCoverageExchange( null ); 609 Format format = new Format( co.getSupportedFormats().getNativeFormat() ); 610 611 return gce.getReader( grd, co, envelope, format ); 612 613 } 614 615 /** 616 * According to WCS 1.0.0 the CRS of the GetCoverage request BBOX can be different to the 617 * desired CRS of the resulting coverage. This method transforms the request CRS to the output 618 * CRS if requiered. At the moment deegree WCS doesn't support transformation of grid coverages 619 * so the output CRS will always be the native CRS of te data. 620 * 621 * @param request 622 * @param nativeCrs 623 * @return a boundingbox of the request 624 * @throws CRSTransformationException 625 * @throws UnknownCRSException 626 */ 627 private Envelope calculateRequestEnvelope( GetCoverage request, String nativeCrs ) 628 throws UnknownCRSException, CRSTransformationException { 629 630 SpatialSubset spsu = request.getDomainSubset().getSpatialSubset(); 631 Envelope envelope = spsu.getEnvelope(); 632 633 String reqCrs = request.getDomainSubset().getRequestSRS().getCode(); 634 635 GeoTransformer gt = new GeoTransformer( nativeCrs ); 636 Envelope result = gt.transform( envelope, CRSFactory.create( reqCrs ), true ); 637 638 return result; 639 640 } 641 642 }