/[thuban]/branches/WIP-pyshapelib-bramz/test/test_save.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/test/test_save.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1452 - (hide annotations)
Fri Jul 18 12:57:59 2003 UTC (21 years, 7 months ago) by bh
Original Path: trunk/thuban/test/test_save.py
File MIME type: text/x-python
File size: 21159 byte(s)
* Thuban/Model/layer.py (Layer.__init__): Rename
classificationField to classificatin_column and init it here so
that it can be used in SetClassificationColumn
(Layer.GetClassificationColumn, Layer.GetClassificationField):
Rename to GetClassificationColumn.
(Layer.SetClassificationColumn, Layer.SetClassificationField):
Rename to SetClassificationColumn and issue a LAYER_CHANGED
message if the column changes.
(Layer._classification_changed, Layer.ClassChanged): Rename to
_classification_changed. Update the callers.
(Layer.SetShapeStore): Further field->column renames.

* Thuban/Model/load.py (SessionLoader.start_classification)
(SessionLoader.start_clpoint): Updates because of
field->column method name changes in the Layer class

* Thuban/Model/save.py (SessionSaver.write_classification): Updates
because of field->column method name changes in the Layer class

* Thuban/UI/classifier.py (Classifier.__init__)
(Classifier._OnTry, Classifier._OnRevert): Updates because of
field->column method name changes in the Layer class

* Thuban/UI/renderer.py (MapRenderer.draw_shape_layer): Updates
because of field->column method name changes in the Layer class

* Thuban/UI/viewport.py (ViewPort.find_shape_at): Updates because
of field->column method name changes in the Layer class

* test/test_save.py (SaveSessionTest.testClassifiedLayer)
(SaveSessionTest.testClassifiedLayer): Update because of
field->column method name changes in the Layer class

* test/test_layer.py (SetShapeStoreTests.setUp)
(SetShapeStoreTests.test_sanity): Update because of field->column
method name changes in the Layer class
(TestLayerModification.setUp): Subscribe to LAYER_CHANGED as well
(TestLayerModification.test_sanity)
(TestLayerModification.test_initial_settings): remove unsued code
and rename to test_sanity.
(TestLayerModification.test_set_classification): New test for
SetClassification and SetClassificationField.

