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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1438 - (show annotations)
Wed Jul 16 13:25:30 2003 UTC (21 years, 7 months ago) by jonathan
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 16376 byte(s)
(SetShapeStoreTests.setUp): Classification
        __init__ no longer has a field parameter, use SetClassificationField.
(SetShapeStoreTests.test_sanity): Use layer object to get class field info.

1 # Copyright (c) 2002, 2003 by Intevation GmbH
2 # 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 import dbflib
24
25 from Thuban.Model.session import Session
26 from Thuban.Model.layer import BaseLayer, Layer, RasterLayer, \
27 SHAPETYPE_POLYGON, SHAPETYPE_ARC, SHAPETYPE_POINT
28 from Thuban.Model.messages import LAYER_LEGEND_CHANGED, \
29 LAYER_VISIBILITY_CHANGED, LAYER_SHAPESTORE_REPLACED, LAYER_CHANGED
30 from Thuban.Model.color import Color
31 from Thuban.Model.table import FIELDTYPE_DOUBLE, FIELDTYPE_STRING, MemoryTable
32 from Thuban.Model.proj import Projection
33 from Thuban.Model.data import DerivedShapeStore
34 from Thuban.Model.classification import Classification, ClassGroupSingleton
35
36 import Thuban.Model.resource
37
38 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 def setUp(self):
49 """Create a session self.session and initialize self.layer to None"""
50 self.session = Session("Test session for %s" % self.__class__)
51 self.layer = None
52
53 def tearDown(self):
54 """Call the layer's Destroy method and set session and layer to None"""
55 self.session = None
56 if self.layer is not None:
57 self.layer.Destroy()
58 self.layer = None
59
60 def build_path(self, filename):
61 return os.path.join("..", "Data", "iceland", filename)
62
63 def open_shapefile(self, filename):
64 """Open and return a shapestore for filename in the iceland data set"""
65 return self.session.OpenShapefile(self.build_path(filename))
66
67 def test_base_layer(self):
68 layer = self.layer = BaseLayer("Test BaseLayer")
69 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.failIf(layer.HasShapes())
81
82 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 def test_arc_layer(self):
96 """Test Layer with arc shapes"""
97 layer = self.layer = Layer("Test Layer",
98 self.open_shapefile("roads-line.shp"))
99 self.failUnless(layer.HasClassification())
100 self.failUnless(layer.HasShapes())
101 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
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 def test_polygon_layer(self):
132 """Test Layer with polygon shapes"""
133 layer = self.layer = Layer("Test Layer",
134 self.open_shapefile("political.shp"))
135 self.failUnless(layer.HasClassification())
136 self.failUnless(layer.HasShapes())
137 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 layer = self.layer = Layer("Test Layer",
154 self.open_shapefile("cultural_landmark-point.shp"))
155 self.failUnless(layer.HasClassification())
156 self.failUnless(layer.HasShapes())
157 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 # 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
180 # Now try to open it.
181 layer = self.layer = Layer("Empty Layer",
182 self.session.OpenShapefile(shapefilename))
183 self.assertEquals(layer.BoundingBox(), None)
184 self.assertEquals(layer.LatLongBoundingBox(), None)
185 self.assertEquals(layer.NumShapes(), 0)
186
187 def test_get_field_type(self):
188 """Test Layer.GetFieldType()"""
189 layer = self.layer = Layer("Test Layer",
190 self.open_shapefile("roads-line.shp"))
191 self.assertEquals(layer.GetFieldType("LENGTH"), FIELDTYPE_DOUBLE)
192 self.assertEquals(layer.GetFieldType("non existing"), None)
193
194 def test_raster_layer(self):
195 if not Thuban.Model.resource.has_gdal_support():
196 return
197
198 filename = self.build_path("island.tif")
199 layer = RasterLayer("Test RasterLayer", filename)
200 self.failIf(layer.HasClassification())
201 self.failIf(layer.HasShapes())
202 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
210 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
220 # check that an exception is raised when the number
221 # of shapes differ from the number of rows in a table.
222 layer2 = Layer("Test Layer",
223 self.open_shapefile("political.shp"))
224 store2 = layer2.ShapeStore()
225 self.assertRaises(ValueError,
226 DerivedShapeStore, store2, store.Table())
227
228 finally:
229 store = derived = None
230 layer2.Destroy()
231 store2 = None
232
233
234 class SetShapeStoreTests(unittest.TestCase, support.SubscriberMixin):
235
236 def setUp(self):
237 """Create a layer with a classification as self.layer"""
238 self.clear_messages()
239 self.session = Session("Test session for %s" % self.__class__)
240 self.shapefilename = os.path.join("..", "Data", "iceland",
241 "cultural_landmark-point.dbf")
242 self.store = self.session.OpenShapefile(self.shapefilename)
243 self.layer = Layer("test layer", self.store)
244 self.classification = Classification()
245 self.classification.AppendGroup(ClassGroupSingleton("FARM"))
246 self.layer.SetClassificationField("CLPTLABEL")
247 self.layer.SetClassification(self.classification)
248 self.layer.UnsetModified()
249 self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,
250 self.subscribe_with_params,
251 LAYER_SHAPESTORE_REPLACED)
252 self.layer.Subscribe(LAYER_CHANGED,
253 self.subscribe_with_params, LAYER_CHANGED)
254
255 def tearDown(self):
256 self.clear_messages()
257 self.layer.Destroy()
258 self.session.Destroy()
259 self.session = self.layer = self.store = self.classification = None
260
261 def test_sanity(self):
262 """SetShapeStoreTests sanity check
263
264 Test the initial state of the test case instances after setUp.
265 """
266 cls = self.layer.GetClassification()
267 self.assert_(cls is self.classification)
268 field = self.layer.GetClassificationField()
269 self.assertEquals(field, "CLPTLABEL")
270 self.assertEquals(self.layer.GetFieldType(field), FIELDTYPE_STRING)
271 self.assertEquals(self.layer.GetClassification().GetNumGroups(), 1)
272 self.failIf(self.layer.WasModified())
273
274 def test_set_shape_store_modified_flag(self):
275 """Test whether Layer.SetShapeStore() sets the modified flag"""
276 memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
277 [("bla",)] * self.layer.ShapeStore().Table().NumRows())
278 self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
279
280 self.assert_(self.layer.WasModified())
281
282 def test_set_shape_store_different_field_name(self):
283 """Test Layer.SetShapeStore() with different column name"""
284 memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
285 [("bla",)] * self.layer.ShapeStore().Table().NumRows())
286 self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
287 # The classification should contain only the default group now.
288 self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
289 self.check_messages([(self.layer, LAYER_CHANGED),
290 (self.layer, LAYER_SHAPESTORE_REPLACED)])
291
292 def test_set_shape_store_same_field(self):
293 """Test Layer.SetShapeStore() with same column name and type"""
294 memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_STRING)],
295 [("bla",)] * self.layer.ShapeStore().Table().NumRows())
296 self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
297 # The classification should be the same as before
298 self.assert_(self.layer.GetClassification() is self.classification)
299 self.check_messages([(self.layer, LAYER_SHAPESTORE_REPLACED)])
300
301 def test_set_shape_store_same_field_different_type(self):
302 """Test Layer.SetShapeStore() with same column name but different type
303 """
304 memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_DOUBLE)],
305 [(0.0,)] * self.layer.ShapeStore().Table().NumRows())
306 self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
307 # The classification should contain only the default group now.
308 self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
309 self.check_messages([(self.layer, LAYER_CHANGED),
310 (self.layer, LAYER_SHAPESTORE_REPLACED)])
311
312
313 class TestLayerLegend(unittest.TestCase, support.SubscriberMixin):
314
315 """Test cases for Layer method that modify the layer.
316 """
317
318 def setUp(self):
319 """Clear the list of received messages and create a layer and a session
320
321 The layer is bound to self.layer and the session to self.session.
322 """
323 self.clear_messages()
324 self.session = Session("Test session for %s" % self.__class__)
325 filename = os.path.join("..", "Data", "iceland", "political.shp")
326 self.layer = Layer("Test Layer",
327 self.session.OpenShapefile(filename))
328 self.layer.Subscribe(LAYER_LEGEND_CHANGED, self.subscribe_with_params,
329 LAYER_LEGEND_CHANGED)
330 self.layer.Subscribe(LAYER_VISIBILITY_CHANGED,
331 self.subscribe_with_params,
332 LAYER_VISIBILITY_CHANGED)
333
334 def tearDown(self):
335 """Clear the list of received messages and explictly destroy self.layer
336 """
337 self.layer.Destroy()
338 self.layer = None
339 self.session.Destroy()
340 self.session = None
341 self.clear_messages()
342
343 def test_initial_settings(self):
344 """Test Layer's initial legend attributes"""
345 # test default settings
346 self.failIf(self.layer.WasModified())
347 #self.assertEquals(self.layer.fill, None)
348 #self.assertEquals(self.layer.stroke.hex(), "#000000")
349 #self.assertEquals(self.layer.stroke_width, 1)
350 self.assertEquals(self.layer.Visible(), 1)
351 # no messages should have been produced
352 self.check_messages([])
353
354 def test_visibility(self):
355 """Test Layer visibility"""
356 self.layer.SetVisible(0)
357 self.assertEquals(self.layer.Visible(), 0)
358 self.check_messages([(self.layer, LAYER_VISIBILITY_CHANGED)])
359
360 # currently, modifying the visibility doesn't count as changing
361 # the layer.
362 self.failIf(self.layer.WasModified())
363
364
365 #
366 # the tree info now contains Color objects which are difficult to test
367 #
368 # def test_tree_info(self):
369 # """Test Layer.TreeInfo"""
370 # self.assertEquals(self.layer.TreeInfo(),
371 # ("Layer 'Test Layer'",
372 # ['Shown',
373 # 'Shapes: 156',
374 # ('Extent (lat-lon):'
375 # ' (-24.5465, 63.2868, -13.4958, 66.5638)'),
376 # 'Shapetype: Polygon',
377 # 'Fill: None',
378 # 'Outline: (0.000, 0.000, 0.000)']))
379
380
381 if __name__ == "__main__":
382 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