source: cows/branches/wcsmerge/cows/service/imps/csmlbackend/wcs_csmllayer.py @ 4635

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows/branches/wcsmerge/cows/service/imps/csmlbackend/wcs_csmllayer.py@4635
Revision 4635, 6.2 KB checked in by domlowe, 12 years ago (diff)

more merging - capabilities doc looking better.

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.contents import DatasetSummary
18from cows.service.imps.csmlbackend.csmlcommon import CSMLLayerMapper, CSMLConnector, extractToNetCDF
19
20
21class CSMLwcsCoverageMapper(CSMLLayerMapper): #Todo define IwcsCoverageMapper
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        timelimits=[domain[tax][0],domain[tax][len(domain[tax])-1]] 
42        crs=feature.getNativeCRS()
43        crss=[self._crscat.getCRS(crs).twoD]
44        if 'EPSG:4326' in crss:
45            crss.append('CRS:84')
46            crss.append('WGS84')
47
48        return title, abstract, timelimits, units, crss
49       
50       
51     
52    def map(self, **kwargs):
53        """
54        Given csml.parser.Dataset object list the names of
55        all layers available.
56       
57        @return: A mapping of layer names to ILayer implementations.
58        @raise ValueError: If no layers are available for these keywords.
59        """
60        fileoruri=kwargs['fileoruri']
61        if fileoruri in self.layermapcache.keys():
62            #we've accessed this layer map before, get it from the cache dictionary
63            return self.layermapcache[fileoruri]
64         
65        ds = self.connector.getCsmlDoc(fileoruri)
66        layermap={}
67        self._crscat=csml.csmllibs.csmlcrs.CRSCatalogue()
68        for feature in csml.csmllibs.csmlextra.listify(ds.featureCollection.featureMembers):
69            title, abstract, timelimits, units, crss=self.getInfo(feature)
70            layermap[feature.id]=CSMLCoverage([title],[abstract], timelimits, units, crss, feature)
71        if len(layermap) > 0:
72            self.layermapcache[fileoruri]=layermap
73            return layermap
74        else:
75            raise ValueError
76
77class CoverageDescription(DatasetSummary): #ToDo define ICoverageDescription?
78    """
79    Extends DatasetSummary from cows.model.contents
80    """
81    def __init__(self, identifier, timeDomain, crs=None, **kw):
82        super(CoverageDescription, self).__init__(**kw)
83        self.identifier=identifier
84        self.timeLimits=timeDomain
85        self.crs=crs
86
87
88class CSMLCoverage(): #TODO: define ICoverage
89    """ represents a WCS Coverage. Implements ICoverage """
90   
91    def __init__(self, title, abstract, timelimits, units, crss, feature):
92        self.title=title
93        self.abstract=abstract
94        self.description='TO DO - coverage description'
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       
107    def getDescription(self):
108        pass
109   
110    def getBBox(self, crs):
111        """
112        @return: A 4-typle of the bounding box in the given coordinate
113            reference system.
114        """
115        #TODO: make this generic
116        return self.wgs84BBox
117   
118    def getCvg(self, bbox, time=None, crs=None, response_crs=None):
119        """
120        Creates a subset of the layer in a particular CRS and set of
121        dimensions.
122        #TODO: this is all out of synch
123        @param crs: The coordinate reference system.
124        @param dimValues: A mapping of dimension names to dimension values
125            as specified in the IDimension.extent
126        @param renderOpts: A generic mapping object for passing rendering
127            options
128        @return: An object implementing ILayerSlab
129        #create netcdf for whole lat/lon for given dimValues, use to init slab
130        """
131
132        log.debug('WCS: getSubset(%s, %s, %s)' % (bbox, time, crs))
133        #unpack the Boundingbox.
134       
135       
136        ############################# from old WCS stack #################
137        boundingbox=bbox
138        lon=self._feature.getLongitudeAxis()
139        lat=self._feature.getLatitudeAxis()
140        t=self._feature.getTimeAxis()
141        if None in [lon, lat, t]:
142            #TODO need to return a suitable wcs error.
143            print 'warning, could not get correct axis info'
144            #best guess!
145            if t is None:
146                t='time'
147            if lon is None:
148                lon = 'longitude'
149            if lat is None:
150                lat = 'latitude'
151       
152        #create selection dictionary:
153        sel={}
154        sel[lat]=(boundingbox[1], boundingbox[3])
155        sel[lon]=(boundingbox[0], boundingbox[2])
156        if time is not None:
157            if  type(time) is unicode:
158                sel[t]=str(time)
159            else:
160                sel[t]=time
161        #z is the 4th axis (eg height or pressure).
162        #NOTE, need to decide whether bounding box is of form: x1,y1,z1,x2,y2,z2 or x1,y1,x2,y2,z1,z2
163        #currently the latter is implemented.
164           
165        if len(boundingbox)  == 6:
166            for ax in self._feature.getAxisLabels():
167                if ax not in [lat, lon, t]:
168                    #must be Z 
169                    z=str(ax)
170                    sel[z]=(boundingbox[4], boundingbox[5])
171           
172           
173        axisNames=self._feature.getAxisLabels()
174        ##################################################################
175       
176        filename = extractToNetCDF(self._feature, sel)
177        return filename
178       
Note: See TracBrowser for help on using the repository browser.