/[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 1538 - (hide annotations)
Fri Aug 1 14:27:46 2003 UTC (21 years, 7 months ago) by bh
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 17673 byte(s)
Import the SHAPETYPE_* constants from data
instead of layer.
(TestLayer.test_derived_store): Remove the test for the exception
when instantiating the DerivedShapeStore with an incompatible
table which is now in test_derivedshapestore.py. Add some more
tests of the layer methods to determine whether they work for a
DerivedShapeStore as well.

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