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

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

Creating FeatureSet? class to provide query methods on collection of FeatureInstances?.

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