source: cows/trunk/cows/model/filterencoding.py @ 4344

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

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

Line 
1# Copyright (C) 2008 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
6""" Classes to handle filter encoding queries as used in WFS """
7
8from xml.etree import ElementTree as etree
9import logging
10log = logging.getLogger(__name__)
11
12""" utility functions to save writing out fully qualified names """
13nsOGC = 'http://www.opengis.net/ogc'
14def OGC(tag):
15    return "{"+nsOGC+"}"+tag
16
17nsGML = 'http://www.opengis.net/gml'
18def GML(tag):
19    return "{"+nsGML+"}"+tag
20
21
22
23class AndOperator(object):
24    """ Return the intersection of two filters"""
25    def __init__(self, elem):
26        self.children=elem.getchildren()
27
28    def evaluate(self, featureset):
29        qp=QueryProcessor()
30        filter=qp.getFilterOrOperator(self.children[0])
31        set1=filter.evaluate(featureset)
32        filter2=qp.getFilterOrOperator(self.children[1])
33        set2=filter2.evaluate(featureset)
34        resultset = set1.intersection(set2)
35        return resultset
36       
37       
38class OrOperator(object):
39    """ Return the union of two filters"""
40    def __init__(self, elem):
41        self.children=elem.getchildren()
42
43    def evaluate(self, featureset):
44        qp=QueryProcessor()
45        filter=qp.getFilterOrOperator(self.children[0])
46        set1=filter.evaluate(featureset)
47        filter2=qp.getFilterOrOperator(self.children[1])
48        set2=filter2.evaluate(featureset)
49        resultset = set1.union(set2)
50        return resultset
51
52#TODO: NOT operator
53       
54class Filter(object):
55    def __init__(self, elem):
56        self.elem=elem
57
58
59class GMLIdFilter(Filter):
60    def evaluate(self, featureset):       
61        log.debug('Value of gml id filter %s'%self.elem.get(GML('id')))
62        resultset=set([featureset.getFeatureByGMLid(self.elem.get(GML('id')))])
63        return resultset
64
65class BBoxFilter(Filter):
66    def evaluate(self, featureset):
67        #parse the bbox xml envelope to get values
68        envelope=self.elem.getchildren()[0]
69        srsname=envelope.get('srsName')
70        lowercorner=envelope.getchildren()[0].text.split()
71        uppercorner=envelope.getchildren()[1].text.split()
72        bbtuple=(float(lowercorner[0]),float(lowercorner[1]), float(uppercorner[0]), float(uppercorner[1]))
73        resultset=set(featureset.getFeaturesByBBox(bbtuple, srsname))                             
74        return resultset       
75
76class FEQueryProcessor(object):
77    def __init__(self):
78        pass
79   
80    def evaluate(self, featureset, queryxml):
81        #The root elem should only have one direct child elemtent. Evaluating this
82        #child element should return the resultset for the entire nested filter.
83        self.rootelem=etree.fromstring(queryxml)
84        log.debug('filter root element %s'%self.rootelem)
85        log.debug('child elements %s'%self.rootelem.getchildren())
86        filterelem=self.rootelem.getchildren()[0]
87        resultset=set()
88        for filterdef in filterelem.getchildren():
89            filter=self.getFilterOrOperator(filterdef)
90            filterresult=filter.evaluate(featureset)
91            resultset=resultset.union(filterresult)
92        return resultset
93   
94    def getFilterOrOperator(self, filterelem):
95        if filterelem.tag=='And':
96            f=AndOperator(filterelem)
97        elif filterelem.tag=='Or':
98            f=OrOperator(filterelem)
99        elif filterelem.tag ==OGC('GmlObjectId'):
100            f=GMLIdFilter(filterelem)
101        elif filterelem.tag ==OGC('BBOX'):
102            f=BBoxFilter(filterelem)
103        log.debug('Filter tag = %s'%filterelem.tag)
104        return f
105       
106
107           
Note: See TracBrowser for help on using the repository browser.