/[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 2339 - (hide annotations)
Fri Aug 20 16:59:21 2004 UTC (20 years, 6 months ago) by silke
Original Path: trunk/thuban/test/test_layer.py
File MIME type: text/x-python
File size: 19246 byte(s)
Fix bug in projection handling of layers

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