1 bh 723 # Copyright (c) 2002, 2003 by Intevation GmbH
2 bh 292 # Authors:
3     # Bernhard Herzog <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     """
9     Test saving a thuban session as XML
10     """
11    
12     __version__ = "$Revision$"
13     # $Source$
14     # $Id$
15    
16     import os
17     import unittest
18     from StringIO import StringIO
19    
20     import xml.sax
21     import xml.sax.handler
22 jonathan 530 from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException
23 bh 292
24 bh 1245 import xmlsupport
25    
26 bh 292 import support
27     support.initthuban()
28    
29 bh 1268 import dbflib
30    
31     from Thuban.Lib.fileutil import relative_filename
32     from Thuban.Model.save import XMLWriter, save_session, sort_data_stores
33 bh 292 from Thuban.Model.session import Session
34     from Thuban.Model.map import Map
35 jonathan 947 from Thuban.Model.layer import Layer, RasterLayer
36 bh 292 from Thuban.Model.proj import Projection
37 bh 1268 from Thuban.Model.table import DBFTable
38     from Thuban.Model.transientdb import TransientJoinedTable
39     from Thuban.Model.data import DerivedShapeStore
40 bh 292
41 jonathan 1168 from Thuban.Model.classification import ClassGroupSingleton, ClassGroupRange, \
42     ClassGroupProperties
43 bh 292
44 jonathan 1168 from Thuban.Model.range import Range
45    
46    
47     class XMLWriterTest(unittest.TestCase):
48    
49     def testEncode(self):
50     """Test XMLWriter.encode"""
51     writer = XMLWriter()
52 jonathan 1200 eq = self.assertEquals
53 jonathan 1168
54 jonathan 1200 eq(writer.encode("hello world"), "hello world")
55     eq(writer.encode(unicode("hello world")), unicode("hello world"))
56 jonathan 1173
57 jonathan 1200 eq(writer.encode("\x80\x90\xc2\x100"),
58     "\xc2\x80\xc2\x90\xc3\x82\x100")
59     eq(writer.encode(u"\x80\x90\xc2\x100"),
60     "\xc2\x80\xc2\x90\xc3\x82\x100")
61     eq(writer.encode(u"\xFF5E"), "\xc3\xbf5E")
62 jonathan 1173
63 jonathan 1200 eq(writer.encode('&"\'<>'), "&amp;&quot;&apos;&lt;&gt;")
64     eq(writer.encode(unicode('&"\'<>')), "&amp;&quot;&apos;&lt;&gt;")
65 jonathan 1168
66 bh 1245 class SaveSessionTest(unittest.TestCase, support.FileTestMixin,
67     xmlsupport.ValidationTest):
68 bh 292
69 bh 1375 dtd = "http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"
70 bh 1268 thubanids = [((dtd, n), (None, "id")) for n in
71     ["fileshapesource", "filetable", "jointable",
72     "derivedshapesource"]]
73     thubanidrefs = [((dtd, n), (None, m)) for n, m in
74     [("layer", "shapestore"),
75     ("jointable", "left"),
76     ("jointable", "right"),
77     ("derivedshapesource", "table"),
78     ("derivedshapesource", "shapesource")]]
79     del n, m, dtd
80    
81 bh 292 def compare_xml(self, xml1, xml2):
82 bh 1375 list1 = xmlsupport.sax_eventlist(xml1, ids = self.thubanids,
83     idrefs = self.thubanidrefs)
84     list2 = xmlsupport.sax_eventlist(xml2, ids = self.thubanids,
85     idrefs = self.thubanidrefs)
86     if list1 != list2:
87     for a, b in zip(list1, list2):
88     if a != b:
89     self.fail("%r != %r" % (a, b))
90 bh 292
91 bh 1375
92 bh 292 def testEmptySession(self):
93     """Save an empty session"""
94     session = Session("empty session")
95     filename = self.temp_file_name("save_emptysession.thuban")
96     save_session(session, filename)
97     session.Destroy()
98    
99     file = open(filename)
100     written_contents = file.read()
101     file.close()
102     self.compare_xml(written_contents,
103     '<?xml version="1.0" encoding="UTF-8"?>\n'
104 bh 1375 '<!DOCTYPE session SYSTEM "thuban-0.9.dtd">\n'
105 bh 1268 '<session title="empty session" '
106 bh 1375 'xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">'
107 bh 1268 '\n</session>\n')
108 bh 292
109 bh 1245 self.validate_data(written_contents)
110    
111 bh 292 def testSingleLayer(self):
112     """Save a session with a single map with a single layer"""
113     # deliberately put an apersand in the title :)
114     session = Session("single map&layer")
115     proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
116     map = Map("Test Map", projection = proj)
117     session.AddMap(map)
118     # use shapefile from the example data
119     shpfile = os.path.join(os.path.dirname(__file__),
120     os.pardir, "Data", "iceland", "political.shp")
121 bh 723 layer = Layer("My Layer", session.OpenShapefile(shpfile))
122 bh 292 map.AddLayer(layer)
123    
124     filename = self.temp_file_name("save_singlemap.thuban")
125     save_session(session, filename)
126    
127     file = open(filename)
128     written_contents = file.read()
129     file.close()
130 jonathan 775 expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
131 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
132 bh 1268 <session title="single map&amp;layer"
133 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
134 bh 1268 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
135 bh 292 <map title="Test Map">
136 jonathan 755 <projection name="Unknown">
137 bh 292 <parameter value="zone=26"/>
138     <parameter value="proj=utm"/>
139     <parameter value="ellps=clrk66"/>
140     </projection>
141 bh 1268 <layer title="My Layer" shapestore="D1"
142 jonathan 775 fill="None" stroke="#000000" stroke_width="1" visible="%s"/>
143 bh 292 </map>
144 bh 1268 </session>'''
145    
146 jonathan 775 expected_contents = expected_template % \
147     (os.path.join("..", "..", "Data", "iceland", "political.shp"),
148     "true")
149    
150 bh 292 self.compare_xml(written_contents, expected_contents)
151    
152 bh 1245 self.validate_data(written_contents)
153    
154 jonathan 775 layer.SetVisible(False)
155     save_session(session, filename)
156    
157     file = open(filename)
158     written_contents = file.read()
159     file.close()
160     expected_contents = expected_template % \
161     (os.path.join("..", "..", "Data", "iceland", "political.shp"),
162     "false")
163     self.compare_xml(written_contents, expected_contents)
164 bh 1245 self.validate_data(written_contents)
165 jonathan 775
166     session.Destroy()
167    
168 jonathan 755 def testLayerProjection(self):
169 bh 1268 """Test saving layers with projections"""
170 jonathan 755 # deliberately put an apersand in the title :)
171     session = Session("single map&layer")
172     proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
173     map = Map("Test Map", projection = proj)
174     session.AddMap(map)
175     # use shapefile from the example data
176     shpfile = os.path.join(os.path.dirname(__file__),
177     os.pardir, "Data", "iceland", "political.shp")
178     layer = Layer("My Layer", session.OpenShapefile(shpfile))
179     proj = Projection(["proj=lcc", "ellps=clrk66"], "Layer Projection")
180     layer.SetProjection(proj)
181     map.AddLayer(layer)
182 bh 292
183 bh 1268 filename = self.temp_file_name("save_layerproj.thuban")
184 jonathan 755 save_session(session, filename)
185     session.Destroy()
186 bh 292
187 jonathan 755 file = open(filename)
188     written_contents = file.read()
189     file.close()
190     expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
191 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
192 bh 1268 <session title="single map&amp;layer"
193 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
194 bh 1268 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
195 jonathan 755 <map title="Test Map">
196     <projection name="Unknown">
197     <parameter value="zone=26"/>
198     <parameter value="proj=utm"/>
199     <parameter value="ellps=clrk66"/>
200     </projection>
201 bh 1268 <layer title="My Layer" shapestore="D1"
202 jonathan 775 fill="None" stroke="#000000" stroke_width="1" visible="true">
203 jonathan 755 <projection name="Layer Projection">
204     <parameter value="proj=lcc"/>
205     <parameter value="ellps=clrk66"/>
206     </projection>
207     </layer>
208     </map>
209     </session>''' % os.path.join("..", "..", "Data", "iceland",
210     "political.shp")
211     #print written_contents
212     #print "********************************************"
213     #print expected_contents
214     self.compare_xml(written_contents, expected_contents)
215    
216 bh 1245 self.validate_data(written_contents)
217    
218 jonathan 947 def testRasterLayer(self):
219     # deliberately put an apersand in the title :)
220     session = Session("single map&layer")
221     map = Map("Test Map")
222     session.AddMap(map)
223     # use shapefile from the example data
224     imgfile = os.path.join(os.path.dirname(__file__),
225     os.pardir, "Data", "iceland", "island.tif")
226     layer = RasterLayer("My RasterLayer", imgfile)
227     map.AddLayer(layer)
228 bh 1245
229 jonathan 947 filename = self.temp_file_name("save_singlemap.thuban")
230     save_session(session, filename)
231     session.Destroy()
232 bh 1245
233 jonathan 947 file = open(filename)
234     written_contents = file.read()
235     file.close()
236     expected_contents = '''<?xml version="1.0" encoding="UTF-8"?>
237 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
238 bh 1268 <session title="single map&amp;layer"
239 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
240 jonathan 947 <map title="Test Map">
241 bh 1268 <rasterlayer title="My RasterLayer" filename="%s"
242 jonathan 947 visible="true">
243     </rasterlayer>
244     </map>
245 bh 1268 </session>''' % os.path.join(os.path.dirname(__file__),
246 jonathan 947 os.pardir, "Data", "iceland",
247     "island.tif")
248     #print written_contents
249     #print "********************************************"
250     #print expected_contents
251     self.compare_xml(written_contents, expected_contents)
252 jonathan 755
253 bh 1245 self.validate_data(written_contents)
254    
255 jonathan 1168 def testClassifiedLayer(self):
256 bh 1417 """Save a session with a single map with classifications"""
257 jonathan 1168 # deliberately put an apersand in the title :)
258 bh 1417 session = Session("Map with Classifications")
259 jonathan 1168 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
260     map = Map("Test Map", projection = proj)
261     session.AddMap(map)
262     # use shapefile from the example data
263     shpfile = os.path.join(os.path.dirname(__file__),
264     os.pardir, "Data", "iceland", "political.shp")
265     layer = Layer("My Layer", session.OpenShapefile(shpfile))
266     map.AddLayer(layer)
267 bh 1417 layer2 = Layer("My Layer", layer.ShapeStore())
268     map.AddLayer(layer2)
269 jonathan 755
270 jonathan 1168 clazz = layer.GetClassification()
271    
272 bh 1452 layer.SetClassificationColumn("AREA")
273 jonathan 1168
274 bh 1417 clazz.AppendGroup(ClassGroupSingleton(42, ClassGroupProperties(),
275     "single"))
276     clazz.AppendGroup(ClassGroupSingleton("text", ClassGroupProperties(),
277     "single-text"))
278 jonathan 1168
279 jonathan 1357 clazz.AppendGroup(ClassGroupRange((0, 42),
280 jonathan 1168 ClassGroupProperties(),
281     "range"))
282    
283     range = ClassGroupRange(Range("[0;42]"))
284     range.SetProperties(ClassGroupProperties())
285     range.SetLabel("new-range")
286     clazz.AppendGroup(range)
287    
288 bh 1417
289     clazz = layer2.GetClassification()
290 bh 1452 layer2.SetClassificationColumn("POPYCOUN")
291 bh 1417
292     # Classification with Latin 1 text
293     clazz.AppendGroup(ClassGroupSingleton('\xe4\xf6\xfc', # ae, oe, ue
294     ClassGroupProperties(),
295     '\xdcml\xe4uts')) # Uemlaeuts
296    
297    
298     filename = self.temp_file_name("%s.thuban" % self.id())
299 jonathan 1168 save_session(session, filename)
300    
301     file = open(filename)
302     written_contents = file.read()
303     file.close()
304     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
305 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
306 bh 1417 <session title="Map with Classifications"
307 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
308 bh 1268 <fileshapesource id="D1" filename="%s" filetype="shapefile"/>
309 jonathan 1168 <map title="Test Map">
310     <projection name="Unknown">
311     <parameter value="zone=26"/>
312     <parameter value="proj=utm"/>
313     <parameter value="ellps=clrk66"/>
314     </projection>
315 bh 1268 <layer title="My Layer" shapestore="D1"
316 jonathan 1168 fill="None" stroke="#000000" stroke_width="1" visible="%s">
317     <classification field="AREA" field_type="double">
318     <clnull label="">
319     <cldata fill="None" stroke="#000000" stroke_width="1"/>
320     </clnull>
321     <clpoint value="42" label="single">
322     <cldata fill="None" stroke="#000000" stroke_width="1"/>
323     </clpoint>
324     <clpoint value="text" label="single-text">
325     <cldata fill="None" stroke="#000000" stroke_width="1"/>
326     </clpoint>
327     <clrange range="[0;42[" label="range">
328     <cldata fill="None" stroke="#000000" stroke_width="1"/>
329     </clrange>
330     <clrange range="[0;42]" label="new-range">
331     <cldata fill="None" stroke="#000000" stroke_width="1"/>
332     </clrange>
333     </classification>
334     </layer>
335 bh 1417 <layer title="My Layer" shapestore="D1"
336     fill="None" stroke="#000000" stroke_width="1" visible="true">
337     <classification field="POPYCOUN" field_type="string">
338     <clnull label="">
339     <cldata fill="None" stroke="#000000" stroke_width="1"/>
340     </clnull>
341     <clpoint value="\xc3\xa4\xc3\xb6\xc3\xbc"
342     label="\xc3\x9cml\xc3\xa4uts">
343     <cldata fill="None" stroke="#000000" stroke_width="1"/>
344     </clpoint>
345     </classification>
346     </layer>
347 jonathan 1168 </map>
348 bh 1245 </session>'''
349    
350 jonathan 1168 expected_contents = expected_template % \
351     (os.path.join("..", "..", "Data", "iceland", "political.shp"),
352     "true")
353    
354     #print written_contents
355     #print "********************************************"
356     #print expected_contents
357     self.compare_xml(written_contents, expected_contents)
358    
359 bh 1245 self.validate_data(written_contents)
360    
361 jonathan 1168 session.Destroy()
362    
363 bh 1268 def test_dbf_table(self):
364     """Test saving a session with a dbf table link"""
365     session = Session("a DBF Table session")
366     # use shapefile from the example data
367     dbffile = os.path.join(os.path.dirname(__file__),
368     os.pardir, "Data", "iceland", "political.dbf")
369     table = session.AddTable(DBFTable(dbffile))
370 jonathan 1168
371 bh 1268 filename = self.temp_file_name("save_singletable.thuban")
372     save_session(session, filename)
373    
374     file = open(filename)
375     written_contents = file.read()
376     file.close()
377     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
378 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
379 bh 1268 <session title="a DBF Table session"
380 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
381 bh 1268 <filetable id="D1" filename="%s" filetype="DBF" title="political"/>
382     </session>'''
383    
384     expected_contents = expected_template % dbffile
385     self.compare_xml(written_contents, expected_contents)
386    
387     def test_joined_table(self):
388     """Test saving a session with joined table"""
389     # Create a simple table to use in the join
390     dbffile = self.temp_file_name("save_joinedtable.dbf")
391     dbf = dbflib.create(dbffile)
392     dbf.add_field("RDTYPE", dbflib.FTInteger, 10, 0)
393     dbf.add_field("TEXT", dbflib.FTString, 10, 0)
394     dbf.write_record(0, {'RDTYPE': 8, "TEXT": "foo"})
395     dbf.write_record(1, {'RDTYPE': 2, "TEXT": "bar"})
396     dbf.write_record(2, {'RDTYPE': 3, "TEXT": "baz"})
397     dbf.close()
398    
399     # Create the session and a map
400     session = Session("A Joined Table session")
401     try:
402     map = Map("Test Map")
403     session.AddMap(map)
404    
405     # Add the dbf file to the session
406     dbftable = session.AddTable(DBFTable(dbffile))
407    
408     # Create a layer with the shapefile to use in the join
409     shpfile = os.path.join(os.path.abspath(os.path.dirname(__file__)),
410     os.pardir, "Data", "iceland",
411     "roads-line.shp")
412     layer = Layer("My Layer", session.OpenShapefile(shpfile))
413     map.AddLayer(layer)
414    
415     # Do the join
416     store = layer.ShapeStore()
417     #for col in store.Table().Columns():
418     # print col.name
419     joined = TransientJoinedTable(session.TransientDB(),
420     store.Table(), "RDLNTYPE",
421 bh 1375 dbftable, "RDTYPE",
422     outer_join = True)
423 bh 1268 store = session.AddShapeStore(DerivedShapeStore(store, joined))
424     layer.SetShapeStore(store)
425    
426     # Save the session
427     filename = self.temp_file_name("save_joinedtable.thuban")
428     save_session(session, filename)
429    
430     # Read it back and compare
431     file = open(filename)
432     written_contents = file.read()
433     file.close()
434     expected_template = '''<?xml version="1.0" encoding="UTF-8"?>
435 bh 1375 <!DOCTYPE session SYSTEM "thuban-0.9.dtd">
436 bh 1268 <session title="A Joined Table session"
437 bh 1375 xmlns="http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd">
438 bh 1268 <fileshapesource filename="%(shpfile)s"
439     filetype="shapefile" id="D142197204"/>
440     <filetable filename="%(dbffile)s"
441     title="save_joinedtable"
442     filetype="DBF" id="D141881756"/>
443     <jointable id="D142180284"
444     title="Join of roads-line and save_joinedtable"
445     leftcolumn="RDLNTYPE" left="D142197204"
446 bh 1375 rightcolumn="RDTYPE" right="D141881756"
447     jointype="LEFT OUTER" />
448 bh 1268 <derivedshapesource id="D141915644"
449     table="D142180284"
450     shapesource="D142197204"/>
451     <map title="Test Map">
452     <layer title="My Layer"
453     shapestore="D141915644" visible="true"
454     stroke="#000000" stroke_width="1" fill="None"/>
455     </map>
456     </session>'''
457    
458     expected_contents = expected_template % {
459     "dbffile": relative_filename(self.temp_dir(), dbffile),
460     "shpfile": relative_filename(self.temp_dir(), shpfile)
461     }
462     self.compare_xml(written_contents, expected_contents)
463     finally:
464     session.Destroy()
465     session = None
466    
467    
468     class MockDataStore:
469    
470     """A very simple data store that only has dependencies"""
471    
472     def __init__(self, name, *dependencies):
473     self.name = name
474     self.dependencies = dependencies
475    
476     def __repr__(self):
477     return self.name
478    
479     def Dependencies(self):
480     return self.dependencies
481    
482    
483     class TestStoreSort(unittest.TestCase):
484    
485     def check_sort(self, containers, sorted):
486     """Check whether the list of data containers is sorted"""
487     # check whether sorted is in the right order
488     seen = {}
489     for container in sorted:
490     self.failIf(id(container) in seen,
491     "Container %r at least twice in %r" % (container,
492     sorted))
493     for dep in container.Dependencies():
494     self.assert_(id(dep) in seen,
495     "Dependency %r of %r not yet seen" % (dep,
496     container))
497     seen[id(container)] = 1
498     # check whether all of containers is in sorted
499     for container in containers:
500     self.assert_(id(container) in seen,
501     "Container %r in containers but not in sorted")
502     self.assertEquals(len(containers), len(sorted))
503    
504     def test_sort_data_stores(self):
505     """Test Thuban.Model.save.sort_data_stores"""
506     d1 = MockDataStore("d1")
507     d2 = MockDataStore("d2")
508     d3 = MockDataStore("d3", d1)
509     d4 = MockDataStore("d4", d1, d3)
510    
511     containers = [d4, d1, d2, d3]
512     self.check_sort(containers, sort_data_stores(containers))
513     containers = [d1, d3, d2, d4]
514     self.check_sort(containers, sort_data_stores(containers))
515    
516    
517    
518 bh 292 if __name__ == "__main__":
519     # Fake the __file__ global because it's needed by a test
520     import sys
521     __file__ = sys.argv[0]
522 bh 723 support.run_tests()

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26