source: cows/branches/wcsmerge/cows/pylons/wcs_controller.py @ 4690

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows/branches/wcsmerge/cows/pylons/wcs_controller.py@4690
Revision 4690, 8.4 KB checked in by domlowe, 12 years ago (diff)

adding stub describecoverage template

Line 
1"""
2WMS controller for OGC Web Services (OWS).
3
4@author: Stephen Pascoe
5"""
6
7import re
8import math
9from cStringIO import StringIO
10from sets import Set
11from matplotlib.cm import get_cmap
12from pylons import request, response, c
13import paste
14
15import logging
16log = logging.getLogger(__name__)
17
18import Image
19from genshi.template import TextTemplate
20
21from cows.model.wms import Dimension
22from cows.model.wcs import WcsDatasetSummary, CoverageDescription
23from cows.model import PossibleValues, WGS84BoundingBox, BoundingBox, Contents
24from cows.pylons import ows_controller
25from cows.exceptions import *
26from cows import bbox_util
27
28class WCSController(ows_controller.OWSController):
29    """
30    Subclass this controller in a pylons application and set the layerMapper
31    class attribute to implement a WCS.
32
33    @cvar layerMapper: an cows.service.wcs_iface.ILayerMapper object.
34
35    """
36    layerMapper = None
37    _layerSlabCache = {}
38
39    #-------------------------------------------------------------------------
40    # Attributes required by OWSController
41
42    service = 'WCS'
43    owsOperations = (ows_controller.OWSController.owsOperations +
44        ['GetCoverage', 'DescribeCoverage'])
45    validVersions = ['1.0.0']
46   
47
48    #-------------------------------------------------------------------------
49
50    def __before__(self, **kwargs):
51        """
52        This default implementation of __before__() will pass all routes
53        arguments to the layer mapper to retrieve a list of coverages for
54        this WCS.
55
56        It will be called automatically by pylons before each action method.
57
58        @todo: The layer mapper needs to come from somewhere.
59
60        """
61        log.debug("loading layers")
62        self.layers = self.layerMapper.map(**kwargs)
63
64    #-------------------------------------------------------------------------
65    # Methods implementing stubs in OWSController
66
67    def _renderCapabilities(self, version, format):
68        if version == '1.0.0':
69            t = ows_controller.templateLoader.load('wcs_capabilities_1_0_0.xml')
70        else:
71            # We should never get here!  The framework should raise an exception before now.
72            raise RuntimeError("Version %s not supported" % version)
73       
74        return t.generate(c=c).render()
75
76    def _loadCapabilities(self):
77        """
78        @note: Assumes self.layers has already been created by __before__().
79
80        """
81        self.datasetSummaries=[]
82        ows_controller.addOperation('GetCoverage')
83        ows_controller.addOperation('DescribeCoverage') 
84        featureInfoFormats = Set()
85
86        log.debug('Loading capabilities contents')
87        c.capabilities.contents = Contents()
88       
89        #TODO, the bounding box may include a Z dimension in WCS.
90        for cvgName, coverage in self.layers.items():
91            log.debug('Loading coverage %s' % cvgName)
92
93            wgs84BBox = WGS84BoundingBox(coverage.wgs84BBox[:2],
94                                         coverage.wgs84BBox[2:])
95            # Get CRS/BBOX pairs
96            bboxObjs = []
97            for crs in coverage.crss:
98                bbox = coverage.getBBox(crs)
99                bboxObjs.append(BoundingBox(bbox[:2], bbox[2:], crs=crs))
100               
101            # Create the cows object
102            #From the ows_servers stack - allthese values should come from  the Coverage object.
103            #TODO, the bounding box may include a Z dimension in WCS.
104            ds = WcsDatasetSummary(identifier=coverage.id,
105                                 titles=coverage.title,
106                                 boundingBoxes=[BoundingBox([bbox[0],bbox[1]], [bbox[2],bbox[3]],
107                                 crs='CRS:84')], 
108                                 description=coverage.description,
109                                 abstracts=coverage.abstract,
110                                 formats=['application/cf-netcdf'],
111                                 supportedCRSs=coverage.crss, 
112                                 timelimits=coverage.timeLimits
113                                 )
114
115            c.capabilities.contents.datasetSummaries.append(ds)
116
117           
118    def _getLayerParam(self, paramName='coverage'):
119        """
120        Retrieve the layers parameter enforcing the rule of only
121        selecting one coverage for now.
122
123        @param paramName: Overrides the query string parameter name to
124            look for.  This is usefull for implementing GetFeatureInfo.
125
126        """
127        layerName = self.getOwsParam(paramName)
128
129        # Select the first layer if several are requested.
130        # This plays nicer with mapClient.
131        if ',' in layerName:
132            #layerName = layerName.split(',')[0]
133            raise InvalidParameterValue(
134                'Multi-coverage getCoverage requests are not supported', 'coverage')
135        try:
136            layerObj = self.layers[layerName]
137        except KeyError:
138            raise InvalidParameterValue('coverage %s not found' % layerName,
139                                        paramName)
140
141        return layerName, layerObj
142   
143   
144    #-------------------------------------------------------------------------
145    # OWS Operation methods: DescribeCoverage and GetCoverage
146   
147    def GetCoverage(self):
148        # Housekeeping
149        version = self.getOwsParam('version', default=self.validVersions[0])
150        if version not in self.validVersions:
151            raise InvalidParameterValue('Version %s not supported' % version,
152                                        'version')
153        # Layer handling
154        layerName, layerObj = self._getLayerParam()
155       
156        # Coordinate parameters
157        bbox = tuple(float(x) for x in self.getOwsParam('bbox').split(','))
158
159        srs = self.getOwsParam('crs')
160
161        #if srs not in layerObj.crss:
162         #   raise InvalidParameterValue('Layer %s does not support SRS %s' % (layerName, srs))
163
164        # Get format
165        format = self.getOwsParam('format')
166       
167        if srs not in layerObj.crss:
168            raise InvalidParameterValue('Layer %s does not support SRS %s' % (layerName, srs))
169        times= self.getOwsParam('times')
170#               
171        filepath = layerObj.getCvg(bbox, time=times) #TODO, refactor so is more flexible (e.g. not just netcdf)
172        fileToReturn=open(filepath, 'r')
173        mType='application/cf-netcdf'
174        response.headers['Content-Type']=mType
175        response.headers['Content-Disposition'] = paste.httpheaders.CONTENT_DISPOSITION(attachment=True, filename='filename.nc')
176        return response.write(fileToReturn.read())
177           
178    def DescribeCoverage(self):
179        c.descriptions=[]
180        requestCvg=self.getOwsParam('coverage')
181#        super(WCSController, self).GetCapabilities()
182        #TODO, the bounding box may include a Z dimension in WCS.
183        log.debug(requestCvg)
184        for cvgName, coverage in self.layers.items():
185            log.debug(cvgName)
186            if cvgName == requestCvg:
187                log.debug('found match')
188                wgs84BBox = WGS84BoundingBox(coverage.wgs84BBox[:2],
189                                         coverage.wgs84BBox[2:])
190                # Get CRS/BBOX pairs
191                bboxObjs = []
192                for crs in coverage.crss:
193                    bbox = coverage.getBBox(crs)
194                    bboxObjs.append(BoundingBox(bbox[:2], bbox[2:], crs=crs))
195                   
196                # Create the enhanced Dataset summary for thic coverage
197                #TODO, the bounding box may include a Z dimension in WCS.
198                #TODO, what extra information does this require over the normal dataset summary               
199                ds = CoverageDescription(identifier=coverage.id,
200                                     titles=coverage.title,
201                                     boundingBoxes=[BoundingBox([bbox[0],bbox[1]], [bbox[2],bbox[3]],
202                                     crs='CRS:84')], 
203                                     description=coverage.description,
204                                     abstracts=coverage.abstract,
205                                     formats=['application/cf-netcdf'],
206                                     supportedCRSs=coverage.crss, 
207                                     timelimits=coverage.timeLimits
208                                     )
209
210                c.descriptions.append(ds)
211        response.headers['content-type']='text/xml'
212        t = ows_controller.templateLoader.load('wcs_describecoverage_1_0_0.xml')
213        return t.generate(c=c).render()               
214
215
216
217
218           
Note: See TracBrowser for help on using the repository browser.