Changeset 4634


Ignore:
Timestamp:
15/12/08 10:52:39 (11 years ago)
Author:
domlowe
Message:

more merging

Location:
cows/branches/wcsmerge/cows
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cows/branches/wcsmerge/cows/pylons/wcs_controller.py

    r4633 r4634  
    5858 
    5959        """ 
    60             #self.updateSequence = "hello" 
    6160        log.debug("loading layers") 
    62             #print self.layers 
    6361        self.layers = self.layerMapper.map(**kwargs) 
    6462 
     
    8684        log.debug('Loading capabilities contents') 
    8785        c.capabilities.contents = Contents() 
     86         
     87        #TODO, the bounding box may include a Z dimension in WCS. 
    8888        for cvgName, coverage in self.layers.items(): 
    8989            log.debug('Loading coverage %s' % cvgName) 
     
    9696                bbox = coverage.getBBox(crs) 
    9797                bboxObjs.append(BoundingBox(bbox[:2], bbox[2:], crs=crs)) 
    98             # Get dimensions 
    99             dims = {} 
    100             for dimName, dim in coverage.dimensions.items(): 
    101                 dimParam = self._mapDimToParam(dimName) 
    102                 dims[dimParam] = Dimension(valuesUnit=dim.units, 
    103                                           unitSymbol=dim.units, 
    104                                           possibleValues= 
    105                                             PossibleValues.fromAllowedValues(dim.extent)) 
    10698                 
    10799            # Create the cows object 
    108100            #From the ows_servers stack - allthese values should come from  the Coverage object. 
     101            #TODO, the bounding box may include a Z dimension in WCS. 
    109102            ds = WcsDatasetSummary(identifier=coverage.id, 
    110103                                 titles=coverage.title, 
     
    126119        """ 
    127120        Retrieve the layers parameter enforcing the rule of only 
    128         selecting one coverage 
     121        selecting one coverage for now. 
    129122 
    130123        @param paramName: Overrides the query string parameter name to 
     
    149142     
    150143     
    151     def _getFormatParam(self): 
    152         format = self.getOwsParam('format', default='image/png') 
    153         if format not in self._pilImageFormats: 
    154             raise InvalidParameterValue( 
    155                 'Format %s not supported' % format, 'format') 
    156  
    157         return format 
    158  
    159     _escapedDimNames = ['width', 'height', 'version', 'request', 
    160                         'layers', 'styles', 'crs', 'srs', 'bbox', 
    161                         'format', 'transparent', 'bgcolor', 
    162                         'exceptions'] 
    163  
    164     def _getDimValues(self, layerObj): 
    165         dimValues = {} 
    166         for dimName, dim in layerObj.dimensions.items(): 
    167             defaultValue = dim.extent[0] 
    168             escapedDimName=self._mapDimToParam(dimName) 
    169             dimValues[escapedDimName] = self.getOwsParam(escapedDimName, 
    170                                                   default=defaultValue) 
    171         return dimValues 
    172  
    173     def _mapDimToParam(self, dimName): 
    174         """ 
    175         Dimension names might clash with WMS parameter names, making 
    176         them inaccessible in WMS requests.  This method maps a 
    177         dimension name to a parameter name that appears in the 
    178         capabilities document and WMS requests. 
    179  
    180         """ 
    181         if dimName.lower() in self._escapedDimNames: 
    182             return dimName+'_dim' 
    183         else: 
    184             return dimName 
    185          
    186     def _mapParamToDim(self, dimParam): 
    187         """ 
    188         Maps a dimension parameter name to it's real dimension name. 
    189  
    190         @see: _mapDimToParam() 
    191  
    192         """ 
    193         try: 
    194             dimName = re.match(r'(.*)_dim$', dimParam).group(1) 
    195             if dimName.lower() in self._escapedDimNames: 
    196                 return dimName 
    197             else: 
    198                 return dimParam 
    199         except AttributeError: 
    200             return dimParam 
    201  
    202  
    203 #    def _retrieveSlab(self, layerObj, srs, dimValues, renderOpts): 
    204 #        # Find the slab in the cache first 
    205 #        cacheKey = layerObj.getCacheKey(srs, dimValues) 
    206 #         
    207 #        slab = self._layerSlabCache.get(cacheKey) 
    208 #        if slab is None: 
    209 #            slab = layerObj.getSlab(srs, dimValues, renderOpts) 
    210 #            if cacheKey is not None: 
    211 #                self._layerSlabCache[cacheKey] = slab 
    212 # 
    213 #        return slab 
    214      
    215 #    def _retrieveSubset(self, layerObj, srs, dimValues): 
    216 #        # Find the slab in the cache first 
    217 #        cacheKey = layerObj.getCacheKey(srs, dimValues) 
    218 #         
    219 #        slab = self._layerSlabCache.get(cacheKey) 
    220 #        if slab is None: 
    221 #             
    222 #            slab = layerObj.getCvg(srs, dimValues) 
    223 #            slab = layerObj.getCvg(srs, dimValues) 
    224 #            if cacheKey is not None: 
    225 #                self._layerSlabCache[cacheKey] = slab 
    226 #                 
    227 #        return slab 
    228      
    229     #------------------------------------------------------------------------- 
    230     # OWS Operation methods 
     144    #------------------------------------------------------------------------- 
     145    # OWS Operation methods: DescribeCoverage and GetCoverage 
    231146     
    232147    def GetCoverage(self): 
     
    252167        if srs not in layerObj.crss: 
    253168            raise InvalidParameterValue('Layer %s does not support SRS %s' % (layerName, srs)) 
    254  
    255         dimValues = self._getDimValues(layerObj) 
    256              
    257         #now need to revert modified dim values (e.g. height_dim) back to dim values the layerMapper understands (e.g. height) 
    258         restoredDimValues={} 
    259         for dim in dimValues: 
    260             restoredDim=self._mapParamToDim(dim) 
    261             restoredDimValues[restoredDim]=dimValues[dim] 
    262                  
     169        times= self.getOwsParam('times') 
     170#                 
    263171        #------------------------------------------------------- 
    264172        #!TODO: Minimum and maximum values 
    265173#        filepath = self._retrieveSubset(layerObj, srs, bbox, restoredDimValues) 
    266         filepath = layerObj.getCvg(bbox) 
     174        filepath = layerObj.getCvg(bbox, time=times) 
    267175        fileToReturn=open(filepath, 'r') 
    268176        mType='application/cf-netcdf' 
     
    271179        return response.write(fileToReturn.read()) 
    272180             
    273 # 
    274     def GetContext(self): 
    275         """ 
    276         Return a WebMap Context document for a given set of layers. 
    277  
    278         """ 
    279         # Parameters 
    280         layers = self.getOwsParam('layers', default=None) 
    281  
    282         # Filter self.layers for selected layers 
    283         if layers is not None: 
    284             newLayerMap = {} 
    285             for layerName in layers.split(','): 
    286                 try: 
    287                     newLayerMap[layerName] = self.layers[layerName] 
    288                 except KeyError: 
    289                     raise InvalidParameterValue('Layer %s not found' % layerName, 
    290                                                 'layers') 
    291                      
    292             self.layers = newLayerMap 
    293  
    294         # Automatically select the first bbox/crs for the first layer 
    295         aLayer = self.layers.values()[0] 
    296         crs = aLayer.crss[0] 
    297         bb = aLayer.getBBox(crs) 
    298         c.bbox = BoundingBox(bb[:2], bb[2:], crs) 
    299  
    300         # Initialise as if doing GetCapabilities 
    301         ows_controller.initCapabilities() 
    302         self._loadCapabilities() 
    303  
    304         response.headers['Content-Type'] = 'text/xml' 
    305         t = ows_controller.templateLoader.load('wms_context_1_1_1.xml') 
    306         return t.generate(c=c).render() 
    307  
    308     def GetFeatureInfo(self): 
     181 
     182    def GetFeatureInfo(self): #TODO: This should be DescribeCoverage 
    309183        # Housekeeping 
    310184        version = self.getOwsParam('version', default=self.validVersions[0]) 
     
    362236        response.write(layerObj.getFeatureInfo(format, srs, (x, y), dimValues)) 
    363237 
    364     def GetLegend(self): 
    365         """ 
    366         Return an image of the legend. 
    367  
    368         """ 
    369         # Parameters 
    370         layerName, layerObj = self._getLayerParamInfo() 
    371         format = self._getFormatParam() 
    372  
    373         img = layerObj.getLegendImage() 
    374  
    375         buf = StringIO() 
    376         img.save(buf, self._pilImageFormats[format]) 
    377  
    378         response.headers['Content-Type'] = format 
    379         response.write(buf.getvalue()) 
    380  
    381  
    382     def GetInfo(self): 
    383         from pprint import pformat 
    384         request.headers['Content-Type'] = 'text/ascii' 
    385         response.write('Some info about this service\n') 
    386         for layer in model.ukcip02.layers: 
    387             response.write('Layer %s: %s\n' % (layer, pformat(g.ukcip02_layers[layer].__dict__))) 
    388238 
    389239             
  • cows/branches/wcsmerge/cows/service/imps/csmlbackend/wcs_csmllayer.py

    r4633 r4634  
    1010    import cdms 
    1111from pylons import config, request, session 
    12 import Image 
    1312from copy import copy 
    14 from matplotlib import cm 
    15 import cdtime 
     13 
    1614import logging 
    1715log = logging.getLogger(__name__) 
    1816 
    1917from cows.model.contents import DatasetSummary 
    20 from cows.service.wms_iface import IwmsLayer, IwmsDimension, IwmsLayerSlab 
    2118from cows.service.imps.csmlbackend.csmlcommon import CSMLLayerMapper, CSMLConnector, extractToNetCDF 
    22 from cows.service.imps.csmlbackend.wms_csmllayer import CSMLwmsLayerMapper, CSMLwmsLayer 
    2319 
    2420 
    25 class CSMLwcsCoverageMapper(CSMLLayerMapper): 
     21class CSMLwcsCoverageMapper(CSMLLayerMapper): #Todo define IwcsCoverageMapper 
    2622    """ 
    2723    Map keyword arguments to a collection of layers (coverages) 
     
    3531    def getInfo(self, feature): 
    3632        ''' given a csml feature, return info about the layer/feature 
    37         @return:   title, abstract, dimensions, units, crss ''' 
     33        @return:   title, abstract, units, crss ''' 
    3834 
    3935        title, abstract = super(CSMLwcsCoverageMapper, self).getInfo(feature) 
    4036        units=feature.getDomainUnits() 
    41         dimensions={} 
    4237        tmpunits=copy(units) 
    4338        tmpunits.reverse() 
    44         domain = feature.getDomain() 
    45         for dim in feature.getAxisLabels(): 
    46             nextdim=CSMLwmsDimension(domain, dim, tmpunits.pop()) 
    47             if dim not in ['latitude', 'longitude']: 
    48                 dimensions[dim]=nextdim 
     39#        domain = feature.getDomain()  
    4940        crs=feature.getNativeCRS() 
    5041        crss=[self._crscat.getCRS(crs).twoD] 
     
    5243            crss.append('CRS:84') 
    5344            crss.append('WGS84') 
    54         return title, abstract, dimensions, units, crss 
     45        return title, abstract, units, crss 
    5546        
    5647         
     
    7364        self._crscat=csml.csmllibs.csmlcrs.CRSCatalogue() 
    7465        for feature in csml.csmllibs.csmlextra.listify(ds.featureCollection.featureMembers): 
    75             title, abstract, dimensions, units, crss=self.getInfo(feature) 
    76             layermap[feature.id]=CSMLCoverage(title,abstract, dimensions, units, crss, feature) 
     66            title, abstract, units, crss=self.getInfo(feature) 
     67            layermap[feature.id]=CSMLCoverage(title,abstract, units, crss, feature) 
    7768        if len(layermap) > 0: 
    7869            self.layermapcache[fileoruri]=layermap 
     
    8172            raise ValueError 
    8273 
    83 class CoverageDescription(DatasetSummary): 
     74class CoverageDescription(DatasetSummary): #ToDo define ICoverageDescription? 
    8475    """ 
    8576    Extends DatasetSummary from cows.model.contents 
     
    9283 
    9384 
    94 class CSMLCoverage(): #TODO implements ICoverage 
     85class CSMLCoverage(): #TODO: define ICoverage 
    9586    """ represents a WCS Coverage. Implements ICoverage """ 
    9687     
    97     def __init__(self, title, abstract, dimensions, units, crss, feature): 
     88    def __init__(self, title, abstract, units, crss, feature): 
    9889        self.title=title 
    9990        self.abstract=abstract 
    100         self.dimensions=dimensions 
    10191        self.description='TO DO - coverage description' 
    10292        self.timeLimits='t1, t2' 
     
    184174        return filename 
    185175         
    186          
    187          
    188 #         
    189 #        #unicode conversion 
    190 #        for dimval in dimValues: 
    191 #            if dimval != 'time': 
    192 #                dimValues[dimval]=float(dimValues[dimval]) 
    193 #            else: 
    194 #                #remove any trailing Zs from time string 
    195 #                if dimValues[dimval] [-1:] in ['Z', 'z']: 
    196 #                    dimValues[dimval]=dimValues[dimval][:-1] 
    197 #        if type(self._feature) == csml.parser.GridSeriesFeature: 
    198 #            randomname= csml.csmllibs.csmlextra.getRandomID() + '.nc' 
    199 #            result= self._feature.subsetToGridSeries(config['tmpfilebuffer'], ncname=randomname, **dimValues) 
    200 #            return result[1] 
    201 #        else: 
    202 #            raise NotImplementedError 
    203      
    204      
    205     def getCacheKey(self, crs, dimValues=None): 
    206         """ 
    207         Create a unique key for use in caching a slab. 
    208  
    209         The intention here is that most of the work should be done when 
    210         instantiating an ILayerSlab object.  These can be cached by the 
    211         server for future use.  The server will first call getCacheKey() 
    212         for the slab creation arguments and if the key is in it's cache 
    213         it will use a pre-generated ILayerSlab object. 
    214  
    215         """ 
    216         dimList = list(dimValues.items()) 
    217         dimList.sort() 
    218         return '%s:%s' % (crs, dimList) 
    219      
    220 #class CSMLwcsLayer(CSMLwmsLayer): 
    221 #    """ 
    222 #     representing a WMS layer.    Implements IwmsLayer 
    223 # 
    224 #    @ivar title: The layer title.  As seen in the Capabilities document. 
    225 #    @ivar abstract:  Abstract as seen in the Capabilities document. 
    226 #    @ivar dimensions: A dictionary of IDimension objects. 
    227 #    @ivar units: A string describing the units. 
    228 #    @ivar crss: A sequence of SRS/CRSs supported by this layer. 
    229 # 
    230 #    @todo: Do we need minValue/maxValue? 
    231 # 
    232 #    """ 
    233 #     
    234 #    def __init__(self, title, abstract, dimensions, units, crss, feature): 
    235 #        self.featureInfoFormats=None #NotImplemented 
    236 #        self.title=title 
    237 #        self.abstract=abstract 
    238 #        self.dimensions=dimensions 
    239 #        self.units=units 
    240 #        self.crss=crss 
    241 #        self._feature=feature 
    242 #        self.legendSize=(30,100) 
    243 #        bb= self._feature.getCSMLBoundingBox().getBox() 
    244 #        #convert 0 - 360 to -180, 180 as per common WMS convention 
    245 #        if abs(bb[2]-bb[0]) >= 359 and abs(bb[2]-bb[0]) < 361: 
    246 #            bb[0], bb[2]=-180, 180 
    247 #        self.wgs84BBox = bb 
    248 #        self.featureInfoFormats = ['text/html'] 
    249 #        try: 
    250 #            self.wgs84BBox = self.getBBox('EPSG:4326') 
    251 #        except: 
    252 #            raise ValueError("Layer must provide a bounding box in EPSG:4326 " 
    253 #                             "coordinates for compatibility with WMS-1.3.0") 
    254 #        self.featureinfofilecache={} #used for caching netcdf file in getFeatureInfo 
    255 #         
    256 #    def getBBox(self, crs): 
    257 #        """ 
    258 #        @return: A 4-typle of the bounding box in the given coordinate 
    259 #            reference system. 
    260 #        """ 
    261 #        #bb= self._feature.getCSMLBoundingBox().getBox() 
    262 #        #convert 0 - 360 to -180, 180 as per common WMS convention 
    263 #        #if abs(bb[2]-bb[0]) >= 359 and abs(bb[2]-bb[0]) < 361: 
    264 #        #    bb[0], bb[2]=-180, 180 
    265 #        #self.wgs84BBox = bb 
    266 #        return self.wgs84BBox 
    267 #        #raise NotImplementedError 
    268 #     
    269 #    def getSubset(self, crs, dimValues=None): 
    270 #        """ 
    271 #        Creates a subset of the layer in a particular CRS and set of 
    272 #        dimensions. 
    273 # 
    274 #        @param crs: The coordinate reference system. 
    275 #        @param dimValues: A mapping of dimension names to dimension values 
    276 #            as specified in the IDimension.extent 
    277 #        @param renderOpts: A generic mapping object for passing rendering 
    278 #            options 
    279 #        @return: An object implementing ILayerSlab 
    280 #        #create netcdf for whole lat/lon for given dimValues, use to init slab 
    281 #        """ 
    282 # 
    283 #        log.debug('getSlab(%s, %s)' % (crs, dimValues)) 
    284 #         
    285 #        #unicode conversion 
    286 #        for dimval in dimValues: 
    287 #            if dimval != 'time': 
    288 #                dimValues[dimval]=float(dimValues[dimval]) 
    289 #            else: 
    290 #                #remove any trailing Zs from time string 
    291 #                if dimValues[dimval] [-1:] in ['Z', 'z']: 
    292 #                    dimValues[dimval]=dimValues[dimval][:-1] 
    293 #        if type(self._feature) == csml.parser.GridSeriesFeature: 
    294 #            randomname= csml.csmllibs.csmlextra.getRandomID() + '.nc' 
    295 #            result= self._feature.subsetToGridSeries(config['tmpfilebuffer'], ncname=randomname, **dimValues) 
    296 #            return result 
    297 #        else: 
    298 #            raise NotImplementedError 
    299 #         
    300 ##    def getSlab(self, crs, dimValues=None, renderOpts={}): 
    301 ##        """ 
    302 ##        Creates a slab of the layer in a particular CRS and set of 
    303 ##        dimensions. 
    304 ## 
    305 ##        @param crs: The coordinate reference system. 
    306 ##        @param dimValues: A mapping of dimension names to dimension values 
    307 ##            as specified in the IDimension.extent 
    308 ##        @param renderOpts: A generic mapping object for passing rendering 
    309 ##            options 
    310 ##        @return: An object implementing ILayerSlab 
    311 ##        #create netcdf for whole lat/lon for given dimValues, use to init slab 
    312 ##        """ 
    313 ## 
    314 ##        log.debug('getSlab(%s, %s)' % (crs, dimValues)) 
    315 ##         
    316 ##        #unicode conversion 
    317 ##        for dimval in dimValues: 
    318 ##            if dimval != 'time': 
    319 ##                dimValues[dimval]=float(dimValues[dimval]) 
    320 ##            else: 
    321 ##                #remove any trailing Zs from time string 
    322 ##                if dimValues[dimval] [-1:] in ['Z', 'z']: 
    323 ##                    dimValues[dimval]=dimValues[dimval][:-1] 
    324 ##        if type(self._feature) == csml.parser.GridSeriesFeature: 
    325 ##            randomname= csml.csmllibs.csmlextra.getRandomID() + '.nc' 
    326 ##            result= self._feature.subsetToGridSeries(config['tmpfilebuffer'], ncname=randomname, **dimValues) 
    327 ##            #for now have to read netcdf back from  
    328 ##            #disk (limitiation of CSML api) 
    329 ##            netcdf=cdms.open(result[1]) 
    330 ##            #and then delete the temporary file 
    331 ##            os.system('rm %s'%result[1]) 
    332 ##            bbox=self.getBBox(crs) 
    333 ##            return CSMLwmsLayerSlab(netcdf, self, crs, dimValues, renderOpts, bbox) 
    334 ##        else: 
    335 ##            raise NotImplementedError 
    336 #         
    337 #    def getCacheKey(self, crs, dimValues=None, renderOpts={}): 
    338 #        """ 
    339 #        Create a unique key for use in caching a slab. 
    340 # 
    341 #        The intention here is that most of the work should be done when 
    342 #        instantiating an ILayerSlab object.  These can be cached by the 
    343 #        server for future use.  The server will first call getCacheKey() 
    344 #        for the slab creation arguments and if the key is in it's cache 
    345 #        it will use a pre-generated ILayerSlab object. 
    346 # 
    347 #        """ 
    348 #        dimList = list(dimValues.items()) 
    349 #        dimList.sort() 
    350 #        return '%s:%s' % (crs, dimList) 
    351 # 
    352 #    def getFeatureInfo(self, format, crs, point, dimValues): 
    353 #        """ 
    354 #        Return a response string descibing the feature at a given 
    355 #        point in a given CRS. 
    356 # 
    357 #        Currently only "html" is supported as output format 
    358 # 
    359 #        @param format: One of self.featureInfoFormats.  Defines which 
    360 #            format the response will be in. 
    361 #        @param crs: One of self.crss 
    362 #        @param point: a tuple (x, y) in the supplied crs of the point 
    363 #            being selected. 
    364 #        @param dimValues: A mapping of dimension names to dimension values. 
    365 #        @return: A string containing the response. 
    366 # 
    367 #        """ 
    368 #         
    369 #        #cached netcdf is indexed by a tuple of feature id and dimvalues - i.e. typically a particular time and Z value for that feature. 
    370 #        #look in dictionary for cached copy, and if so use that as the file object. 
    371 #        dictindex=str((self._feature.id, dimValues)) 
    372 #        if dictindex in self.featureinfofilecache: 
    373 #            log.debug('calling cache') 
    374 #            f=self.featureinfofilecache[dictindex] 
    375 #        else: #else, use the csml api to subset the feature afresh 
    376 #            log.debug('not calling cache') 
    377 #            randomname= csml.csmllibs.csmlextra.getRandomID() + '.nc' 
    378 #            result= self._feature.subsetToGridSeries(config['tmpfilebuffer'], ncname=randomname, **dimValues) 
    379 #            #for now have to read netcdf back from disk (limitation of CSML api) 
    380 #            f=cdms.open(result[1]) 
    381 #            #append to cache: 
    382 #            self.featureinfofilecache[dictindex]=f 
    383 #            #and then delete the temporary file 
    384 #            os.system('rm %s'%result[1]) 
    385 #         
    386 #        netcdf = f(self.title)  #netcdf here is a cdms transient variable 
    387 #         
    388 #        
    389 #        #Now grab the netCDF object for the point specified. 
    390 #        #The reason for the 'cob' option is so that if the grid the data  
    391 #        #is defined on does not have a grid point at the point specified,  
    392 #        #we should  still get the nearest location 
    393 #         
    394 #        t_point = netcdf(latitude=(point[1], point[1], 'cob'), longitude=(point[0], point[0], 'cob')) 
    395 #        #now get the value recorded at this location 
    396 #        value = t_point.getValue().tolist() 
    397 #        log.debug(value) 
    398 #        log.debug(t_point.fill_value()) 
    399 #        #and the fill_value too 
    400 #        fill_value = t_point.fill_value() 
    401 #        #value is actually embedded in a multi dimensional list,  
    402 #        #so we need to extract the actual value from the list 
    403 #        while type(value) is list: 
    404 #                value = value[0] 
    405 # 
    406 #        #now check if the value is actually the fill_value rather than  
    407 #        #a value recorded at the point specified 
    408 #        log.debug('%s %s' % (value, fill_value)) 
    409 #        if (2*fill_value) == value: 
    410 #                value = "No value found at position: "+str(point[1])+", "+str(point[0]) 
    411 #        else: 
    412 #                value = "Value found at position: "+str(point[1])+", "+str(point[0])+" is: "+str(value) 
    413 #        # finally return the value 
    414 #        return value 
    415  
    416  
    417 class CSMLwmsDimension(IwmsDimension): 
    418     """ 
    419     implements IDimension 
    420     @ivar units: The units string. 
    421     @ivar extent: Sequence of extent values. 
    422  
    423     """ 
    424      
    425     def __init__(self, domain, dimname, unit): 
    426         self.units = unit 
    427         self.extent = [] 
    428         #patch to handle current limitations of multiple time dimension scanning in csml.  
    429         if string.lower(self.units)[:10] in ['days_since', 'seconds_si', 'minutes_si', 'hours_sinc','months _sin', 'years_sinc']: 
    430             if type(domain[dimname][0]) is not str   : 
    431                 tunits=self.units.replace('_', ' ') 
    432                 for val in domain[dimname]: 
    433                     csmltime= csml.csmllibs.csmltime.UDtimeToCSMLtime(cdtime.reltime(float(val), tunits).tocomp()) 
    434                     self.extent.append(csmltime) 
    435             else: 
    436                 for val in domain[dimname]: 
    437                     self.extent.append(str(val)) 
    438         else: 
    439             for val in domain[dimname]: 
    440                 self.extent.append(str(val)) 
    441         #for time axis replace units with iso string 
    442         if dimname == 'time': 
    443             self.units='ISO8601' 
    444         
Note: See TracChangeset for help on using the changeset viewer.