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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1142 - (hide annotations)
Tue Jun 10 09:41:57 2003 UTC (21 years, 9 months ago) by bh
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 15320 byte(s)
* Thuban/Model/messages.py (LAYER_SHAPESTORE_REPLACED): New
message.

* Thuban/Model/layer.py (Layer.SetShapeStore): Send
LAYER_SHAPESTORE_REPLACED when the shapestore changes. A
LAYER_CHANGED will still be sent if the classification changes.

* Thuban/UI/classifier.py (Classifier.__init__): Add the map as
parameter so we can subscribe to some of its messages
(Classifier.__init__): Subscribe to the map's MAP_LAYERS_REMOVED
and the layer's LAYER_SHAPESTORE_REPLACED
(Classifier.unsubscribe_messages): New. Unsubscribe from message
subscribed to in __init__
(Classifier.map_layers_removed)
(Classifier.layer_shapestore_replaced): receivers for the messages
subscribed to in __init__. Unsubscribe and close the dialog

* Thuban/UI/mainwindow.py (MainWindow.OpenLayerProperties): Pass
the map to the Classifier dialog

* test/test_layer.py (SetShapeStoreTests): Derive from
SubscriberMixin as well so we can test messages
(SetShapeStoreTests.setUp): Subscribe to some of the layer's
messages
(SetShapeStoreTests.tearDown): Clear the messages again
(SetShapeStoreTests.test_sanity): Expand the doc-string and check
for the modified flag too
(SetShapeStoreTests.test_set_shape_store_modified_flag): New test
to check whether SetShapeStore sets the modified flag
(SetShapeStoreTests.test_set_shape_store_different_field_name)
(SetShapeStoreTests.test_set_shape_store_same_field)
(SetShapeStoreTests.test_set_shape_store_same_field_different_type):
Add tests for the messages. This checks both the new
LAYER_SHAPESTORE_REPLACED and the older LAYER_CHANGED

