/[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 2351 - (show annotations)
Sat Sep 25 18:49:20 2004 UTC (20 years, 5 months ago) by bh
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 19244 byte(s)
(TestLayer.test_arc_layer_with_projection):
Remove a debug print and some tab characters.

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 self.assertFloatSeqEqual(layer.ClipBoundingBox((-180, -6, 100, +120)),
194 (90.0, -6, 100, 11.1616263))
195 shapes = layer.ShapesInRegion((-180, -170, 200, +120))
196 self.assertEquals([s.ShapeID() for s in shapes],[0])
197
198 def test_empty_layer(self):
199 """Test Layer with empty shape file"""
200 # create an empty shape file
201 shapefilename = self.temp_file_name("layer_empty.shp")
202 shp = shapelib.create(shapefilename, shapelib.SHPT_POLYGON)
203 shp.close()
204 # create an empty DBF file too because Thuban can't cope yet
205 # with missing DBF file.
206 dbffilename = self.temp_file_name("layer_empty.dbf")
207 dbf = dbflib.create(dbffilename)
208 dbf.add_field("NAME", dbflib.FTString, 20, 0)
209 dbf.close()
210
211 # Now try to open it.
212 layer = self.layer = Layer("Empty Layer",
213 self.session.OpenShapefile(shapefilename))
214 self.assertEquals(layer.BoundingBox(), None)
215 self.assertEquals(layer.LatLongBoundingBox(), None)
216 self.assertEquals(layer.NumShapes(), 0)
217
218 def test_get_field_type(self):
219 """Test Layer.GetFieldType()"""
220 layer = self.layer = Layer("Test Layer",
221 self.open_shapefile("roads-line.shp"))
222 self.assertEquals(layer.GetFieldType("LENGTH"), FIELDTYPE_DOUBLE)
223 self.assertEquals(layer.GetFieldType("non existing"), None)
224
225 def test_raster_layer(self):
226 if not Thuban.Model.resource.has_gdal_support():
227 raise support.SkipTest("No gdal support")
228
229 filename = self.build_path("island.tif")
230 layer = RasterLayer("Test RasterLayer", filename)
231 self.failIf(layer.HasClassification())
232 self.failIf(layer.HasShapes())
233 self.assertEquals(layer.GetImageFilename(), os.path.abspath(filename))
234 self.assertFloatSeqEqual(layer.BoundingBox(),
235 [-24.5500000, 63.2833330,
236 -13.4916670, 66.5666670])
237 self.assertFloatSeqEqual(layer.LatLongBoundingBox(),
238 [-24.5500000, 63.2833330,
239 -13.4916670, 66.5666670])
240
241 def test_derived_store(self):
242 """Test layer with derived store"""
243 layer = self.layer = Layer("Test Layer",
244 self.open_shapefile("roads-line.shp"))
245 try:
246 store = layer.ShapeStore()
247 derived = DerivedShapeStore(store, store.Table())
248 layer.SetShapeStore(derived)
249 self.assert_(layer.ShapeStore() is derived)
250
251 self.assertEquals(layer.ShapeType(), SHAPETYPE_ARC)
252 self.assertEquals(layer.NumShapes(), 839)
253 shape = layer.Shape(32)
254 self.assertPointListEquals(shape.Points(),
255 [[(-15.082174301147, 66.277381896972),
256 (-15.026350021362, 66.273391723632)]])
257 self.assertFloatSeqEqual(layer.BoundingBox(),
258 [-24.450359344482422, 63.426830291748047,
259 -13.55668830871582, 66.520111083984375])
260 shapes = layer.ShapesInRegion((-24.0, 64.0, -23.75, 64.25))
261 self.assertEquals([s.ShapeID() for s in shapes],
262 [613, 726, 838])
263
264 self.assertFloatSeqEqual(layer.ShapesBoundingBox([32]),
265 [-15.082174301147461, 66.27339172363281,
266 -15.026350021362305, 66.27738189697265])
267
268 finally:
269 store = derived = None
270
271
272 class SetShapeStoreTests(unittest.TestCase, support.SubscriberMixin):
273
274 def setUp(self):
275 """Create a layer with a classification as self.layer"""
276 self.clear_messages()
277 self.session = Session("Test session for %s" % self.__class__)
278 self.shapefilename = os.path.join("..", "Data", "iceland",
279 "cultural_landmark-point.dbf")
280 self.store = self.session.OpenShapefile(self.shapefilename)
281 self.layer = Layer("test layer", self.store)
282 self.classification = Classification()
283 self.classification.AppendGroup(ClassGroupSingleton("FARM"))
284 self.layer.SetClassificationColumn("CLPTLABEL")
285 self.layer.SetClassification(self.classification)
286 self.layer.UnsetModified()
287 self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,
288 self.subscribe_with_params,
289 LAYER_SHAPESTORE_REPLACED)
290 self.layer.Subscribe(LAYER_CHANGED,
291 self.subscribe_with_params, LAYER_CHANGED)
292
293 def tearDown(self):
294 self.clear_messages()
295 self.layer.Destroy()
296 self.session.Destroy()
297 self.session = self.layer = self.store = self.classification = None
298
299 def test_sanity(self):
300 """SetShapeStoreTests sanity check
301
302 Test the initial state of the test case instances after setUp.
303 """
304 cls = self.layer.GetClassification()
305 self.assert_(cls is self.classification)
306 field = self.layer.GetClassificationColumn()
307 self.assertEquals(field, "CLPTLABEL")
308 self.assertEquals(self.layer.GetFieldType(field), FIELDTYPE_STRING)
309 self.assertEquals(self.layer.GetClassification().GetNumGroups(), 1)
310 self.failIf(self.layer.WasModified())
311
312 def test_set_shape_store_modified_flag(self):
313 """Test whether Layer.SetShapeStore() sets the modified flag"""
314 memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
315 [("bla",)] * self.layer.ShapeStore().Table().NumRows())
316 self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
317
318 self.assert_(self.layer.WasModified())
319
320 def test_set_shape_store_different_field_name(self):
321 """Test Layer.SetShapeStore() with different column name"""
322 memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
323 [("bla",)] * self.layer.ShapeStore().Table().NumRows())
324 self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
325 # The classification should contain only the default group now.
326 self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
327 self.check_messages([(self.layer, LAYER_CHANGED),
328 (self.layer, LAYER_SHAPESTORE_REPLACED)])
329
330 def test_set_shape_store_same_field(self):
331 """Test Layer.SetShapeStore() with same column name and type"""
332 memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_STRING)],
333 [("bla",)] * self.layer.ShapeStore().Table().NumRows())
334 self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
335 # The classification should be the same as before
336 self.assert_(self.layer.GetClassification() is self.classification)
337 self.check_messages([(self.layer, LAYER_SHAPESTORE_REPLACED)])
338
339 def test_set_shape_store_same_field_different_type(self):
340 """Test Layer.SetShapeStore() with same column name but different type
341 """
342 memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_DOUBLE)],
343 [(0.0,)] * self.layer.ShapeStore().Table().NumRows())
344 self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
345 # The classification should contain only the default group now.
346 self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
347 self.check_messages([(self.layer, LAYER_CHANGED),
348 (self.layer, LAYER_SHAPESTORE_REPLACED)])
349
350
351 class TestLayerModification(unittest.TestCase, support.SubscriberMixin):
352
353 """Test cases for Layer method that modify the layer.
354 """
355
356 def setUp(self):
357 """Clear the list of received messages and create a layer and a session
358
359 The layer is bound to self.layer and the session to self.session.
360 """
361 self.clear_messages()
362 self.session = Session("Test session for %s" % self.__class__)
363 self.filename = os.path.join("..", "Data", "iceland", "political.shp")
364 self.layer = Layer("Test Layer",
365 self.session.OpenShapefile(self.filename))
366 self.layer.Subscribe(LAYER_LEGEND_CHANGED, self.subscribe_with_params,
367 LAYER_LEGEND_CHANGED)
368 self.layer.Subscribe(LAYER_VISIBILITY_CHANGED,
369 self.subscribe_with_params,
370 LAYER_VISIBILITY_CHANGED)
371 self.layer.Subscribe(LAYER_CHANGED, self.subscribe_with_params,
372 LAYER_CHANGED)
373
374 def tearDown(self):
375 """Clear the list of received messages and explictly destroy self.layer
376 """
377 self.layer.Destroy()
378 self.layer = None
379 self.session.Destroy()
380 self.session = None
381 self.clear_messages()
382
383 def test_sanity(self):
384 """TestLayerModification Sanity Checks"""
385 # test default settings
386 self.failIf(self.layer.WasModified())
387 self.assertEquals(self.layer.Visible(), 1)
388 # no messages should have been produced
389 self.check_messages([])
390
391 def test_visibility(self):
392 """Test Layer visibility"""
393 self.layer.SetVisible(0)
394 self.assertEquals(self.layer.Visible(), 0)
395 self.check_messages([(self.layer, LAYER_VISIBILITY_CHANGED)])
396
397 # currently, modifying the visibility doesn't count as changing
398 # the layer.
399 self.failIf(self.layer.WasModified())
400
401 def test_set_classification(self):
402 """Test Layer.SetClassification"""
403 classification = Classification()
404 classification.AppendGroup(ClassGroupRange((0.0, 0.1)))
405
406 self.layer.SetClassification(classification)
407 self.layer.SetClassificationColumn("AREA")
408
409 self.check_messages([(self.layer, LAYER_CHANGED),
410 (self.layer, LAYER_CHANGED)])
411 self.failUnless(self.layer.WasModified())
412
413 self.clear_messages()
414 self.layer.UnsetModified()
415
416 # change only the classification column. This should issue a
417 # LAYER_CHANGED message as well.
418 self.layer.SetClassificationColumn("PERIMETER")
419
420 self.check_messages([(self.layer, LAYER_CHANGED)])
421 self.failUnless(self.layer.WasModified())
422
423
424 def test_tree_info(self):
425 """Test Layer.TreeInfo"""
426 self.assertEquals(self.layer.TreeInfo(),
427 ("Layer 'Test Layer'",
428 ['Filename: %s' % os.path.abspath(self.filename),
429 'Shown',
430 'Shapes: 156',
431 'Extent (lat-lon): (-24.5465, 63.2868, -13.4958, 66.5638)',
432 'Shapetype: Polygon',
433 self.layer.GetClassification()]))
434
435
436 if __name__ == "__main__":
437 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