1   
  2  """ 
  3  Test suite for the StyledLayerDescriptor python library. 
  4   
  5  License 
  6  ======= 
  7  Copyright 2011-2014 David Zwarg <U{david.a@zwarg.com}> 
  8   
  9  Licensed under the Apache License, Version 2.0 (the "License"); 
 10  you may not use this file except in compliance with the License. 
 11  You may obtain a copy of the License at 
 12   
 13  U{http://www.apache.org/licenses/LICENSE-2.0} 
 14   
 15  Unless required by applicable law or agreed to in writing, software 
 16  distributed under the License is distributed on an "AS IS" BASIS, 
 17  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 18  See the License for the specific language governing permissions and 
 19  limitations under the License. 
 20   
 21  @author: David Zwarg 
 22  @contact: david.a@zwarg.com 
 23  @copyright: 2011-2014, Azavea 
 24  @license: Apache 2.0 
 25  @version: 1.0.10 
 26  """ 
 27  import sld 
 28  import unittest 
 29  import copy 
 30  from lxml import etree 
 31   
 32   
 34      """ 
 35      All tests for django-sld are contained in this TestCase class. 
 36      """ 
 37   
 38      _sld0 = None 
 39      """Store a parsed SLD, with known styles and structure""" 
 40   
 41      _sld1 = None 
 42      """Store a dynamically generated SLD""" 
 43   
 51   
 53          """ 
 54          Test an empty constructor, and make sure the SLD is valid. 
 55          """ 
 56          sld_doc = sld.StyledLayerDescriptor() 
 57   
 58          self.assertTrue('sld' in sld_doc._nsmap) 
 59   
 60          expected = """<sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc" version="1.0.0"/>""" 
 61          actual = etree.tostring(sld_doc._node, with_tail=False) 
 62          self.assertEqual(actual, expected.encode('utf-8')) 
 63   
 64          sld_doc.normalize() 
 65   
 66          self.assertTrue(sld_doc.validate()) 
  67   
 69          """ 
 70          Test a constructor on a bogus file. 
 71          """ 
 72          try: 
 73              sld.StyledLayerDescriptor('junk') 
 74              self.fail("Error") 
 75          except: 
 76               
 77              pass 
  78   
 80          """ 
 81          Test the SLD version on the root element. 
 82          """ 
 83          self.assertEqual(self._sld0.version, "1.0.0") 
  84   
 86          """ 
 87          Test the namespace on the root element. 
 88          """ 
 89          self.assertEqual(self._sld0.xmlns, 'http://www.opengis.net/sld') 
  90   
 92          """ 
 93          Test the object type of the NamedLayer property. 
 94          """ 
 95          self.assertTrue(isinstance(self._sld0.NamedLayer, sld.NamedLayer), "NamedLayer property is not the proper class.") 
  96   
 98          """ 
 99          Test the creation and construction of a NamedLayer element. 
100          """ 
101          self.assertTrue(self._sld1.NamedLayer is None) 
102   
103          sld_doc = copy.deepcopy(self._sld1) 
104   
105          sld_doc.create_namedlayer('test named layer') 
106          self.assertFalse(sld_doc.NamedLayer is None) 
107   
108          sld_doc.normalize() 
109          self.assertTrue(sld_doc.validate()) 
 110   
112          """ 
113          Test the proper parsing of the name of the NamedLayer. 
114          """ 
115          expected = 'poptot' 
116          self.assertEqual(self._sld0.NamedLayer.Name, expected, "NamedLayer was named '%s', not '%s'" % (self._sld0.NamedLayer.Name, expected,)) 
 117   
119          """ 
120          Test the object type of the UserStyle property. 
121          """ 
122          self.assertTrue(isinstance(self._sld0.NamedLayer.UserStyle, sld.UserStyle), "UserStyle property is not the proper class.") 
 123   
