/[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 1599 - (hide annotations)
Mon Aug 18 12:45:28 2003 UTC (21 years, 6 months ago) by bh
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 18730 byte(s)
Fix some bugs in Thuban and the test suite that were uncovered by
changes introduced in Python 2.3:

* Thuban/Model/table.py (DBFTable.__init__): Make sure the
filename is an absolute name

* Thuban/Model/layer.py (RasterLayer.__init__): Make sure the
filename is an absolute name

* test/test_save.py (SaveSessionTest.testRasterLayer): Use a
unique filename to save to and use the correct relative filename
in the expected output.
(SaveSessionTest.test_dbf_table): Use the correct relative
filename in the expected output.

* test/test_layer.py (TestLayer.test_raster_layer): Update the
test to check whether the filename is absolute.

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