source: qesdi/wms_ddc_vis/trunk/lib/wms_ddc_vis/controllers/csmlwms.py @ 5479

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/qesdi/wms_ddc_vis/trunk/lib/wms_ddc_vis/controllers/csmlwms.py@5479
Revision 5479, 7.4 KB checked in by pnorton, 10 years ago (diff)

Made some more modifications to the ddc WMS. I've tried to reduce the amount of code duplication between the code and the cows egg.

Line 
1import logging
2import Image
3import re
4from StringIO import StringIO
5from pylons import request, response, c
6
7from cows import bbox_util
8
9from wms_ddc_vis.model.ddc_layer_mapper import DDCLayerMapper
10from wms_ddc_vis.model.ddc_wms_layer import STYLES, RENDERING_OPTIONS
11
12from cows.pylons.wms_controller import WMSController
13
14
15log = logging.getLogger(__name__)
16
17class CsmlwmsController(WMSController):
18    layerMapper = DDCLayerMapper()
19
20    def _getLayerParam(self, paramName='layers'):
21        """
22        Retrieve the layers parameter enforcing the rule of only
23        selecting one layer.
24
25        @param paramName: Overrides the query string parameter name to
26            look for.  This is usefull for implementing GetFeatureInfo.
27
28        """
29        layers = {}
30        layerNames = self.getOwsParam(paramName)
31       
32        # Select the first layer if several are requested.
33        # This plays nicer with mapClient.
34        layerNames = layerNames.split(',')
35       
36        layerObjects = []
37       
38        for layerName in layerNames:
39            try:
40                layerObj = self.layers[layerName]
41                layerObjects.append(layerObj)
42#                layers[layerName] = layerObj
43            except KeyError:
44                raise InvalidParameterValue('Layer %s not found' % layerName,
45                                        paramName)
46
47        return layerNames, layerObjects
48        #return layers
49
50
51       
52    def _retrieveSlab(self, layerObj, srs, dimValues, style, transparent, renderOpts):
53       
54        # Find the slab in the cache first
55        cacheKey = layerObj.getCacheKey(srs, style, transparent, dimValues, renderOpts)
56        slab = self._layerSlabCache.get(cacheKey)
57       
58        if slab is None:
59           
60            slab = layerObj.getSlab(srs, style, transparent, dimValues, renderOpts)
61           
62            if cacheKey is not None:
63                self._layerSlabCache[cacheKey] = slab
64
65        return slab
66
67    #-------------------------------------------------------------------------
68    # OWS Operation methods
69   
70    def GetMap(self):
71
72        # Housekeeping
73        version = self.getOwsParam('version', default=self.validVersions[0])
74       
75        if version not in self.validVersions:
76            raise InvalidParameterValue('Version %s not supported' % version,
77                                        'version')
78       
79       
80        renderingOptions = {}
81        for opt in RENDERING_OPTIONS:
82            if self.getOwsParam(opt, default=None) != None:
83                renderingOptions[opt] = self.getOwsParam(opt)
84       
85        log.debug("renderingOptions = %s" % (renderingOptions,))
86       
87
88       
89        transparent = self.getOwsParam('transparent', default='FALSE')
90       
91        transparent = transparent.lower() == 'true'
92       
93        bgcolor = self.getOwsParam('bgcolor', default='0xFFFFFF')
94
95        # Layer handling
96        layerNames, layerObjects = self._getLayerParam()
97#        layers = self._getLayerParam()
98       
99        log.debug("layerNames = %s" % (layerNames,))
100        log.debug("layerObjects = %s" % (layerObjects,))
101       
102        styles = self.getOwsParam('styles', default='')
103       
104        if styles != None:
105            styles = styles.split(',')
106            assert len(styles) == len(layerNames)
107       
108        log.debug("style = %s" % (styles,))       
109       
110        # Coordinate parameters
111        bbox = tuple(float(x) for x in self.getOwsParam('bbox').split(','))
112        width = int(self.getOwsParam('width'))
113        height = int(self.getOwsParam('height'))
114
115        if version == '1.1.1':
116            srs = self.getOwsParam('srs')
117        else:
118            srs = self.getOwsParam('crs')
119
120        #if srs not in layerObj.crss:
121         #   raise InvalidParameterValue('Layer %s does not support SRS %s' % (layerName, srs))
122
123        # Get format
124        format = self.getOwsParam('format')
125        if format not in self._pilImageFormats:
126            raise InvalidParameterValue(
127                'Format %s not supported' % format, 'format')
128
129
130        finalImg = Image.new('RGBA', (width, height), (0,0,0,0))
131
132        # Multiple Layers handling.. 
133#        for layerName, layerObj in layers.iteritems():
134        for i in range(len(layerNames)):
135           
136            layerName = layerNames[i]
137            layerObj = layerObjects[i]
138            if styles != None:
139                style = styles[i]
140            else:
141                style = ""
142               
143            if style == "":
144                style = STYLES.DEFAULT
145               
146           
147            if srs not in layerObj.crss:
148                raise InvalidParameterValue('Layer %s does not support SRS %s' % (layerName, srs))
149
150            dimValues = self._getDimValues(layerObj)
151           
152            #now need to revert modified dim values (e.g. height_dim) back to dim values the layerMapper understands (e.g. height)
153            restoredDimValues={}
154            for dim in dimValues:
155                restoredDim=self._mapParamToDim(dim)
156                restoredDimValues[restoredDim]=dimValues[dim]
157               
158            #-------------------------------------------------------
159            # The real work
160            #!TODO: Minimum and maximum values
161
162            slab = self._retrieveSlab(layerObj, srs, restoredDimValues, style,
163                                      transparent, renderingOptions)
164
165            # We must request a bbox within the layer's bbox.
166            lbbox = layerObj.getBBox(srs)
167            ibbox = bbox_util.intersection(bbox, lbbox)
168
169            log.debug('bbox = %s' % (bbox,))
170            log.debug('lbbox = %s' % (lbbox,))
171            log.debug('ibbox = %s' % (ibbox,))
172
173            log.debug("width, height = %s, %s" % (width, height,))
174            img = slab.getImage(bbox, width, height)
175           
176            log.debug("img = %s format=%s, size=%s, mode=%s" % (img, img.format, img.size, img.mode))
177            log.debug("finalImg = %s format=%s, size=%s, mode=%s" % (finalImg, finalImg.format, finalImg.size, finalImg.mode))
178
179            finalImg = Image.composite(finalImg, img, finalImg)   
180
181           
182        # IE < 7 doesn't display the alpha layer right.  Here we sniff the
183        # user agent and remove the alpha layer if necessary.
184        try:
185            ua = request.headers['User-Agent']
186        except:
187            pass
188        else:
189            if 'MSIE' in ua and 'MSIE 7' not in ua:
190                finalImg = finalImg.convert('RGB')
191
192        buf = StringIO()
193        finalImg.save(buf, self._pilImageFormats[format])
194
195        response.headers['Content-Type'] = format
196        response.write(buf.getvalue())
197
198    def GetLegend(self):
199        """
200        Return an image of the legend.
201
202        """
203        # Parameters
204        layerName, layerObj = self._getLayerParamInfo()
205        format = self._getFormatParam()
206
207        # This hook alows extra arguments to be passed to the layer backend.  It
208        # is required for UKCP.
209#        renderOpts = dict(request_params=self._owsParams)
210     
211        renderingOptions = {}
212        for opt in RENDERING_OPTIONS:
213            if self.getOwsParam(opt, default=None) != None:
214                renderingOptions[opt] = self.getOwsParam(opt)
215       
216#        log.debug("renderingOptions = %s" % (renderingOptions,))
217
218        img = layerObj.getLegendImage(renderOpts=renderingOptions)
219
220        buf = StringIO()
221        img.save(buf, self._pilImageFormats[format])
222
223        response.headers['Content-Type'] = format
224        response.write(buf.getvalue())
225
Note: See TracBrowser for help on using the repository browser.