140   
142          """ 
143          Test the parsing of the UserStyle Title, and proper rendering. 
144          """ 
145          sld_doc = copy.deepcopy(self._sld0) 
146          us = sld_doc.NamedLayer.UserStyle 
147          expected = 'Population' 
148          self.assertEqual(us.Title, expected, "UserStyle Title was '%s', not '%s'" % (us.Title, expected,)) 
149   
150          expected = 'Consternation' 
151          us.Title = expected 
152          self.assertEqual(us.Title, expected, "UserStyle Title was '%s', not '%s'" % (us.Title, expected,)) 
153   
154          us._node.remove(us._node[2]) 
155   
156          expected = """<UserStyle xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
157        <Title>%s</Title> 
158        <Abstract>A grayscale style showing the population numbers in a given geounit.</Abstract> 
159        </UserStyle>""" % expected 
160          actual = etree.tostring(us._node, with_tail=False) 
161          self.assertEqual(len(actual), len(expected)) 
162          self.assertEqual(actual, expected.encode('utf-8'), "UserStyle was not serialized correctly.\n%s" % actual) 
163   
164          sld_doc.normalize() 
165          self.assertFalse(sld_doc.validate()) 
 166   
168          """ 
169          Test the construction of the UserStyle Title, and proper rendering. 
170          """ 
171          sld_doc = copy.deepcopy(self._sld1) 
172          sld_doc.create_namedlayer('test named layer') 
173          sld_doc.NamedLayer.create_userstyle() 
174   
175          us = sld_doc.NamedLayer.UserStyle 
176          self.assertTrue(us.Title is None, "UserStyle Title was not None") 
177   
178          expected = 'Consternation' 
179          us.Title = expected 
180          self.assertEqual(us.Title, expected, "UserStyle Title was '%s', not '%s'" % (us.Title, expected,)) 
181   
182          expected = """<sld:UserStyle xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc"><sld:Title>%s</sld:Title></sld:UserStyle>""" % expected 
183          actual = etree.tostring(us._node, with_tail=False) 
184          self.assertEqual(len(actual), len(expected)) 
185          self.assertEqual(actual, expected.encode('utf-8'), "UserStyle was not serialized correctly.\n%s" % actual) 
186   
187          sld_doc.normalize() 
188          self.assertFalse(sld_doc.validate()) 
 189   
191          """ 
192          Test the parsing of the UserStyle Abstract, and proper rendering. 
193          """ 
194          sld_doc = copy.deepcopy(self._sld0) 
195          us = sld_doc.NamedLayer.UserStyle 
196          expected = 'A grayscale style showing the population numbers in a given geounit.' 
197          self.assertEqual(us.Abstract, expected, "UserStyle Abstract was '%s', not '%s'" % (us.Abstract, expected,)) 
198   
199          expected = 'Something completely different' 
200          us.Abstract = expected 
201          self.assertEqual(us.Abstract, expected, "UserStyle Abstract was '%s', not '%s'" % (us.Abstract, expected,)) 
202   
203          us._node.remove(us._node[2]) 
204   
205          expected = """<UserStyle xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
206        <Title>Population</Title> 
207        <Abstract>%s</Abstract> 
208        </UserStyle>""" % expected 
209          actual = etree.tostring(us._node, with_tail=False) 
210          self.assertEqual(len(actual), len(expected)) 
211          self.assertEqual(actual, expected.encode('utf-8'), "UserStyle was not serialized correctly.\n%s" % actual) 
212   
213          sld_doc.normalize() 
214          self.assertFalse(sld_doc.validate()) 
 215   
217          """ 
218          Test the construction of the UserStyle Abstract, and proper rendering. 
219          """ 
220          sld_doc = copy.deepcopy(self._sld1) 
221          sld_doc.create_namedlayer('test named layer') 
222          sld_doc.NamedLayer.create_userstyle() 
223   
224          us = sld_doc.NamedLayer.UserStyle 
225          self.assertTrue(us.Abstract is None, "UserStyle Abstract was not None") 
226   
227          expected = 'Something completely different' 
228          us.Abstract = expected 
229          self.assertEqual(us.Abstract, expected, "UserStyle Abstract was '%s', not '%s'" % (us.Abstract, expected,)) 
230   
231          expected = """<sld:UserStyle xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc"><sld:Abstract>%s</sld:Abstract></sld:UserStyle>""" % expected 
232          actual = etree.tostring(us._node, with_tail=False) 
233          self.assertEqual(len(actual), len(expected)) 
234          self.assertEqual(actual, expected.encode('utf-8'), "UserStyle was not serialized correctly.\n%s" % actual) 
235   
236          sld_doc.normalize() 
237          self.assertFalse(sld_doc.validate()) 
 238   
