/[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 2229 - (show annotations)
Thu Jun 3 15:18:07 2004 UTC (20 years, 9 months ago) by bh
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 18978 byte(s)
(TestLayerModification.setUp): Save the
filename as an instance variable so we can refer to it in tests
(TestLayerModification.test_tree_info): Uncomment this method
again and make it work.  This tests for the formatting issue
filed in RT#2239 on 2004-01-13

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