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 }