    001    // $HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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    }