source: cowsserver/trunk/lib/cowsserver/controllers/csmlwms.py @ 6509

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cowsserver/trunk/lib/cowsserver/controllers/csmlwms.py@6509
Revision 6509, 9.9 KB checked in by pnorton, 9 years ago (diff)

Added some metadata information to the plot.

Line 
1import logging
2import time
3
4from geoplot.grid_plot import GridPlot
5from geoplot.contour_plot import ContourPlot
6from geoplot.interval_plot import IntervalPlot
7
8from cows.pylons.wms_controller import WMSController
9from cows.pylons import ows_controller
10from cows.exceptions import InvalidParameterValue
11
12from cows.service.imps.geoplot_wms_backend.geoplot_layer_mapper import GeoplotLayerMapper
13from cows.service.imps.geoplot_wms_backend.geoplot_wms_layer import GeoplotWmsLayer
14from cows.service.imps.geoplot_wms_backend.slab_options_json_generator import SlabJSONGenerator
15from cows.service.imps.geoplot_wms_backend.slab_options_parser import SlabOptionsParser
16
17GeoplotWmsLayer.EnableDisplayOptions = True
18GeoplotWmsLayer.EnableXMLAxisConfig = True
19
20from cowsserver.lib.base import request, response
21from cowsserver.lib.wms_request_log_utils import buildLogString, wms_request_logger
22
23from cowsserver.lib.modified_beaker_cache_decorator import cows_controller_beaker_cache
24
25from pylons.decorators.cache import beaker_cache
26
27log = logging.getLogger(__name__)
28
29class CsmlwmsController(WMSController):
30    layerMapper = GeoplotLayerMapper()
31   
32    owsOperations = (WMSController.owsOperations + ['GetDisplayOptions','GetAxisConfig','GetFigure'])
33   
34    nonPILFormats = {'application/postscript':'ps',
35                     'application/pdf':'pdf',
36                     'image/svg+xml':'svg'}
37   
38    def _loadCapabilities(self, *args, **kwargs):
39        ows_controller.addOperation('GetDisplayOptions', formats=['application/json'])
40        ows_controller.addOperation('GetFigure', formats=['image/png', 'image/jpg','image/gif', 'application/postscript', 'application/pdf','image/svg+xml' ])
41        WMSController._loadCapabilities(self, *args, **kwargs)
42   
43    def __before__(self, **kwargs):
44        wms_request_logger.info( buildLogString(request) )
45        WMSController.__before__(self, **kwargs)
46       
47    @cows_controller_beaker_cache(expire=3600)
48    def GetDisplayOptions(self):
49        log.info("running GetDisplayOptions")
50       
51        #create a list of names for each of the styles (each slabClass has its onw style)
52        styleOptionsMap = {}
53        for klass in GeoplotWmsLayer.slab_classes:
54            styleOptionsMap[klass.style] = [x for x in klass.renderingOptions]
55       
56       
57       
58        generator = SlabJSONGenerator(styleOptionsMap)
59       
60        response.headers['Content-Type'] = 'application/json'
61       
62        jsonString = generator.generateJSON()
63       
64        response.write( jsonString )
65   
66    @cows_controller_beaker_cache(expire=3600)
67    def GetAxisConfig(self):
68        log.info("running GetAxisConfig")
69        log.debug("self.layers = %s" % (self.layers,))
70       
71        layer = self._getLayerParam()[0]
72       
73        log.debug("layer = %s" % (layer,))
74       
75        configFile = layer.getAxisConfigFile()
76        log.debug("configFile = %s" % (configFile,))
77       
78        fin = open(configFile,'r')
79        log.debug("fin = %s" % (fin,))
80        response.headers['content-type'] = 'text/xml'
81       
82        response.write(fin.read())
83       
84    @cows_controller_beaker_cache(expire=3600)
85    def GetFigure(self):
86        log.info("running GetFigure")
87       
88        #!TODO: clearup!
89        # Get the parameters
90       
91        version      = self._getVersionParam()
92        format = self.getOwsParam('format', default='image/png')
93       
94        validFormats = self._pilImageFormats.keys()
95        validFormats.extend(self.nonPILFormats.keys())
96       
97        if format not in validFormats:
98            raise InvalidParameterValue('Format %s not supported' % format, 'format')
99         
100        transparent  = self._getTransparentParam()
101        bgcolor      = self._getBgcolorParam()
102        bbox         = self._getBboxParam()
103        width        = self._getWidthParam()
104        height       = self._getHeightParam()
105       
106        fileoruri = request.environ['pylons.routes_dict']['fileoruri']
107       
108        layerObjects = self._getLayerParam()
109       
110        assert len(layerObjects) == 1
111        layerObj = layerObjects[0]
112       
113        styles       = self._getStylesParam(len(layerObjects))
114       
115        if styles == "":
116            style = None
117        else:
118            style = styles[0]
119       
120        slab_class = layerObj._getSlabClass(style)
121       
122        srs          = self._getSrsParam(version)
123       
124        log.info("GetFigure: format=%s, transparent =%s, bgcolor =%s, bbox =%s, width =%s, height =%s, style =%s, srs = %s" % (format, transparent, bgcolor, bbox, width, height, style, srs,))
125        log.debug("slab_class = %s" % (slab_class,))
126       
127        dimValues = self._getDimValues(layerObj)
128       
129        log.debug("dimValues = %s" % (dimValues,))
130        variable = layerObj.dataReader.getNetcdfVar(layerObj.title, dimValues)
131       
132       
133        expectedParams = []
134        expectedParams.extend(self._escapedDimNames)
135        expectedParams.extend(layerObj.dimensions.keys())
136        expectedParams.append('service')
137       
138        #get any other parameters on the request that the layer might need
139        additionalParams = self._getAdditionalParameters(expectedParams)
140       
141        parser = SlabOptionsParser(slab_class.renderingOptions, additionalParams)
142       
143        log.debug("additionalParams = %s" % (additionalParams,))       
144        log.debug("variable.shape = %s" % (variable.shape,))
145        log.debug("bbox = %s" % (bbox,))
146
147        (xMin, yMin, xMax, yMax) = bbox
148       
149        kwargs = {}
150        kwargs['xLimits'] = (xMin, xMax)
151        kwargs['yLimits'] = (yMin, yMax)
152        kwargs['drawColourBar'] = True
153        kwargs['drawLogo'] = True
154        kwargs['drawRivers'] = False
155        kwargs['drawMetadata'] = True
156        kwargs['units'] = layerObj.units
157        kwargs['width'] = width
158        kwargs['height'] = height
159       
160        #common rendering options
161       
162        argMap = {'cmap':'cmap',
163                  'cmap_scale':'colourBarScale',
164                  'cmap_min':'colourBarMin',
165                  'cmap_max':'colourBarMax'}
166       
167        kwargs['metadataList'] = []
168        kwargs['metadataList'].append( ('Dataset',fileoruri) )
169        kwargs['metadataList'].append( ('Layer Name',layerObj.name) )
170        kwargs['metadataList'].append( ('Layer Title',layerObj.title) )
171       
172        dimString = ""
173        for k, v in dimValues.items():
174            dimString += "%s=%s, " % (k, v)
175           
176           
177       
178        dimString = dimString[:-2]
179           
180       
181        kwargs['metadataList'].append( ('Dimensions', dimString) )
182
183        if style is None or style == 'grid':
184            plot_class = GridPlot
185            argMap.update({'show_grid_lines':'showGridLines',
186                      'hide_outside':'hideOutsideBounds',})
187
188        elif style == 'contour':
189            plot_class = ContourPlot
190            argMap.update({'num_contour_lines':'numContourLines',
191                      'contour_label_interval':'contourLabelInterval',
192                      'contour_font_size':'contourFontSize',
193                      'intervals':'intervals'})
194           
195        elif style == 'interval':
196            plot_class = IntervalPlot
197            argMap.update({
198                      'hide_outside':'hideOutsideBounds',
199                      'show_grid_lines':'showGridLines',
200                      'num_intervals': 'numIntervals',
201                      'intervalNames': 'intervalNames',
202                      'intervals':'intervals'})
203           
204        else:
205            raise Exception("unknown style %s" % (styles[0],))
206       
207        # set the defaults for the min and max colourmap
208        kwargs['colourBarMax'] = parser.getOption('cmap_max')
209        if kwargs['colourBarMax'] is None:
210            kwargs['colourBarMax'] = variable[:].max()
211
212        kwargs['colourBarMin'] = parser.getOption('cmap_min')
213        if kwargs['colourBarMin'] is None:
214            kwargs['colourBarMin'] = variable[:].min()       
215
216       
217
218        self._addArguments(kwargs, argMap, parser, slab_class)
219        log.debug("kwargs = %s" % (kwargs,))
220        kwargs['cdmsVar'] = variable
221        plt = plot_class(**kwargs)
222
223        log.info("format = %s" % (format, ))
224        if format in self.nonPILFormats.keys():
225            plt.format = self.nonPILFormats[format]
226            buf = plt.drawToBuffer()
227           
228            response.headers['Content-Type'] = format
229            response.write(buf.getvalue())   
230        else:
231           
232            img = plt.drawToImage()
233            self._writeImageResponse(img, format)
234               
235        log.debug("finished getFigure")
236   
237    def _addArguments(self, kwargs, argMap, parser, slab_class):
238       
239        for renderingOpt in slab_class.renderingOptions:
240            if renderingOpt.name not in argMap:
241                log.warning("GetFigure has now means of passing on argument %s = %s to plot" % (renderingOpt.name, parser.getOption(renderingOpt.name)))
242       
243        for parameterArgName, plotArgName in argMap.items():
244            kwargs[plotArgName] = parser.getOption(parameterArgName)
245           
246           
247   
248    @cows_controller_beaker_cache(expire=3600)
249    def GetLegend(self):
250        log.info("running GetLegend")
251        return WMSController.GetLegend(self)
252   
253    @cows_controller_beaker_cache(expire=3600)
254    def GetCapabilities(self):
255        log.info("running GetCapabilities")
256        return WMSController.GetCapabilities(self)
257       
258    def _getLowerCaseParams(self):
259        lowerDictionary = {}
260       
261        for k, v in request.params.items():
262           
263            if v == None:
264                continue 
265           
266            v.strip()
267           
268            if v == "":
269                continue
270           
271            lowerDictionary[k.lower()] = v
272       
273        return lowerDictionary
274
275    @cows_controller_beaker_cache(expire=3600)
276    def GetMap(self):
277        log.info("running GetMap")
278        st = time.time()
279        WMSController.GetMap(self)
280        log.debug("Got Image response in %ss" % (time.time() - st))               
Note: See TracBrowser for help on using the repository browser.