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

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

unfinished implementation of getFeature

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.featureinstances = self.layerMapper.map(**kwargs)
58        log.debug('Feature instances %s'%self.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        #create dictionary of form {featuretype: [layer, layer, ...], {featuretype2: [layer, layer, ...]}
96#        for layerName, layer in self.layers.items():
97#            log.info(dir(layer))
98#            if type(layer._feature) not in ftlist:
99#                ftlist[type(layer._feature)] = [layer]
100#            else:
101#                ftlist[type(layer._feature)].append(layer)
102#        log.info('FeatureTypeList: %s'%ftlist)
103#       
104       
105        for layerName, layer in self.layers.items():
106            log.info('Loading layer %s' % layerName)
107#            log.info('feature type %s'%layer._feature)
108
109            wgs84BBox = WGS84BoundingBox(layer.wgs84BBox[:2],
110                                         layer.wgs84BBox[2:])
111#            wgs84BBox = WGS84BoundingBox(['10','20'],['20','40'])
112           
113            ds = WfsFeatureSummary(keywords=layer.keywords, 
114                                   outputformats=layer.outputformats, 
115                                   identifier=layerName,
116                                   titles=[layer.title],
117                                   abstracts=[layer.abstract],                                   
118                                   wgs84BoundingBoxes=[wgs84BBox])
119
120            c.capabilities.contents.datasetSummaries.append(ds)
121
122    def _getSchema(self, typename):
123        namespace = typename.split(':')[0]
124        schemalocation = conf
125       
126    def _parsetypename(self, typename):
127        """ parse feature type name into schema and name"""       
128        if typename not in self.layers.keys():
129            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')
130   
131        namespace, ft = typename.split(':')
132        wfsconfiglocation=config['wfsconfig']
133        wfscfg = ConfigParser.ConfigParser()
134        wfscfg.read(wfsconfiglocation)     
135        xmlschema=open(wfscfg.get('application_schemas', namespace)).read()     
136        log.debug('location of application schema %s' %(xmlschema))
137        return xmlschema
138
139               
140    def DescribeFeatureType(self):
141        """ DescribeFeatureType """
142        version = self.getOwsParam('version', default=self.validVersions[0])
143        if version not in self.validVersions:
144            raise InvalidParameterValue('Version %s not supported' % version,
145                                        'version')
146        typename=self.getOwsParam('typename')
147        ftschema =self._parsetypename(typename)
148        log.debug(self.layers.items())
149       
150
151               
152        outputformat=self.getOwsParam('outputformat', default='text/xml')
153       
154        #temporarily returns entire schema
155        #TODO: return single featuretype definition
156        msg  = ftschema
157        response.headers['content-type'] = 'text/xml'
158        return msg
159 
160    def GetFeature(self):
161        """ GetFeature request
162        """
163        #TODO QUERY model
164        version = self.getOwsParam('version', default=self.validVersions[0])
165        if version not in self.validVersions:
166            raise InvalidParameterValue('Version %s not supported' % version,
167                                        'version')
168        featureid=self.getOwsParam('featureid')
169        #TODO populate self.featureinstances!
170        feature=self.featureinstances[featureid]   
171        response.headers['content-type'] = 'text/xml'
172        return feature.toGML()
173       
174        if featureid is not None:
175            msg = str(feature)
176        else:
177            msg = 'No feature specified'         
178        return msg
179   
180   
Note: See TracBrowser for help on using the repository browser.