source: TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/csml_util.py @ 3090

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI05-delivery/ows_framework/trunk/ows_server/ows_server/lib/csml_util.py@3090
Revision 3090, 6.2 KB checked in by domlowe, 12 years ago (diff)

support for ragged section in wcs

Line 
1# Copyright (C) 2007 STFC & NERC (Science and Technology Facilities Council).
2# This software may be distributed under the terms of the
3# Q Public License, version 1.0 or later.
4# http://ndg.nerc.ac.uk/public_docs/QPublic_license.txt
5"""
6csml access routines.
7
8@author: Stephen Pascoe
9"""
10from pylons import Response, c, g, cache, request, session
11import csml, cdms
12import os, string
13import zipfile
14import tempfile
15from ows_server.models import ndgObject,ndgRetrieve
16
17def get_csml_doc(fileoruri):
18        """
19        Gets a csml document from file or exist when passed a file name or uri         
20               
21        Note, access control is not implemented on file access, only on exist access.
22       
23        """
24        if string.find(fileoruri,'__NDG-A0__') == -1:
25            #it's a local file not an identifier
26            file=fileoruri
27            csml_dir = request.environ['paste.config']['app_conf']['csml_dir']
28            path = os.path.join(csml_dir, file)
29            if os.path.exists(path+'.csml'):
30                f = path+'.csml'
31            elif os.path.exists(path+'.xml'):
32                f = path +'.xml'
33            else:
34                raise ValueError("Cannot find CSML file %s" % file)
35           
36            d = csml.parser.Dataset()
37            d.parse(f)
38       
39        else:
40            #it's an NDG identifier, get the document from exist.
41            uri=fileoruri
42            uriN=ndgObject.ndgObject(uri)
43            cf=request.environ['ndgConfig']
44            requestor=request.environ['REMOTE_ADDR']
45            if 'ndgSec' in session:
46                securityTokens=session['ndgSec']
47            else: securityTokens=None
48            status,x=ndgRetrieve.ndgRetrieve(
49                    uriN,cf,requestor=requestor,
50                    securityTokens=securityTokens)
51            d=csml.parser.Dataset()
52            if type(x) is str:
53                #then its an access denied message or similar:
54                return x
55            d.parseElemTree(x.tree)                   
56        return d
57
58#this version of get_csml_doc can be deleted now if no problems found with new version:
59#def get_csml_doc(file):
60    #"""
61    #A trivial document retrieval function.
62
63    #This could be replaced with a proper csml server object that supports
64    #multiple stores (filesystem, exist) and cache's the results for
65    #performance.
66
67    #"""
68    #csml_dir = request.environ['paste.config']['app_conf']['csml_dir']
69    #path = os.path.join(csml_dir, file)
70    #if os.path.exists(path+'.csml'):
71        #f = path+'.csml'
72    #elif os.path.exists(path+'.xml'):
73        #f = path +'.xml'
74    #else:
75        #raise ValueError("Cannot find CSML file %s" % file)
76   
77    #d = csml.parser.Dataset()
78    #d.parse(f)
79     
80    #return d
81
82       
83def extractToNetCDF(feature, sel, publish=False):
84    """
85       performs the CSML subset and returns a filename of the netcdf extract
86       publish flag is used to indicate that the netcdf file should be made available to the webserver (for asynchronous delivery)
87    """
88
89    if publish:
90        #if publishing to download directory is required, do so and return publishable file name
91        #used e.g. in WCS when "STORE = true"
92        extract_dir=request.environ['paste.config']['app_conf']['publish_dir']
93    else:
94        extract_dir = request.environ['paste.config']['app_conf']['tmp_dir']
95         
96    # Subset the feature
97    (fd, filename) = tempfile.mkstemp('.nc', 'csml_wxs_', extract_dir); os.close(fd)
98    if type(feature) is csml.parser.GridSeriesFeature:
99        feature.subsetToGridSeries(ncname=os.path.basename(filename), outputdir=os.path.dirname(filename) ,**sel)
100    elif type(feature) is csml.parser.TrajectoryFeature:
101        feature.subsetToTrajectory(ncname=os.path.basename(filename), outputdir=os.path.dirname(filename) ,**sel)
102    elif type(feature) is csml.parser.PointSeriesFeature:
103        del sel['longitude'] #delete dummy values
104        del sel['latitude'] #delete dummy values
105        feature.subsetToPointSeries(ncname=os.path.basename(filename), outputdir=os.path.dirname(filename) ,**sel)
106    elif type(feature) is csml.parser.RaggedSectionFeature:
107        del sel['longitude'] #delete dummy values
108        del sel['latitude'] #delete dummy values
109        feature.subsetByTime(ncname=os.path.basename(filename), outputdir=os.path.dirname(filename) ,**sel)
110    return filename
111       
112def extractToVariable(feature, sel):
113    """
114      calls extractToNetCDF to get the netcdf file, then returns a cdms variable from this file
115    """
116    #call extractToNetCDF:
117    filename = extractToNetCDF(feature, sel)
118    d = cdms.open(filename)
119    var = d(feature.name.CONTENT, squeeze=1)
120    # Work around for CSML bug
121    #var = d(feature.name.CONTENT, longitude=sel['longitude'], latitude=sel['latitude'],
122    #        squeeze=1)
123
124    d.close()
125    #os.remove(filename)
126    return var
127       
128class CsmlBundle(csml.API.csmlContainer.Container):
129    """
130    A quick stab at bundling CSML.
131
132    """
133    def __init__(self, context, **kwargs):
134        """
135        @param context: A directory path to store the CSML and NetCDF
136        """
137        self.context = context
138        kwargs['csmlpath'] = os.path.join(context, 'container.xml')
139        super(CsmlBundle, self).__init__(**kwargs)
140
141    def add(self, fpd):
142        """
143        Overrides the file storage descriptor so that the CSML points relative to the
144        bundle context
145
146        @warning: THIS IS A HACK!
147
148        """
149        (feature, path, desc) = fpd
150        if os.path.dirname(path) != self.context:
151            raise ValueError, "Extract not in bundle context"
152        desc.fileName.CONTENT = os.path.basename(path)
153
154        return super(CsmlBundle, self).add(fpd)
155
156    def join(self, *p):
157        return os.path.join(self.context, *p)
158
159    def makeBundle(self, file, bundleName=None):
160        """
161        Writes the bundle to a zipfile.
162
163        @param file: path or file-like object (see zipfile docs)
164
165        """
166        if bundleName is None:
167            bundleName = os.path.splitext(os.path.basename(file))[0]
168       
169        zf = zipfile.ZipFile(file, 'w')
170        self.getContents()
171        for f in self.containerContents:
172            zf.write(f, os.path.join(bundleName, os.path.basename(f)))
173        zf.close()
174
175        return file
Note: See TracBrowser for help on using the repository browser.