244   
261   
263          """ 
264          Test the parsing of the Rules property. 
265          """ 
266          rules = self._sld0.NamedLayer.UserStyle.FeatureTypeStyle.Rules 
267          self.assertEqual(len(rules), 6) 
268          self.assertTrue(isinstance(rules[0], sld.Rule), "Rule item in list is not the proper class.") 
 269   
289   
291          """ 
292          Test the parsing of the individual Rule properties. 
293          """ 
294          sld_doc = copy.deepcopy(self._sld0) 
295          rule = sld_doc.NamedLayer.UserStyle.FeatureTypeStyle.Rules[0] 
296   
297          expected = "> 880" 
298          self.assertEqual(rule.Title, expected) 
299   
300          expected = "> 999" 
301          rule.Title = expected 
302          self.assertEqual(rule.Title, expected) 
303   
304          expected = """<Rule xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
305            <Title>> 999</Title> 
306            <ogc:Filter> 
307              <ogc:PropertyIsGreaterThanOrEqualTo> 
308                <ogc:PropertyName>number</ogc:PropertyName> 
309                <ogc:Literal>880</ogc:Literal> 
310              </ogc:PropertyIsGreaterThanOrEqualTo> 
311            </ogc:Filter> 
312            <MaxScaleDenominator>20000</MaxScaleDenominator> 
313            <PolygonSymbolizer> 
314              <Fill> 
315                <CssParameter name="fill">#252525</CssParameter> 
316              </Fill> 
317            </PolygonSymbolizer> 
318          </Rule>""" 
319          actual = etree.tostring(rule._node, with_tail=False) 
320          self.assertEqual(actual, expected.encode('utf-8'), actual) 
321   
322          sld_doc.normalize() 
323          self.assertTrue(sld_doc.validate()) 
 324   
326          """ 
327          Test the construction of new Rule properties. 
328          """ 
329          sld_doc = copy.deepcopy(self._sld1) 
330          sld_doc.create_namedlayer('test named layer') 
331          sld_doc.NamedLayer.create_userstyle() 
332          sld_doc.NamedLayer.UserStyle.create_featuretypestyle() 
333          sld_doc.NamedLayer.UserStyle.FeatureTypeStyle.create_rule('test rule', sld.PointSymbolizer) 
334   
335          rule = sld_doc.NamedLayer.UserStyle.FeatureTypeStyle.Rules[0] 
336   
337          expected = "> 999" 
338          rule.Title = expected 
339          self.assertEqual(rule.Title, expected) 
340   
341          expected = """<sld:Rule xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc"><sld:Title>> 999</sld:Title><sld:PointSymbolizer><sld:Graphic><sld:Mark><sld:WellKnownName>square</sld:WellKnownName><sld:Fill><sld:CssParameter name="fill">#ff0000</sld:CssParameter></sld:Fill></sld:Mark></sld:Graphic></sld:PointSymbolizer></sld:Rule>""" 
342          actual = etree.tostring(rule._node, with_tail=False) 
343          self.assertEqual(actual, expected.encode('utf-8'), actual) 
344   
345          sld_doc.normalize() 
346          self.assertTrue(sld_doc.validate()) 
 347   
349          """ 
350          Test the parsing of the Filter property. 
351          """ 
352          sld_doc = copy.deepcopy(self._sld0) 
353          rule = sld_doc.NamedLayer.UserStyle.FeatureTypeStyle.Rules[0] 
354   
355          self.assertFalse(rule.Filter.PropertyIsGreaterThanOrEqualTo is None) 
356   
357          self.assertEqual(rule.Filter.PropertyIsGreaterThanOrEqualTo.PropertyName, 'number') 
358          self.assertEqual(rule.Filter.PropertyIsGreaterThanOrEqualTo.Literal, '880') 
359   
360          sld_doc.normalize() 
361          self.assertTrue(sld_doc.validate()) 
 362   
