source: cows/trunk/cows/service/imps/csmlbackend/wcs_csmllayer.py @ 4772

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows/trunk/cows/service/imps/csmlbackend/wcs_csmllayer.py@4772
Revision 4772, 6.4 KB checked in by domlowe, 11 years ago (diff)

adding support for z dimension in WCS requests - axisdescriptions currently stubs

Line 
1"""
2implementation of ILayerMapper, IwmsLayer, IwmsDimension, ILayerSlab interfaces, as defined in wms_iface.py & wxs_iface.py
3
4"""
5import os, string
6import csml
7try:
8    import cdms2 as cdms
9except:
10    import cdms
11from pylons import config, request, session
12from copy import copy
13
14import logging
15log = logging.getLogger(__name__)
16
17from cows.model.wcs import WcsDatasetSummary
18from cows.service.imps.csmlbackend.csmlcommon import CSMLLayerMapper, CSMLConnector, extractToNetCDF
19
20
21class CSMLwcsCoverageMapper(CSMLLayerMapper): 
22    """
23    Map keyword arguments to a collection of layers (coverages)
24    Supports the retrieval of coverages according to arbitrary
25    keyword/value pairs. 
26    """
27    def __init__(self):
28        super(CSMLwcsCoverageMapper, self).__init__()
29       
30   
31    def getInfo(self, feature):
32        ''' given a csml feature, return info about the layer/feature
33        @return:   title, abstract, units, crss '''
34
35        title, abstract = super(CSMLwcsCoverageMapper, self).getInfo(feature)
36        units=feature.getDomainUnits()
37        tmpunits=copy(units)
38        tmpunits.reverse()
39        domain = feature.getDomain()
40        tax= feature.getTimeAxis()
41        timepositions=domain[tax]
42        timelimits=[domain[tax][0],domain[tax][len(domain[tax])-1]] 
43        crs=feature.getNativeCRS()
44        crss=[self._crscat.getCRS(crs).twoD]
45        if 'EPSG:4326' in crss:
46            crss.append('CRS:84')
47            crss.append('WGS84')
48
49        return title, abstract, timepositions, timelimits, units, crss
50           
51    def getCoverageDescription(self):
52        pass
53       
54     
55    def map(self, **kwargs):
56        """
57        Given csml.parser.Dataset object list the names of
58        all layers available.
59       
60        @return: A mapping of layer names to ILayer implementations.
61        @raise ValueError: If no layers are available for these keywords.
62        """
63        fileoruri=kwargs['fileoruri']
64        if fileoruri in self.layermapcache.keys():
65            #we've accessed this layer map before, get it from the cache dictionary
66            return self.layermapcache[fileoruri]
67         
68        ds = self.connector.getCsmlDoc(fileoruri)
69        layermap={}
70        self._crscat=csml.csmllibs.csmlcrs.CRSCatalogue()
71        for feature in csml.csmllibs.csmlextra.listify(ds.featureCollection.featureMembers):
72            title, abstract, timepositions, timelimits, units, crss=self.getInfo(feature)
73            layermap[feature.id]=CSMLCoverage([title],[abstract], timepositions, timelimits, units, crss, feature)
74        if len(layermap) > 0:
75            self.layermapcache[fileoruri]=layermap
76            return layermap
77        else:
78            raise ValueError
79
80class AxisDescription(object):
81    """ represents an axisDescription from the rangeSet (see wcs 1.0.0 describe coverage) """
82    def __init__(self):
83        self.name='air_pressure'
84        self.label='air_pressure'
85        self.values=[10, 30, 50, 100, 150, 200, 250, 300, 400, 500, 600, 700, 850, 950,1000]
86
87class CSMLCoverage(object): #TODO: define ICoverage
88    """ represents a WCS Coverage. Implements ICoverage """
89   
90    def __init__(self, title, abstract, timepositions, timelimits, units, crss, feature):
91        self.title=title
92        self.abstract=abstract
93        self.description='TO DO - coverage description'
94        self.timePositions=timepositions
95        self.timeLimits=timelimits
96        self.units=units
97        self.crss=crss
98        self._feature=feature
99        self.id=feature.id
100        bb = self._feature.getCSMLBoundingBox().getBox()
101        #convert 0 - 360 to -180, 180 as per common WXS convention
102        if abs(bb[2]-bb[0]) >= 359 and abs(bb[2]-bb[0]) < 361:
103            bb[0], bb[2]=-180, 180
104        self.wgs84BBox = bb
105        self.featureInfoFormats = ['text/html']
106        self.axisDescriptions = [AxisDescription()]
107   
108    def getBBox(self, crs):
109        """
110        @return: A 4-typle of the bounding box in the given coordinate
111            reference system.
112        """
113        #TODO: make this generic
114        return self.wgs84BBox
115   
116    def getCvg(self, bbox, time=None, crs=None, response_crs=None, **kwargs):
117        """
118        Creates a subset of the layer in a particular CRS and set of
119        dimensions.
120        #TODO: this is all out of synch
121        @param crs: The coordinate reference system.
122        @param dimValues: A mapping of dimension names to dimension values
123            as specified in the IDimension.extent
124        @param renderOpts: A generic mapping object for passing rendering
125            options
126        @return: An object implementing ILayerSlab
127        #create netcdf for whole lat/lon for given dimValues, use to init slab
128        """
129
130        log.debug('WCS: getSubset(%s, %s, %s)' % (bbox, time, crs))
131        #unpack the Boundingbox.
132       
133       
134        ############################# from old WCS stack #################
135        boundingbox=bbox
136        lon=self._feature.getLongitudeAxis()
137        lat=self._feature.getLatitudeAxis()
138        t=self._feature.getTimeAxis()
139        if None in [lon, lat, t]:
140            #TODO need to return a suitable wcs error.
141            log.debug('warning, could not get correct axis info')
142            #best guess!
143            if t is None:
144                t='time'
145            if lon is None:
146                lon = 'longitude'
147            if lat is None:
148                lat = 'latitude'
149       
150        #create selection dictionary:
151        sel={}
152        sel[lat]=(boundingbox[1], boundingbox[3])
153        sel[lon]=(boundingbox[0], boundingbox[2])
154        if time is not None:
155            if  type(time) is unicode:
156                sel[t]=str(time)
157            else:
158                sel[t]=time
159               
160        #z is the 4th axis/band (eg height or pressure or wavelength) requested via kwargs as defined in the rangeset.axisDescriptions.
161        for kw in kwargs:
162            log.debug(kw)
163            log.debug(self._feature.getAxisLabels())
164            for ax in self._feature.getAxisLabels():
165                if ax not in [lat, lon, t]:
166                    if ax == kw:
167                        z=str(ax)
168                        sel[z]=(kwargs[kw])
169                        log.debug('Z axis: %s'%z)     
170        ##################################################################
171        log.debug('Final selection being made to the csml api %s'%str(sel))
172        filename = extractToNetCDF(self._feature, sel)
173        return filename
174       
Note: See TracBrowser for help on using the repository browser.