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

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

Refactored filterencoding to make it more flexible, including adding logical operators.

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'])
43    validVersions = ['1.1.0']
44
45    #-------------------------------------------------------------------------
46
47    def __before__(self, **kwargs):
48        """
49        This default implementation of __before__() will pass all routes
50        arguments to the layer mapper to retrieve a list of layers for
51        this WFS.
52
53        It will be called automatically by pylons before each action method.
54
55
56        """
57        log.debug('loading layers')
58        self.layers, self.featureset = self.layerMapper.map(**kwargs)
59        log.debug('Feature instances %s'%self.featureset.featureinstances)
60   
61        #-------------------------------------------------------------------------
62        # Methods implementing stubs in OWSController
63
64    def _renderCapabilities(self, version, format):
65        """
66        Renders capabilities document.
67        """
68        if version == '1.1.0':
69            t = ows_controller.templateLoader.load('wfs_capabilities_1_1_0.xml')
70        else:
71            # We should never get here!  The framework should raise an exception before now.
72            raise RuntimeError("Version %s not supported" % version)
73       
74        return t.generate(c=c).render()
75
76    def _loadCapabilities(self):
77        """
78        @note: Assumes self.layers has already been created by __before__().
79        Builds capabilities document.
80
81        """
82        log.info('Loading WFS Capabilites')
83       
84        ows_controller.addOperation('GetFeature')
85        ows_controller.addOperation('DescribeFeature')
86       
87       
88        featureInfoFormats = Set()
89
90        log.debug('Loading capabilities contents')
91        c.capabilities.contents = Contents()
92       
93       
94        ftlist={}
95        #       
96       
97        for layerName, layer in self.layers.items():
98            log.info('Loading layer %s' % layerName)
99#            log.info('feature type %s'%layer._feature)
100
101            wgs84BBox = WGS84BoundingBox(layer.wgs84BBox[:2],
102                                         layer.wgs84BBox[2:])
103           
104            ds = WfsFeatureSummary(keywords=layer.keywords, 
105                                   outputformats=layer.outputformats, 
106                                   identifier=layerName,
107                                   titles=[layer.title],
108                                   abstracts=[layer.abstract],                                   
109                                   wgs84BoundingBoxes=[wgs84BBox])
110
111            c.capabilities.contents.datasetSummaries.append(ds)
112
113    def _getSchema(self, typename):
114        namespace = typename.split(':')[0]
115        schemalocation = conf
116       
117    def _parsetypename(self, typename):
118        """ parse feature type name into schema and name"""       
119        if typename not in self.layers.keys():
120            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')
121   
122        namespace, ft = typename.split(':')
123        wfsconfiglocation=config['wfsconfig']
124        wfscfg = ConfigParser.ConfigParser()
125        wfscfg.read(wfsconfiglocation)     
126        xmlschema=open(wfscfg.get('application_schemas', namespace)).read()     
127        log.debug('location of application schema %s' %(xmlschema))
128        return xmlschema
129
130               
131    def DescribeFeatureType(self):
132        """ DescribeFeatureType """
133        version = self.getOwsParam('version', default=self.validVersions[0])
134        if version not in self.validVersions:
135            raise InvalidParameterValue('Version %s not supported' % version,
136                                        'version')
137        typename=self.getOwsParam('typename')
138        ftschema =self._parsetypename(typename)
139        log.debug(self.layers.items())       
140               
141        outputformat=self.getOwsParam('outputformat', default='text/xml')
142       
143        #temporarily returns entire schema
144        #TODO: return single featuretype definition
145        msg  = ftschema
146        response.headers['content-type'] = 'text/xml'
147        return msg
148 
149    def GetFeature(self):
150        """ GetFeature request
151        """
152        #TODO QUERY model
153        version = self.getOwsParam('version', default=self.validVersions[0])
154        if version not in self.validVersions:
155            raise InvalidParameterValue('Version %s not supported' % version,
156                                        'version')
157
158        #Parse the query to analyse the filters it contains
159        queryxml=self.getOwsParam('query')
160        qp=FEQueryProcessor()
161        c.resultset=qp.evaluate(self.featureset, queryxml)
162        log.debug('Final resultset from query processor %s'%c.resultset)
163       
164       
165        #Group resultset together in a wfs feature collection (use template)
166        response.headers['content-type'] = 'text/xml'
167        t = ows_controller.templateLoader.load('wfs_featurecollection.xml')
168        return t.generate(c=c).render()           
169
170
171#        featureid=self.getOwsParam('featureid')
172#        #TODO populate self.featureinstances!
173#        feature=self.featureset.featureinstances[featureid]   
174#        response.headers['content-type'] = 'text/xml'
175#        return feature.toGML()
176#       
177   
178   
Note: See TracBrowser for help on using the repository browser.