377   
379          """ 
380          Test the construction of an equality filter. 
381          """ 
382          sld_doc = copy.deepcopy(self._sld1) 
383          namedlayer = sld_doc.create_namedlayer('test named layer') 
384          userstyle = namedlayer.create_userstyle() 
385          featuretypestyle = userstyle.create_featuretypestyle() 
386          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
387          rfilter = rule.create_filter('valueA', '==', '5000') 
388   
389          self.assertTrue(rfilter.PropertyIsNotEqualTo is None) 
390          self.assertTrue(rfilter.PropertyIsLessThan is None) 
391          self.assertTrue(rfilter.PropertyIsLessThanOrEqualTo is None) 
392          self.assertTrue(rfilter.PropertyIsGreaterThan is None) 
393          self.assertTrue(rfilter.PropertyIsGreaterThanOrEqualTo is None) 
394          self.assertTrue(rfilter.PropertyIsLike is None) 
395          self.assertFalse(rfilter.PropertyIsEqualTo is None) 
396          self.assertEqual(rfilter.PropertyIsEqualTo.PropertyName, 'valueA') 
397          self.assertEqual(rfilter.PropertyIsEqualTo.Literal, '5000') 
398   
399          sld_doc.normalize() 
400          self.assertTrue(sld_doc.validate()) 
 401   
403          """ 
404          Test the construction of a less-than-or-equal Filter. 
405          """ 
406          sld_doc = copy.deepcopy(self._sld1) 
407          namedlayer = sld_doc.create_namedlayer('test named layer') 
408          userstyle = namedlayer.create_userstyle() 
409          featuretypestyle = userstyle.create_featuretypestyle() 
410          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
411          rfilter = rule.create_filter('valueB', '<=', '5000') 
412   
413          self.assertTrue(rfilter.PropertyIsEqualTo is None) 
414          self.assertTrue(rfilter.PropertyIsNotEqualTo is None) 
415          self.assertTrue(rfilter.PropertyIsLessThan is None) 
416          self.assertTrue(rfilter.PropertyIsGreaterThan is None) 
417          self.assertTrue(rfilter.PropertyIsGreaterThanOrEqualTo is None) 
418          self.assertTrue(rfilter.PropertyIsLike is None) 
419          self.assertFalse(rfilter.PropertyIsLessThanOrEqualTo is None) 
420          self.assertEqual(rfilter.PropertyIsLessThanOrEqualTo.PropertyName, 'valueB') 
421          self.assertEqual(rfilter.PropertyIsLessThanOrEqualTo.Literal, '5000') 
422   
423          sld_doc.normalize() 
424          self.assertTrue(sld_doc.validate()) 
 425   
427          """ 
428          Test the construction of a less-than Filter. 
429          """ 
430          sld_doc = copy.deepcopy(self._sld1) 
431          namedlayer = sld_doc.create_namedlayer('test named layer') 
432          userstyle = namedlayer.create_userstyle() 
433          featuretypestyle = userstyle.create_featuretypestyle() 
434          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
435          rfilter = rule.create_filter('valueC', '<', '500') 
436   
437          self.assertTrue(rfilter.PropertyIsEqualTo is None) 
438          self.assertTrue(rfilter.PropertyIsLessThanOrEqualTo is None) 
439          self.assertTrue(rfilter.PropertyIsNotEqualTo is None) 
440          self.assertTrue(rfilter.PropertyIsGreaterThan is None) 
441          self.assertTrue(rfilter.PropertyIsGreaterThanOrEqualTo is None) 
442          self.assertTrue(rfilter.PropertyIsLike is None) 
443          self.assertFalse(rfilter.PropertyIsLessThan is None) 
444          self.assertEqual(rfilter.PropertyIsLessThan.PropertyName, 'valueC') 
445          self.assertEqual(rfilter.PropertyIsLessThan.Literal, '500') 
446   
447          sld_doc.normalize() 
448          self.assertTrue(sld_doc.validate()) 
 449   
451          """ 
452          Test the construction of a greater-than-or-equal Filter. 
453          """ 
454          sld_doc = copy.deepcopy(self._sld1) 
455          namedlayer = sld_doc.create_namedlayer('test named layer') 
456          userstyle = namedlayer.create_userstyle() 
457          featuretypestyle = userstyle.create_featuretypestyle() 
458          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
459          rfilter = rule.create_filter('valueD', '>=', '100') 
460   
461          self.assertTrue(rfilter.PropertyIsEqualTo is None) 
462          self.assertTrue(rfilter.PropertyIsLessThanOrEqualTo is None) 
463          self.assertTrue(rfilter.PropertyIsLessThan is None) 
464          self.assertTrue(rfilter.PropertyIsNotEqualTo is None) 
465          self.assertTrue(rfilter.PropertyIsGreaterThan is None) 
466          self.assertTrue(rfilter.PropertyIsLike is None) 
467          self.assertFalse(rfilter.PropertyIsGreaterThanOrEqualTo is None) 
468          self.assertEqual(rfilter.PropertyIsGreaterThanOrEqualTo.PropertyName, 'valueD') 
469          self.assertEqual(rfilter.PropertyIsGreaterThanOrEqualTo.Literal, '100') 
470   
471          sld_doc.normalize() 
472          self.assertTrue(sld_doc.validate()) 
 473   
