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

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

pointseries subsetting workign 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       
107    return filename
108       
109def extractToVariable(feature, sel):
110    """
111      calls extractToNetCDF to get the netcdf file, then returns a cdms variable from this file
112    """
113    #call extractToNetCDF:
114    filename = extractToNetCDF(feature, sel)
115    d = cdms.open(filename)
116    var = d(feature.name.CONTENT, squeeze=1)
117    # Work around for CSML bug
118    #var = d(feature.name.CONTENT, longitude=sel['longitude'], latitude=sel['latitude'],
119    #        squeeze=1)
120
121    d.close()
122    #os.remove(filename)
123    return var
124       
125class CsmlBundle(csml.API.csmlContainer.Container):
126    """
127    A quick stab at bundling CSML.
128
129    """
130    def __init__(self, context, **kwargs):
131        """
132        @param context: A directory path to store the CSML and NetCDF
133        """
134        self.context = context
135        kwargs['csmlpath'] = os.path.join(context, 'container.xml')
136        super(CsmlBundle, self).__init__(**kwargs)
137
138    def add(self, fpd):
139        """
140        Overrides the file storage descriptor so that the CSML points relative to the
141        bundle context
142
143        @warning: THIS IS A HACK!
144
145        """
146        (feature, path, desc) = fpd
147        if os.path.dirname(path) != self.context:
148            raise ValueError, "Extract not in bundle context"
149        desc.fileName.CONTENT = os.path.basename(path)
150
151        return super(CsmlBundle, self).add(fpd)
152
153    def join(self, *p):
154        return os.path.join(self.context, *p)
155
156    def makeBundle(self, file, bundleName=None):
157        """
158        Writes the bundle to a zipfile.
159
160        @param file: path or file-like object (see zipfile docs)
161
162        """
163        if bundleName is None:
164            bundleName = os.path.splitext(os.path.basename(file))[0]
165       
166        zf = zipfile.ZipFile(file, 'w')
167        self.getContents()
168        for f in self.containerContents:
169            zf.write(f, os.path.join(bundleName, os.path.basename(f)))
170        zf.close()
171
172        return file
Note: See TracBrowser for help on using the repository browser.