/[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 1983 - (hide annotations)
Thu Nov 27 15:57:23 2003 UTC (21 years, 3 months ago) by bh
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 18998 byte(s)
* Thuban/Model/layer.py (Layer.LatLongBoundingBox)
(Layer.ShapesBoundingBox, RasterLayer.LatLongBoundingBox): Use the
new InverseBBox method to determine the unprojected bounding box
(Layer.ShapesInRegion): Use the ForwardBBox method to project the
bbox.

* test/test_layer.py (TestLayer.test_point_layer_with_projection):
Removed.
(TestLayer.test_arc_layer_with_projection): New. This test is
better able to test whether bounding boxes are projected correctly
than test_point_layer_with_projection

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