475          """ 
476          Test the construction of a greater-than Filter. 
477          """ 
478          sld_doc = copy.deepcopy(self._sld1) 
479          namedlayer = sld_doc.create_namedlayer('test named layer') 
480          userstyle = namedlayer.create_userstyle() 
481          featuretypestyle = userstyle.create_featuretypestyle() 
482          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
483          rfilter = rule.create_filter('valueE', '>', '10') 
484   
485          self.assertTrue(rfilter.PropertyIsEqualTo is None) 
486          self.assertTrue(rfilter.PropertyIsLessThanOrEqualTo is None) 
487          self.assertTrue(rfilter.PropertyIsLessThan is None) 
488          self.assertTrue(rfilter.PropertyIsGreaterThanOrEqualTo is None) 
489          self.assertTrue(rfilter.PropertyIsNotEqualTo is None) 
490          self.assertTrue(rfilter.PropertyIsLike is None) 
491          self.assertFalse(rfilter.PropertyIsGreaterThan is None) 
492          self.assertEqual(rfilter.PropertyIsGreaterThan.PropertyName, 'valueE') 
493          self.assertEqual(rfilter.PropertyIsGreaterThan.Literal, '10') 
494   
495          sld_doc.normalize() 
496          self.assertTrue(sld_doc.validate()) 
 497   
499          """ 
500          Test the construction of an inequality Filter. 
501          """ 
502          sld_doc = copy.deepcopy(self._sld1) 
503          namedlayer = sld_doc.create_namedlayer('test named layer') 
504          userstyle = namedlayer.create_userstyle() 
505          featuretypestyle = userstyle.create_featuretypestyle() 
506          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
507          rfilter = rule.create_filter('valueF', '!=', '0.01') 
508   
509          self.assertTrue(rfilter.PropertyIsEqualTo is None) 
510          self.assertTrue(rfilter.PropertyIsLessThan is None) 
511          self.assertTrue(rfilter.PropertyIsLessThanOrEqualTo is None) 
512          self.assertTrue(rfilter.PropertyIsGreaterThan is None) 
513          self.assertTrue(rfilter.PropertyIsGreaterThanOrEqualTo is None) 
514          self.assertTrue(rfilter.PropertyIsLike is None) 
515          self.assertFalse(rfilter.PropertyIsNotEqualTo is None) 
516          self.assertEqual(rfilter.PropertyIsNotEqualTo.PropertyName, 'valueF') 
517          self.assertEqual(rfilter.PropertyIsNotEqualTo.Literal, '0.01') 
518   
519          sld_doc.normalize() 
520          self.assertTrue(sld_doc.validate()) 
 521   
523          """ 
524          Test the construction of a logical-and Filter. 
525          """ 
526          sld_doc = copy.deepcopy(self._sld1) 
527          namedlayer = sld_doc.create_namedlayer('test named layer') 
528          userstyle = namedlayer.create_userstyle() 
529          featuretypestyle = userstyle.create_featuretypestyle() 
530          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
531   
532          filter1 = sld.Filter(rule) 
533          filter1.PropertyIsGreaterThan = sld.PropertyCriterion(filter1, 'PropertyIsGreaterThan') 
534          filter1.PropertyIsGreaterThan.PropertyName = 'number' 
535          filter1.PropertyIsGreaterThan.Literal = '-10' 
536   
537          filter2 = sld.Filter(rule) 
538          filter2.PropertyIsLessThanOrEqualTo = sld.PropertyCriterion(filter2, 'PropertyIsLessThanOrEqualTo') 
539          filter2.PropertyIsLessThanOrEqualTo.PropertyName = 'number' 
540          filter2.PropertyIsLessThanOrEqualTo.Literal = '10' 
541   
542          rule.Filter = filter1 + filter2 
543   
544          expected = """<sld:Rule xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc"><sld:Title>test rule</sld:Title><sld:PointSymbolizer><sld:Graphic><sld:Mark><sld:WellKnownName>square</sld:WellKnownName><sld:Fill><sld:CssParameter name="fill">#ff0000</sld:CssParameter></sld:Fill></sld:Mark></sld:Graphic></sld:PointSymbolizer><ogc:Filter><ogc:And><ogc:PropertyIsGreaterThan><ogc:PropertyName>number</ogc:PropertyName><ogc:Literal>-10</ogc:Literal></ogc:PropertyIsGreaterThan><ogc:PropertyIsLessThanOrEqualTo><ogc:PropertyName>number</ogc:PropertyName><ogc:Literal>10</ogc:Literal></ogc:PropertyIsLessThanOrEqualTo></ogc:And></ogc:Filter></sld:Rule>""" 
545          actual = etree.tostring(rule._node, with_tail=False) 
546          self.assertEqual(actual, expected.encode('utf-8')) 
547   
548          sld_doc.normalize() 
549          self.assertTrue(sld_doc.validate()) 
 550   
