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 }