1 bh 599 # Copyright (c) 2002, 2003 by Intevation GmbH
2 bh 331 # 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 the Layer class
10     """
11    
12     __version__ = "$Revision$"
13     # $Source$
14     # $Id$
15    
16     import os
17     import unittest
18    
19     import support
20     support.initthuban()
21    
22     import shapelib
23 bh 336 import dbflib
24 bh 331
25 bh 723 from Thuban.Model.session import Session
26 jonathan 947 from Thuban.Model.layer import BaseLayer, Layer, RasterLayer, \
27     SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
28 bh 331 from Thuban.Model.messages import LAYER_LEGEND_CHANGED, \
29 bh 1142 LAYER_VISIBILITY_CHANGED, LAYER_SHAPESTORE_REPLACED, LAYER_CHANGED
30 bh 331 from Thuban.Model.color import Color
31 bh 1088 from Thuban.Model.table import FIELDTYPE_DOUBLE, FIELDTYPE_STRING, MemoryTable
32 jonathan 947 from Thuban.Model.proj import Projection
33 bh 996 from Thuban.Model.data import DerivedShapeStore
34 bh 1088 from Thuban.Model.classification import Classification, ClassGroupSingleton
35 bh 331
36     class TestLayer(unittest.TestCase, support.FileTestMixin,
37     support.FloatComparisonMixin):
38    
39     """Test cases for different layer (shape) types"""
40    
41     def assertFloatTuplesEqual(self, test, value):
42     """Assert equality of two lists of tuples of float"""
43     for i in range(len(test)):
44     self.assertFloatSeqEqual(test[i], value[i])
45    
46 bh 723 def setUp(self):
47 bh 996 """Create a session self.session and initialize self.layer to None"""
48 bh 723 self.session = Session("Test session for %s" % self.__class__)
49 bh 996 self.layer = None
50 bh 723
51     def tearDown(self):
52 bh 996 """Call the layer's Destroy method and set session and layer to None"""
53 bh 723 self.session = None
54 bh 996 if self.layer is not None:
55     self.layer.Destroy()
56     self.layer = None
57 bh 723
58 jonathan 947 def build_path(self, filename):
59     return os.path.join("..", "Data", "iceland", filename)
60 bh 996
61 bh 839 def open_shapefile(self, filename):
62     """Open and return a shapestore for filename in the iceland data set"""
63 jonathan 947 return self.session.OpenShapefile(self.build_path(filename))
64 bh 839
65 jonathan 947 def test_base_layer(self):
66 bh 996 layer = self.layer = BaseLayer("Test BaseLayer")
67 jonathan 947 self.assertEquals(layer.Title(), "Test BaseLayer")
68     self.failUnless(layer.Visible())
69    
70     # toggle visibility
71     layer.SetVisible(False)
72     self.failIf(layer.Visible())
73    
74     layer.SetVisible(True)
75     self.failUnless(layer.Visible())
76    
77     self.failIf(layer.HasClassification())
78     self.assertEquals(layer.GetProjection(), None)
79    
80     # set/get projection
81     proj = Projection(["proj=utm", "zone=26"])
82    
83     layer.SetProjection(proj)
84     self.failUnless(layer.GetProjection() is proj)
85    
86     # __init__ with other arguments
87     layer = BaseLayer("Test BaseLayer", False, proj)
88     self.failIf(layer.Visible())
89     self.failUnless(layer.GetProjection() is proj)
90    
91 bh 331 def test_arc_layer(self):
92     """Test Layer with arc shapes"""
93 bh 996 layer = self.layer = Layer("Test Layer",
94     self.open_shapefile("roads-line.shp"))
95 bh 331 self.assertEquals(layer.ShapeType(), SHAPETYPE_ARC)
96     self.assertEquals(layer.NumShapes(), 839)
97     shape = layer.Shape(32)
98     self.assertFloatTuplesEqual(shape.Points(),
99     [(-15.082174301147461, 66.27738189697265),
100     (-15.026350021362305, 66.27339172363281)])
101     self.assertFloatSeqEqual(layer.BoundingBox(),
102     [-24.450359344482422, 63.426830291748047,
103     -13.55668830871582, 66.520111083984375])
104     self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.75, 64.25)),
105     [613, 726, 838])
106 jonathan 832
107     self.assertFloatSeqEqual(layer.ShapesBoundingBox([32]),
108     [-15.082174301147461, 66.27339172363281,
109     -15.026350021362305, 66.27738189697265])
110    
111     shape = layer.Shape(33)
112     self.assertFloatTuplesEqual(shape.Points(),
113     [(-22.248506546020508, 66.30645751953125),
114     (-22.232730865478516, 66.294075012207031),
115     (-22.23158073425293, 66.287689208984375),
116     (-22.246318817138672, 66.270065307617188)])
117    
118     self.assertFloatSeqEqual(layer.ShapesBoundingBox([32, 33]),
119     [-22.248506546020508, 66.270065307617188,
120     -15.026350021362305, 66.30645751953125])
121    
122     self.assertEquals(layer.ShapesBoundingBox([]), None)
123     self.assertEquals(layer.ShapesBoundingBox(None), None)
124    
125 bh 331 def test_polygon_layer(self):
126     """Test Layer with polygon shapes"""
127 bh 996 layer = self.layer = Layer("Test Layer",
128     self.open_shapefile("political.shp"))
129 bh 331 self.assertEquals(layer.ShapeType(), SHAPETYPE_POLYGON)
130     self.assertEquals(layer.NumShapes(), 156)
131     shape = layer.Shape(4)
132     self.assertFloatTuplesEqual(shape.Points(),
133     [(-22.406391143798828, 64.714111328125),
134     (-22.41621208190918, 64.71600341796875),
135     (-22.406051635742188, 64.719200134277344),
136     (-22.406391143798828, 64.714111328125)])
137     self.assertFloatSeqEqual(layer.BoundingBox(),
138     [-24.546524047851562, 63.286754608154297,
139     -13.495815277099609, 66.563774108886719])
140     self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.9, 64.1)),
141     [91, 92, 144, 146, 148, 150, 152, 153])
142    
143     def test_point_layer(self):
144     """Test Layer with point shapes"""
145 bh 996 layer = self.layer = Layer("Test Layer",
146     self.open_shapefile("cultural_landmark-point.shp"))
147 bh 331 self.assertEquals(layer.ShapeType(), SHAPETYPE_POINT)
148     self.assertEquals(layer.NumShapes(), 34)
149     shape = layer.Shape(0)
150     self.assertFloatTuplesEqual(shape.Points(),
151     [(-22.711074829101562, 66.36572265625)])
152     self.assertFloatSeqEqual(layer.BoundingBox(),
153     [-23.806047439575195, 63.405960083007812,
154     -15.12291431427002, 66.36572265625])
155     self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.80, 64.1)),
156     [0, 1, 2, 3, 4, 5, 27, 28, 29, 30, 31])
157    
158     def test_empty_layer(self):
159     """Test Layer with empty shape file"""
160     # create an empty shape file
161     shapefilename = self.temp_file_name("layer_empty.shp")
162     shp = shapelib.create(shapefilename, shapelib.SHPT_POLYGON)
163     shp.close()
164 bh 336 # create an empty DBF file too because Thuban can't cope yet
165     # with missing DBF file.
166     dbffilename = self.temp_file_name("layer_empty.dbf")
167     dbf = dbflib.create(dbffilename)
168     dbf.add_field("NAME", dbflib.FTString, 20, 0)
169 bh 331
170 bh 336 # Now try to open it.
171 bh 996 layer = self.layer = Layer("Empty Layer",
172     self.session.OpenShapefile(shapefilename))
173 bh 331 self.assertEquals(layer.BoundingBox(), None)
174     self.assertEquals(layer.LatLongBoundingBox(), None)
175     self.assertEquals(layer.NumShapes(), 0)
176    
177 bh 839 def test_get_field_type(self):
178     """Test Layer.GetFieldType()"""
179 bh 996 layer = self.layer = Layer("Test Layer",
180     self.open_shapefile("roads-line.shp"))
181 bh 839 self.assertEquals(layer.GetFieldType("LENGTH"), FIELDTYPE_DOUBLE)
182     self.assertEquals(layer.GetFieldType("non existing"), None)
183 bh 331
184 jonathan 947 def test_raster_layer(self):
185     filename = self.build_path("island.tif")
186     layer = RasterLayer("Test RasterLayer", filename)
187     self.assertEquals(layer.GetImageFilename(), filename)
188     self.assertFloatSeqEqual(layer.BoundingBox(),
189     [-24.5500000, 63.2833330,
190     -13.4916670, 66.5666670])
191     self.assertFloatSeqEqual(layer.LatLongBoundingBox(),
192     [-24.5500000, 63.2833330,
193     -13.4916670, 66.5666670])
194 bh 839
195 bh 996 def test_derived_store(self):
196     """Test layer with derived store"""
197     layer = self.layer = Layer("Test Layer",
198     self.open_shapefile("roads-line.shp"))
199     try:
200     store = layer.ShapeStore()
201     derived = DerivedShapeStore(store, store.Table())
202     layer.SetShapeStore(derived)
203     self.assert_(layer.ShapeStore() is derived)
204     finally:
205     store = derived = None
206 jonathan 947
207 bh 996
208 bh 1142 class SetShapeStoreTests(unittest.TestCase, support.SubscriberMixin):
209 bh 1088
210     def setUp(self):
211     """Create a layer with a classification as self.layer"""
212 bh 1142 self.clear_messages()
213 bh 1088 self.session = Session("Test session for %s" % self.__class__)
214     self.shapefilename = os.path.join("..", "Data", "iceland",
215     "cultural_landmark-point.dbf")
216     self.store = self.session.OpenShapefile(self.shapefilename)
217     self.layer = Layer("test layer", self.store)
218     self.classification = Classification(field = "CLPTLABEL")
219     self.classification.AppendGroup(ClassGroupSingleton("FARM"))
220     self.layer.SetClassification(self.classification)
221 bh 1142 self.layer.UnsetModified()
222     self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,
223     self.subscribe_with_params,
224     LAYER_SHAPESTORE_REPLACED)
225     self.layer.Subscribe(LAYER_CHANGED,
226     self.subscribe_with_params, LAYER_CHANGED)
227 bh 1088
228     def tearDown(self):
229 bh 1142 self.clear_messages()
230 bh 1088 self.layer.Destroy()
231     self.session.Destroy()
232     self.session = self.layer = self.store = self.classification = None
233    
234     def test_sanity(self):
235 bh 1142 """SetShapeStoreTests sanity check
236    
237     Test the initial state of the test case instances after setUp.
238     """
239 bh 1088 cls = self.layer.GetClassification()
240     self.assert_(cls is self.classification)
241     self.assertEquals(cls.GetField(), "CLPTLABEL")
242     self.assertEquals(cls.GetFieldType(), FIELDTYPE_STRING)
243     self.assertEquals(self.layer.GetClassification().GetNumGroups(), 1)
244 bh 1142 self.failIf(self.layer.WasModified())
245 bh 1088
246 bh 1142 def test_set_shape_store_modified_flag(self):
247     """Test whether Layer.SetShapeStore() sets the modified flag"""
248     memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
249     [("bla",)] * self.layer.ShapeStore().Table().NumRows())
250     self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
251    
252     self.assert_(self.layer.WasModified())
253    
254 bh 1088 def test_set_shape_store_different_field_name(self):
255     """Test Layer.SetShapeStore() with different column name"""
256     memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
257     [("bla",)] * self.layer.ShapeStore().Table().NumRows())
258     self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
259     # The classification should contain only the default group now.
260     self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
261 bh 1142 self.check_messages([(self.layer, LAYER_CHANGED),
262     (self.layer, LAYER_SHAPESTORE_REPLACED)])
263 bh 1088
264     def test_set_shape_store_same_field(self):
265     """Test Layer.SetShapeStore() with same column name and type"""
266     memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_STRING)],
267     [("bla",)] * self.layer.ShapeStore().Table().NumRows())
268     self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
269     # The classification should be the same as before
270     self.assert_(self.layer.GetClassification() is self.classification)
271 bh 1142 self.check_messages([(self.layer, LAYER_SHAPESTORE_REPLACED)])
272 bh 1088
273     def test_set_shape_store_same_field_different_type(self):
274     """Test Layer.SetShapeStore() with same column name but different type
275     """
276     memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_DOUBLE)],
277     [(0.0,)] * self.layer.ShapeStore().Table().NumRows())
278     self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
279     # The classification should contain only the default group now.
280     self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
281 bh 1142 self.check_messages([(self.layer, LAYER_CHANGED),
282     (self.layer, LAYER_SHAPESTORE_REPLACED)])
283 bh 1088
284    
285 bh 331 class TestLayerLegend(unittest.TestCase, support.SubscriberMixin):
286    
287     """Test cases for Layer method that modify the layer.
288     """
289    
290     def setUp(self):
291 bh 723 """Clear the list of received messages and create a layer and a session
292 bh 331
293 bh 723 The layer is bound to self.layer and the session to self.session.
294 bh 331 """
295     self.clear_messages()
296 bh 723 self.session = Session("Test session for %s" % self.__class__)
297     filename = os.path.join("..", "Data", "iceland", "political.shp")
298 bh 331 self.layer = Layer("Test Layer",
299 bh 723 self.session.OpenShapefile(filename))
300 bh 331 self.layer.Subscribe(LAYER_LEGEND_CHANGED, self.subscribe_with_params,
301     LAYER_LEGEND_CHANGED)
302     self.layer.Subscribe(LAYER_VISIBILITY_CHANGED,
303     self.subscribe_with_params,
304     LAYER_VISIBILITY_CHANGED)
305    
306     def tearDown(self):
307     """Clear the list of received messages and explictly destroy self.layer
308     """
309     self.layer.Destroy()
310 bh 723 self.layer = None
311     self.session.Destroy()
312     self.session = None
313 bh 331 self.clear_messages()
314    
315     def test_initial_settings(self):
316     """Test Layer's initial legend attributes"""
317     # test default settings
318     self.failIf(self.layer.WasModified())
319 jonathan 409 #self.assertEquals(self.layer.fill, None)
320     #self.assertEquals(self.layer.stroke.hex(), "#000000")
321     #self.assertEquals(self.layer.stroke_width, 1)
322 bh 331 self.assertEquals(self.layer.Visible(), 1)
323     # no messages should have been produced
324     self.check_messages([])
325    
326     def test_visibility(self):
327     """Test Layer visibility"""
328     self.layer.SetVisible(0)
329     self.assertEquals(self.layer.Visible(), 0)
330     self.check_messages([(self.layer, LAYER_VISIBILITY_CHANGED)])
331    
332     # currently, modifying the visibility doesn't count as changing
333     # the layer.
334     self.failIf(self.layer.WasModified())
335    
336 jonathan 395
337     #
338     # the tree info now contains Color objects which are difficult to test
339     #
340     # def test_tree_info(self):
341     # """Test Layer.TreeInfo"""
342     # self.assertEquals(self.layer.TreeInfo(),
343     # ("Layer 'Test Layer'",
344     # ['Shown',
345     # 'Shapes: 156',
346     # ('Extent (lat-lon):'
347     # ' (-24.5465, 63.2868, -13.4958, 66.5638)'),
348     # 'Shapetype: Polygon',
349     # 'Fill: None',
350     # 'Outline: (0.000, 0.000, 0.000)']))
351 bh 331
352    
353     if __name__ == "__main__":
354 bh 599 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