552          """ 
553          Test the construction of a logical-or Filter. 
554          """ 
555          sld_doc = copy.deepcopy(self._sld1) 
556          namedlayer = sld_doc.create_namedlayer('test named layer') 
557          userstyle = namedlayer.create_userstyle() 
558          featuretypestyle = userstyle.create_featuretypestyle() 
559          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
560   
561          filter1 = sld.Filter(rule) 
562          filter1.PropertyIsGreaterThan = sld.PropertyCriterion(filter1, 'PropertyIsGreaterThan') 
563          filter1.PropertyIsGreaterThan.PropertyName = 'number' 
564          filter1.PropertyIsGreaterThan.Literal = '10' 
565   
566          filter2 = sld.Filter(rule) 
567          filter2.PropertyIsLessThan = sld.PropertyCriterion(filter2, 'PropertyIsLessThan') 
568          filter2.PropertyIsLessThan.PropertyName = 'number' 
569          filter2.PropertyIsLessThan.Literal = '-10' 
570   
571          rule.Filter = filter1 | filter2 
572   
573          expected = """<sld:Rule xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc"><sld:Title>test rule</sld:Title><sld:PointSymbolizer><sld:Graphic><sld:Mark><sld:WellKnownName>square</sld:WellKnownName><sld:Fill><sld:CssParameter name="fill">#ff0000</sld:CssParameter></sld:Fill></sld:Mark></sld:Graphic></sld:PointSymbolizer><ogc:Filter><ogc:Or><ogc:PropertyIsGreaterThan><ogc:PropertyName>number</ogc:PropertyName><ogc:Literal>10</ogc:Literal></ogc:PropertyIsGreaterThan><ogc:PropertyIsLessThan><ogc:PropertyName>number</ogc:PropertyName><ogc:Literal>-10</ogc:Literal></ogc:PropertyIsLessThan></ogc:Or></ogc:Filter></sld:Rule>""" 
574          actual = etree.tostring(rule._node, with_tail=False) 
575          self.assertEqual(actual, expected.encode('utf-8')) 
576   
577          sld_doc.normalize() 
578          self.assertTrue(sld_doc.validate()) 
 579   
