/[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 1262 - (hide annotations)
Fri Jun 20 14:15:30 2003 UTC (21 years, 8 months ago) by jonathan
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 15877 byte(s)
(TestLayer.test_derived_store): Add
        a test for the new exception in DerivedShapeStore.__init__.

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