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