581          """ 
582          Test the construction of a logical-and combined with a logical-or Filter. 
583          """ 
584          sld_doc = copy.deepcopy(self._sld1) 
585          namedlayer = sld_doc.create_namedlayer('test named layer') 
586          userstyle = namedlayer.create_userstyle() 
587          featuretypestyle = userstyle.create_featuretypestyle() 
588          rule = featuretypestyle.create_rule('test rule', sld.PointSymbolizer) 
589   
590          filter1 = sld.Filter(rule) 
591          filter1.PropertyIsGreaterThan = sld.PropertyCriterion(filter1, 'PropertyIsGreaterThan') 
592          filter1.PropertyIsGreaterThan.PropertyName = 'number' 
593          filter1.PropertyIsGreaterThan.Literal = '10' 
594   
595          filter2 = sld.Filter(rule) 
596          filter2.PropertyIsLessThan = sld.PropertyCriterion(filter2, 'PropertyIsLessThan') 
597          filter2.PropertyIsLessThan.PropertyName = 'number' 
598          filter2.PropertyIsLessThan.Literal = '-10' 
599   
600          filter3 = sld.Filter(rule) 
601          filter3.PropertyIsEqualTo = sld.PropertyCriterion(filter3, 'PropertyIsEqualTo') 
602          filter3.PropertyIsEqualTo.PropertyName = 'value' 
603          filter3.PropertyIsEqualTo.Literal = 'yes' 
604   
605          rule.Filter = filter1 + (filter2 | filter3) 
606   
607          expected = """<sld:Rule xmlns:sld="http://www.opengis.net/sld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ogc="http://www.opengis.net/ogc"><sld:Title>test rule</sld:Title><sld:PointSymbolizer><sld:Graphic><sld:Mark><sld:WellKnownName>square</sld:WellKnownName><sld:Fill><sld:CssParameter name="fill">#ff0000</sld:CssParameter></sld:Fill></sld:Mark></sld:Graphic></sld:PointSymbolizer><ogc:Filter><ogc:And><ogc:PropertyIsGreaterThan><ogc:PropertyName>number</ogc:PropertyName><ogc:Literal>10</ogc:Literal></ogc:PropertyIsGreaterThan><ogc:Or><ogc:PropertyIsLessThan><ogc:PropertyName>number</ogc:PropertyName><ogc:Literal>-10</ogc:Literal></ogc:PropertyIsLessThan><ogc:PropertyIsEqualTo><ogc:PropertyName>value</ogc:PropertyName><ogc:Literal>yes</ogc:Literal></ogc:PropertyIsEqualTo></ogc:Or></ogc:And></ogc:Filter></sld:Rule>""" 
608          actual = etree.tostring(rule._node, with_tail=False, pretty_print=False) 
609          self.assertEqual(actual, expected.encode('utf-8')) 
610   
611          sld_doc.normalize() 
612          self.assertTrue(sld_doc.validate()) 
 613   
625   
643   
659   
677   
691   
711   
713          """ 
714          Test the parsing of the MaxScaleDenominator & MinScaleDenominator properties. 
715          """ 
716          sld_doc = copy.deepcopy(self._sld0) 
717          rule = sld_doc.NamedLayer.UserStyle.FeatureTypeStyle.Rules[0] 
718   
719          self.assertTrue(rule.MinScaleDenominator is None) 
720          self.assertFalse(rule.MaxScaleDenominator is None) 
721   
722          expected = '20000' 
723          self.assertEqual(rule.MaxScaleDenominator, expected, "MaxScaleDominator was '%s', not '%s'" % (rule.MaxScaleDenominator, expected,)) 
724          expected = '15000' 
725          rule.MaxScaleDenominator = expected 
726          self.assertEqual(rule.MaxScaleDenominator, expected, "MaxScaleDominator was '%s', not '%s'" % (rule.MaxScaleDenominator, expected,)) 
727   
728          del rule.MaxScaleDenominator 
729          self.assertTrue(rule.MaxScaleDenominator is None) 
730   
731          expected = '15000' 
732          rule.MinScaleDenominator = expected 
733          self.assertEqual(rule.MinScaleDenominator, expected, "MinScaleDenominator was '%s', not '%s'" % (rule.MinScaleDenominator, expected,)) 
734   
735          sld_doc.normalize() 
736          self.assertTrue(sld_doc.validate()) 
 737   
739          """ 
740          Test the construction of the MaxScaleDenominator & MinScaleDenominator properties. 
741          """ 
742          sld_doc = copy.deepcopy(self._sld1) 
743          namedlayer = sld_doc.create_namedlayer('test named layer') 
744          userstyle = namedlayer.create_userstyle() 
745          featuretypestyle = userstyle.create_featuretypestyle() 
746   
747          rule1 = featuretypestyle.create_rule('test rule 1', sld.PointSymbolizer) 
748          self.assertTrue(rule1.MinScaleDenominator is None) 
749          self.assertTrue(rule1.MaxScaleDenominator is None) 
750   
751          rule2 = featuretypestyle.create_rule('test rule 2', sld.PointSymbolizer, '10000', '20000') 
752          self.assertFalse(rule2.MinScaleDenominator is None) 
753          self.assertFalse(rule2.MaxScaleDenominator is None) 
754          self.assertEqual(rule2.MinScaleDenominator, '10000') 
755          self.assertEqual(rule2.MaxScaleDenominator, '20000') 
756   
757          sld_doc.normalize() 
758          self.assertTrue(sld_doc.validate()) 
  759   
760   
761  if __name__ == '__main__': 
762      unittest.main() 
763