source: cows/trunk/cows/pylons/wfs_controller.py @ 4398

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/cows/trunk/cows/pylons/wfs_controller.py@4398
Revision 4398, 6.7 KB checked in by domlowe, 11 years ago (diff)

Adding stub code for WFS 2.0 stored query implementation

Line 
1"""
2WFS controller for OGC Web Services (OWS).
3
4@author: Dominic Lowe
5"""
6
7import re
8from cStringIO import StringIO
9from sets import Set
10from matplotlib.cm import get_cmap
11from pylons import request, response, c, config
12import ConfigParser
13
14import logging
15log = logging.getLogger(__name__)
16
17import Image
18
19from cows.model.wfs import WfsFeatureSummary
20from cows.model.filterencoding import FEQueryProcessor
21from cows.model import PossibleValues, WGS84BoundingBox, BoundingBox, Contents
22from cows.pylons import ows_controller
23from cows.exceptions import *
24from cows import bbox_util
25
26class WFSController(ows_controller.OWSController):
27    """
28    Subclass this controller in a pylons application and set the layerMapper
29    class attribute to implement a WFS. Each layer can be mapped to a Feature for the WFS.
30
31    @cvar layerMapper: an cows.service.wxs_iface.ILayerMapper object.
32   
33
34    """
35    layerMapper = None
36    _layerSlabCache = {}
37
38    #-------------------------------------------------------------------------
39    # Attributes required by OWSController
40
41    service = 'WFS'
42    owsOperations = (ows_controller.OWSController.owsOperations + ['DescribeFeatureType', 'GetFeature', 'DescribeStoredQueries'])
43    validVersions = ['1.1.0', '2.0.0']
44   
45
46    #-------------------------------------------------------------------------
47
48    def __before__(self, **kwargs):
49        """
50        This default implementation of __before__() will pass all routes
51        arguments to the layer mapper to retrieve a list of layers for
52        this WFS.
53
54        It will be called automatically by pylons before each action method.
55
56
57        """
58        log.debug('loading layers')
59        self.layers, self.featureset = self.layerMapper.map(**kwargs)
60        log.debug('Feature instances %s'%self.featureset.featureinstances)
61   
62        #-------------------------------------------------------------------------
63        # Methods implementing stubs in OWSController
64
65    def _renderCapabilities(self, version, format):
66        """
67        Renders capabilities document.
68        """
69        if version == '1.1.0':
70            t = ows_controller.templateLoader.load('wfs_capabilities_1_1_0.xml')
71        elif version == '2.0.0':
72            t = ows_controller.templateLoader.load('wfs_capabilities_2_0_0.xml')
73        else:
74            # We should never get here!  The framework should raise an exception before now.
75            raise RuntimeError("Version %s not supported" % version)
76       
77        return t.generate(c=c).render()
78
79    def _loadCapabilities(self):
80        """
81        @note: Assumes self.layers has already been created by __before__().
82        Builds capabilities document.
83
84        """
85        log.info('Loading WFS Capabilites')
86       
87        ows_controller.addOperation('GetFeature')
88        ows_controller.addOperation('DescribeFeature')
89        ows_controller.addOperation('DescribeStoredQueries')
90       
91       
92        featureInfoFormats = Set()
93
94        log.debug('Loading capabilities contents')
95        c.capabilities.contents = Contents()
96       
97       
98        ftlist={}
99        #       
100       
101        for layerName, layer in self.layers.items():
102            log.info('Loading layer %s' % layerName)
103#            log.info('feature type %s'%layer._feature)
104
105            wgs84BBox = WGS84BoundingBox(layer.wgs84BBox[:2],
106                                         layer.wgs84BBox[2:])
107           
108            ds = WfsFeatureSummary(keywords=layer.keywords, 
109                                   outputformats=layer.outputformats, 
110                                   identifier=layerName,
111                                   titles=[layer.title],
112                                   abstracts=[layer.abstract],                                   
113                                   wgs84BoundingBoxes=[wgs84BBox])
114
115            c.capabilities.contents.datasetSummaries.append(ds)
116
117    def _buildStoredQueries(self):
118        return self.layerMapper.queryDescriptions.queries
119
120    def _getSchema(self, typename):
121        namespace = typename.split(':')[0]
122        schemalocation = conf
123       
124    def _parsetypename(self, typename):
125        """ parse feature type name into schema and name"""       
126        if typename not in self.layers.keys():
127            raise InvalidParameterValue('Invalid typename parameter: %s. Typename must consist of namespace and featuretype separated with a colon, as displayed in the GetCapabilities response.'%typename, 'typename')
128   
129        namespace, ft = typename.split(':')
130        wfsconfiglocation=config['wfsconfig']
131        wfscfg = ConfigParser.ConfigParser()
132        wfscfg.read(wfsconfiglocation)     
133        xmlschema=open(wfscfg.get('application_schemas', namespace)).read()     
134        log.debug('location of application schema %s' %(xmlschema))
135        return xmlschema
136
137    def DescribeFeatureType(self):
138        """ DescribeFeatureType """
139        version = self.getOwsParam('version', default=self.validVersions[0])
140        if version not in self.validVersions:
141            raise InvalidParameterValue('Version %s not supported' % version,
142                                        'version')
143        typename=self.getOwsParam('typename')
144        ftschema =self._parsetypename(typename)
145        log.debug(self.layers.items())       
146               
147        outputformat=self.getOwsParam('outputformat', default='text/xml')
148       
149        #temporarily returns entire schema
150        #TODO: return single featuretype definition
151        msg  = ftschema
152        response.headers['content-type'] = 'text/xml'
153        return msg
154 
155    def GetFeature(self):
156        """ GetFeature request
157        """
158        #TODO QUERY model
159        version = self.getOwsParam('version', default=self.validVersions[0])
160        if version not in self.validVersions:
161            raise InvalidParameterValue('Version %s not supported' % version,
162                                        'version')
163
164        #Parse the query to analyse the filters it contains
165        queryxml=self.getOwsParam('query')
166        qp=FEQueryProcessor()
167        c.resultset=qp.evaluate(self.featureset, queryxml)
168        log.debug('Final resultset from query processor %s'%c.resultset)
169       
170       
171        #Group resultset together in a wfs feature collection (use template)
172        response.headers['content-type'] = 'text/xml'
173        t = ows_controller.templateLoader.load('wfs_featurecollection.xml')
174        return t.generate(c=c).render()           
175
176
177   
178    def DescribeStoredQueries(self):
179        """ DescribeStoredQueries method. Takes zero or more stored query ids as args"""
180        c.storedqueries = self._buildStoredQueries()
181        t = ows_controller.templateLoader.load('wfs_describestoredqueries.xml')
182        return t.generate(c=c).render() 
183         
Note: See TracBrowser for help on using the repository browser.