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

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

Improved the getfigure code so that more of the display options are used to generate the figure.

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        layerObjects = self._getLayerParam()
107       
108        assert len(layerObjects) == 1
109        layerObj = layerObjects[0]
110       
111        styles       = self._getStylesParam(len(layerObjects))
112       
113        if styles == "":
114            style = None
115        else:
116            style = styles[0]
117       
118        slab_class = layerObj._getSlabClass(style)
119       
120        srs          = self._getSrsParam(version)
121       
122        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,))
123        log.debug("slab_class = %s" % (slab_class,))
124       
125        dimValues = self._getDimValues(layerObj)
126       
127        log.debug("dimValues = %s" % (dimValues,))
128        variable = layerObj.dataReader.getNetcdfVar(layerObj.title, dimValues)
129       
130       
131        expectedParams = []
132        expectedParams.extend(self._escapedDimNames)
133        expectedParams.extend(layerObj.dimensions.keys())
134        expectedParams.append('service')
135       
136        #get any other parameters on the request that the layer might need
137        additionalParams = self._getAdditionalParameters(expectedParams)
138       
139        parser = SlabOptionsParser(slab_class.renderingOptions, additionalParams)
140       
141        log.debug("additionalParams = %s" % (additionalParams,))       
142        log.debug("variable.shape = %s" % (variable.shape,))
143        log.debug("bbox = %s" % (bbox,))
144
145        (xMin, yMin, xMax, yMax) = bbox
146       
147        kwargs = {}
148        kwargs['xLimits'] = (xMin, xMax)
149        kwargs['yLimits'] = (yMin, yMax)
150        kwargs['drawColourBar'] = True
151        kwargs['drawLogo'] = True
152        kwargs['drawRivers'] = False
153        kwargs['drawMetadata'] = True
154        kwargs['units'] = layerObj.units
155        kwargs['width'] = width
156        kwargs['height'] = height
157       
158        #common rendering options
159       
160        argMap = {'cmap':'cmap',
161                  'cmap_scale':'colourBarScale',
162                  'cmap_min':'colourBarMin',
163                  'cmap_max':'colourBarMax'}
164
165        if style is None or style == 'grid':
166            plot_class = GridPlot
167            argMap.update({'show_grid_lines':'showGridLines',
168                      'hide_outside':'hideOutsideBounds',})
169
170        elif style == 'contour':
171            plot_class = ContourPlot
172            argMap.update({'num_contour_lines':'numContourLines',
173                      'contour_label_interval':'contourLabelInterval',
174                      'contour_font_size':'contourFontSize',
175                      'intervals':'intervals'})
176           
177        elif style == 'interval':
178            plot_class = IntervalPlot
179            argMap.update({
180                      'hide_outside':'hideOutsideBounds',
181                      'show_grid_lines':'showGridLines',
182                      'num_intervals': 'numIntervals',
183                      'intervalNames': 'intervalNames',
184                      'intervals':'intervals'})
185           
186        else:
187            raise Exception("unknown style %s" % (styles[0],))
188       
189        # set the defaults for the min and max colourmap
190        kwargs['colourBarMax'] = parser.getOption('cmap_max')
191        if kwargs['colourBarMax'] is None:
192            kwargs['colourBarMax'] = variable[:].max()
193
194        kwargs['colourBarMin'] = parser.getOption('cmap_min')
195        if kwargs['colourBarMin'] is None:
196            kwargs['colourBarMin'] = variable[:].min()       
197
198       
199
200        self._addArguments(kwargs, argMap, parser, slab_class)
201        log.debug("kwargs = %s" % (kwargs,))
202        kwargs['cdmsVar'] = variable
203        plt = plot_class(**kwargs)
204
205        log.info("format = %s" % (format, ))
206        if format in self.nonPILFormats.keys():
207            plt.format = self.nonPILFormats[format]
208            buf = plt.drawToBuffer()
209           
210            response.headers['Content-Type'] = format
211            response.write(buf.getvalue())   
212        else:
213           
214            img = plt.drawToImage()
215            self._writeImageResponse(img, format)
216               
217        log.debug("finished getFigure")
218   
219    def _addArguments(self, kwargs, argMap, parser, slab_class):
220       
221        for renderingOpt in slab_class.renderingOptions:
222            if renderingOpt.name not in argMap:
223                log.warning("GetFigure has now means of passing on argument %s = %s to plot" % (renderingOpt.name, parser.getOption(renderingOpt.name)))
224       
225        for parameterArgName, plotArgName in argMap.items():
226            kwargs[plotArgName] = parser.getOption(parameterArgName)
227           
228           
229   
230    @cows_controller_beaker_cache(expire=3600)
231    def GetLegend(self):
232        log.info("running GetLegend")
233        return WMSController.GetLegend(self)
234   
235    @cows_controller_beaker_cache(expire=3600)
236    def GetCapabilities(self):
237        log.info("running GetCapabilities")
238        return WMSController.GetCapabilities(self)
239       
240    def _getLowerCaseParams(self):
241        lowerDictionary = {}
242       
243        for k, v in request.params.items():
244           
245            if v == None:
246                continue 
247           
248            v.strip()
249           
250            if v == "":
251                continue
252           
253            lowerDictionary[k.lower()] = v
254       
255        return lowerDictionary
256
257    @cows_controller_beaker_cache(expire=3600)
258    def GetMap(self):
259        log.info("running GetMap")
260        st = time.time()
261        WMSController.GetMap(self)
262        log.debug("Got Image response in %ss" % (time.time() - st))               
Note: See TracBrowser for help on using the repository browser.