source: cows/trunk/cows/service/imps/data_reader_geoplot_backend/data_readers/csml_data_reader.py @ 5692

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows/trunk/cows/service/imps/data_reader_geoplot_backend/data_readers/csml_data_reader.py@5692
Revision 5692, 5.6 KB checked in by pnorton, 11 years ago (diff)

Made some modifications to the data renderer backend. The display options are now attached to each of the slabs rather than being stored in the shared option parser and the controller.

I've also added some code to generate the display options JSON string.

Line 
1
2import os
3
4import csml
5import cdms2 as cdms
6from copy import copy
7
8from cows.service.imps.csmlbackend.config import config
9from cows.service.imps.csmlbackend.csmlcommon import CSMLConnector
10from cows.service.imps.csmlbackend.wms_csmllayer import CSMLwmsDimension
11
12import logging
13
14log = logging.getLogger(__name__)
15
16#
17# Global CSML connector instance
18#
19globalCSMLConnector = CSMLConnector()
20
21
22class CSMLDataReader(object):
23   
24    def __init__(self, fileoruri):
25        self._crscat=csml.csmllibs.csmlcrs.CRSCatalogue()
26        self.connector = globalCSMLConnector
27        self.fileoruri = fileoruri
28        self.ds = self.connector.getCsmlDoc(fileoruri)
29        self.varcache = {} 
30   
31    def getWMSLayerInfo(self):
32       
33        for feature in csml.csmllibs.csmlextra.listify(self.ds.featureCollection.featureMembers):
34            log.debug("feature.id = %s" % (feature.id,))
35            title, abstract, dimensions, units, crss=self._getWMSInfo(feature)
36            bb = self._getBBox(feature)
37            name = feature.id
38           
39            yield (name, title, abstract, dimensions, units, crss, bb) 
40
41   
42    def _getFeatureTitleAndAbstract(self, feature):
43        ''' given a csml feature, return basic info about the layer/feature/coverage
44        @return:   title, abstract'''
45
46        try:
47            title=feature.name.CONTENT
48        except:
49            title=''
50           
51        try:
52            abstract=feature.description.CONTENT
53        except:
54            abstract=title
55       
56        return title, abstract   
57
58    def _getBBox(self, feature):
59        try: 
60            bb = feature.getCSMLBoundingBox().getBox()
61        except:
62            #default to global
63            bb=[-180,-90,180,90]
64        return bb       
65
66    def _getWMSInfo(self, feature):
67        ''' given a csml feature, return info about the layer/feature
68        @return:   title, abstract, dimensions, units, crss '''
69
70        title, abstract = self._getFeatureTitleAndAbstract(feature)
71        units=feature.getDomainUnits() 
72        dimensions={}
73        tmpunits=copy(units)
74        tmpunits.reverse()
75        domain = feature.getDomain()
76       
77        for dim in feature.getAxisLabels():
78            nextdim=CSMLwmsDimension(domain, dim, tmpunits.pop())
79           
80            if dim not in ['latitude', 'longitude']:
81                dimensions[dim]=nextdim
82               
83        crs=feature.getNativeCRS()
84        crss=[self._crscat.getCRS(crs).twoD]
85       
86        if 'EPSG:4326' in crss:
87            crss.append('CRS:84')
88            crss.append('WGS84')
89                   
90        #the units to return are the units of measure.
91        try:
92            units=feature.value.rangeSet.valueArray.valueComponent.uom
93        except:
94            units='unknown units'
95           
96        return title, abstract, dimensions, units, crss
97
98    def _getFeature(self, id):
99        for feature in csml.csmllibs.csmlextra.listify(self.ds.featureCollection.featureMembers):
100           if feature.id == id:
101               return feature
102           
103        raise Exception("Feature with id %s not found" % (id,))
104 
105
106    def getNetcdfVar(self, featureId,  dimValues):
107        "Opens up the csml and retrieves the variable described by the dimensions"
108       
109
110        log.debug("featureId = %s, dimValues = %s" % (featureId, dimValues))
111       
112        dimList = list(dimValues.items())
113        dimList.sort()
114       
115        cacheKey = "%s:%s" % (featureId, dimList)
116
117        if cacheKey not in self.varcache:
118       
119            feature = self._getFeature(featureId)
120           
121            convertedDimVals = self._convertDimValues(dimValues)
122                 
123            if type(feature) == csml.parser.GridSeriesFeature:
124               
125                randomname= csml.csmllibs.csmlextra.getRandomID() + '.nc'
126               
127                log.debug("getting csml feature")
128               
129                result= feature.subsetToGridSeries(config['tmpdir'], 
130                                            ncname=randomname, **convertedDimVals)
131               
132                #for now have to read netcdf back from
133                #disk (limitiation of CSML api)
134                netcdf=cdms.open(result[1])
135               
136                #and then delete the temporary file
137                os.system('rm %s'%result[1])
138               
139                log.debug("removed temp file %s" % (result[1],))
140               
141            else:
142                raise NotImplementedError
143           
144            variable =  netcdf(feature.id, squeeze=1)
145           
146            self.varcache[cacheKey] = variable
147        else:
148            variable = self.varcache[cacheKey]
149       
150        return variable
151   
152       
153    def _convertDimValues(self, dimValues):
154        """
155        Converts the string dimension values to floats (except for time values)
156        """
157        convertedVals = {}
158       
159        for dimval in dimValues:
160            if dimval != 'time':
161                convertedVals[dimval]=float(dimValues[dimval])
162            else:
163                #remove any trailing Zs from time string
164                if dimValues[dimval] [-1:] in ['Z', 'z']:
165                    convertedVals[dimval]=dimValues[dimval][:-1]
166                else:
167                    convertedVals[dimval] = dimValues[dimval] 
168
169        return convertedVals
170   
171    @staticmethod
172    def isDataPresent(fileoruri):
173        global globalCSMLConnector
174       
175        log.debug("globalCSMLConnector.list() = %s" % ([x for x in globalCSMLConnector.list()],))
176        for file in globalCSMLConnector.list():
177            log.debug("file = %s" % (file,))
178            if file == fileoruri:
179                return True
180           
181        return False
Note: See TracBrowser for help on using the repository browser.