Ignore:
Timestamp:
18/08/09 14:51:08 (10 years ago)
Author:
domlowe
Message:

Merging in qesdi changes to cows trunk - still need to merge new backend.

Location:
cows/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cows/trunk

    • Property svn:ignore set to
      .project
      .pydevproject
      cows.egg-info
  • cows/trunk/cows/pylons/wms_controller.py

    r5424 r5629  
    151151                log.info("dataURLs not populated: could not generate WCS url with url_for('wcsroute', filedoruri=%s,qualified=True)"%c.fileoruri) 
    152152                dataURLs=[] 
     153                 
     154             
     155             
     156             
     157            if hasattr(layer, 'styles'): 
     158                styles = layer.styles 
     159            else: 
     160                styles = [''] 
     161             
     162            if hasattr(layer, 'metadataURLs'): 
     163                metadataURLs = layer.metadataURLs 
     164            else: 
     165                metadataURLs = [] 
     166             
    153167            # Create the cows object 
    154168            ds = WmsDatasetSummary(identifier=layerName, 
     
    160174                                   dimensions=dims, 
    161175                                   queryable=queryable, 
    162                                    dataURLs=dataURLs) 
     176                                   dataURLs=dataURLs, 
     177                                   styles=styles, 
     178                                   metadataURLs=metadataURLs) 
    163179 
    164180            # Stuff that should go in the capabilities tree eventually 
     
    208224        layers = {} 
    209225        layerNames = self.getOwsParam(paramName) 
    210  
     226         
    211227        # Select the first layer if several are requested. 
    212228        # This plays nicer with mapClient. 
    213         #if ',' in layerName: 
    214229        layerNames = layerNames.split(',') 
    215             #raise InvalidParameterValue( 
    216             #    'Multi-layer GetMap requests are not supported', 'layers') 
     230         
     231        layerObjects = [] 
     232         
    217233        for layerName in layerNames: 
    218234            try: 
    219235                layerObj = self.layers[layerName] 
    220                 layers[layerName] = layerObj 
     236                layerObjects.append(layerObj) 
    221237            except KeyError: 
    222238                raise InvalidParameterValue('Layer %s not found' % layerName, 
    223239                                        paramName) 
    224240 
    225         #return layerName, layerObj 
    226         return layers 
     241        return layerObjects 
    227242 
    228243    def _getFormatParam(self): 
     
    278293 
    279294 
    280     def _retrieveSlab(self, layerObj, srs, dimValues, renderOpts): 
     295    def _retrieveSlab(self, layerObj, srs, style, dimValues, transparent, bgcolor, additionalParams): 
     296         
    281297        # Find the slab in the cache first 
    282         cacheKey = layerObj.getCacheKey(srs, dimValues) 
     298        cacheKey = layerObj.getCacheKey(srs, style, dimValues, transparent, bgcolor, additionalParams) 
    283299        slab = self._layerSlabCache.get(cacheKey) 
     300         
    284301        if slab is None: 
    285             slab = layerObj.getSlab(srs, dimValues, renderOpts) 
     302             
     303            slab = layerObj.getSlab(srs, style, dimValues, transparent, bgcolor, additionalParams) 
     304             
    286305            if cacheKey is not None: 
    287306                self._layerSlabCache[cacheKey] = slab 
     
    294313    def GetMap(self): 
    295314 
    296         # Housekeeping 
    297         version = self.getOwsParam('version', default=self.validVersions[0]) 
    298         if version not in self.validVersions: 
    299             raise InvalidParameterValue('Version %s not supported' % version, 
    300                                         'version') 
    301         styles = self.getOwsParam('styles', default='') 
    302         transparent = self.getOwsParam('transparent', default='FALSE') 
    303         bgcolor = self.getOwsParam('bgcolor', default='0xFFFFFF') 
    304  
    305         # Layer handling 
    306         #layerName, layerObj = self._getLayerParam() 
    307         layers = self._getLayerParam() 
    308         log.debug('GetMap request for layer(s) %s'%layers) 
    309         # Coordinate parameters 
    310         bbox = tuple(float(x) for x in self.getOwsParam('bbox').split(',')) 
    311         width = int(self.getOwsParam('width')) 
    312         height = int(self.getOwsParam('height')) 
    313  
    314         if version == '1.1.1': 
    315             srs = self.getOwsParam('srs') 
    316         else: 
    317             srs = self.getOwsParam('crs') 
    318  
    319         #if srs not in layerObj.crss: 
    320          #   raise InvalidParameterValue('Layer %s does not support SRS %s' % (layerName, srs)) 
    321  
    322         # Get format 
    323         format = self.getOwsParam('format') 
    324         if format not in self._pilImageFormats: 
    325             raise InvalidParameterValue( 
    326                 'Format %s not supported' % format, 'format') 
    327  
     315        # Get the parameters 
     316        version      = self._getVersionParam() 
     317        format       = self._getFormatParam()         
     318        transparent  = self._getTransparentParam() 
     319        bgcolor      = self._getBgcolorParam() 
     320        bbox         = self._getBboxParam() 
     321        width        = self._getWidthParam() 
     322        height       = self._getHeightParam() 
     323         
     324        layerObjects = self._getLayerParam() 
     325         
     326        styles       = self._getStylesParam(len(layerObjects)) 
     327        srs          = self._getSrsParam(version) 
     328         
     329        log.debug("layerNames = %s" % ([o.name for o in layerObjects],)) 
     330         
    328331        finalImg = Image.new('RGBA', (width, height), (0,0,0,0)) 
    329          
     332 
    330333        # Multiple Layers handling..   
    331         for layerName, layerObj in layers.iteritems(): 
     334        for i in range(len(layerObjects)): 
     335            layerObj = layerObjects[i] 
     336             
     337            #if no styles provided, set style = ""             
     338            if styles == "": 
     339                style = "" 
     340            else: 
     341                style = styles[i] 
     342             
    332343            if srs not in layerObj.crss: 
    333                 raise InvalidParameterValue('Layer %s does not support SRS %s' % (layerName, srs)) 
     344                raise InvalidParameterValue('Layer %s does not support SRS %s' % (layerObj.name, srs)) 
    334345 
    335346            dimValues = self._getDimValues(layerObj) 
     
    340351                restoredDim=self._mapParamToDim(dim) 
    341352                restoredDimValues[restoredDim]=dimValues[dim] 
    342                  
    343             #------------------------------------------------------- 
    344             # The real work 
    345             #!TODO: Minimum and maximum values 
    346  
    347             slab = self._retrieveSlab(layerObj, srs, restoredDimValues, 
    348                                       dict(minValue=0, maxValue=100)) 
    349  
    350             # We must request a bbox within the layer's bbox. 
    351             lbbox = layerObj.getBBox(srs) 
    352             ibbox = bbox_util.intersection(bbox, lbbox) 
    353  
    354             log.debug('bbox = %s' % (bbox,)) 
    355             log.debug('lbbox = %s' % (lbbox,)) 
    356             log.debug('ibbox = %s' % (ibbox,)) 
    357  
    358             # If bbox is not within layerObj.bbox then we need to calculate the 
    359             # pixel offset of the inner bbox, request the right width/height 
    360             # and paste the image into a blank background 
    361             if bbox == ibbox: 
    362                 img = slab.getImage(bbox, width, height) 
    363                 log.debug('slab image.size = %s' % (img.size,)) 
    364                          
    365             else: 
    366                  
    367                 ix0, iy0 = bbox_util.geoToPixel(ibbox[0], ibbox[3], bbox, width, height, 
    368                                                 roundUpY=True) 
    369                 ix1, iy1 = bbox_util.geoToPixel(ibbox[2], ibbox[1], bbox, width, height, 
    370                                                 roundUpX=True) 
    371                 iw = ix1-ix0 
    372                 ih = iy1-iy0 
    373                 log.debug('Deduced inner image: %s, (%d x %d)' % ((ix0, iy0, ix1, iy1), iw, ih)) 
    374                 img1 = slab.getImage(ibbox, iw, ih) 
    375  
    376                 img = Image.new('RGBA', (width, height)) 
    377                 img.paste(img1, (ix0, iy0)) 
    378                  
    379             finalImg = Image.composite(finalImg, img, finalImg)  
    380              
    381            
    382            
    383          
     353             
     354            expectedParams = [] 
     355            expectedParams.extend(self._escapedDimNames) 
     356            expectedParams.extend(layerObj.dimensions.keys()) 
     357             
     358            #get any other parameters on the request that the layer might need 
     359            additionalParams = self._getAdditionalParameters(expectedParams) 
     360             
     361            slab = self._retrieveSlab(layerObj, srs, style, dimValues,  
     362                                      transparent, bgcolor, additionalParams) 
     363 
     364            img = slab.getImage(bbox, width, height) 
     365             
     366            finalImg = Image.composite(finalImg, img, finalImg)     
     367 
    384368        # IE < 7 doesn't display the alpha layer right.  Here we sniff the 
    385369        # user agent and remove the alpha layer if necessary. 
     
    392376                finalImg = finalImg.convert('RGB') 
    393377 
    394         buf = StringIO() 
    395         finalImg.save(buf, self._pilImageFormats[format]) 
    396  
    397         response.headers['Content-Type'] = format 
    398         response.write(buf.getvalue()) 
     378        self._writeImageResponse(finalImg, format) 
    399379 
    400380 
     
    507487        format = self._getFormatParam() 
    508488 
    509         # This hook alows extra arguments to be passed to the layer backend.  It 
    510         # is required for UKCP. 
    511         renderOpts = dict(request_params=self._owsParams) 
    512  
    513         img = layerObj.getLegendImage(renderOpts=renderOpts) 
    514  
    515         buf = StringIO() 
    516         img.save(buf, self._pilImageFormats[format]) 
    517  
    518         response.headers['Content-Type'] = format 
    519         response.write(buf.getvalue()) 
     489        # This hook alows extra arguments to be passed to the layer backend. 
     490        additionalParams = self._getAdditionalParameters(['format']) 
     491         
     492        img = layerObj.getLegendImage(renderOpts=additionalParams) 
     493         
     494        self._writeImageResponse(img, format) 
     495 
    520496 
    521497 
     
    528504 
    529505             
     506    def _getAdditionalParameters(self, expectedParams): 
     507         
     508        additionalParams = {} 
     509         
     510        for paramName, paramValue in self._owsParams.items(): 
     511             
     512            paramName = paramName.lower() 
     513                         
     514            #ignore any of the expected parameters 
     515            if paramName in [p.lower() for p in expectedParams]: 
     516                continue 
     517             
     518            additionalParams[paramName] = paramValue 
     519             
     520        return additionalParams 
     521     
     522    def _getStylesParam(self, numLayers): 
     523        styles = self.getOwsParam('styles', default="") 
     524         
     525        if styles != "": 
     526            styles = styles.split(',') 
     527             
     528            assert len(styles) == numLayers, \ 
     529               "Number of styles %s didn't match the number of layers %s" % ( len(styles), numLayers) 
     530 
     531        return styles 
     532 
     533    def _getTransparentParam(self): 
     534        transparent = self.getOwsParam('transparent', default='FALSE') 
     535        return transparent.lower() == 'true' 
     536     
     537    def _getBgcolorParam(self): 
     538        return self.getOwsParam('bgcolor', default='0xFFFFFF') 
     539 
     540    def _getVersionParam(self): 
     541        version = self.getOwsParam('version', default=self.validVersions[0]) 
     542         
     543        if version not in self.validVersions: 
     544            raise InvalidParameterValue('Version %s not supported' % version, 'version') 
     545         
     546        return version 
     547 
     548    def _getSrsParam(self, version): 
     549        if version == '1.1.1': 
     550            srs = self.getOwsParam('srs') 
     551        else: 
     552            srs = self.getOwsParam('crs') 
     553             
     554        return srs 
     555 
     556    def _getBboxParam(self): 
     557        bbox = tuple(float(x) for x in self.getOwsParam('bbox').split(',')) 
     558        return bbox 
     559     
     560    def _getWidthParam(self): 
     561        return int(self.getOwsParam('width')) 
     562     
     563    def _getHeightParam(self): 
     564        return int(self.getOwsParam('height')) 
     565     
     566 
     567    def _writeImageResponse(self, pilImage, format): 
     568         
     569        buf = StringIO() 
     570        pilImage.save(buf, self._pilImageFormats[format]) 
     571 
     572        response.headers['Content-Type'] = format 
     573        response.write(buf.getvalue())     
Note: See TracChangeset for help on using the changeset viewer.