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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 599 by bh, Thu Apr 3 11:37:13 2003 UTC revision 1687 by bh, Fri Aug 29 10:02:16 2003 UTC
# Line 16  __version__ = "$Revision$" Line 16  __version__ = "$Revision$"
16  import os  import os
17  import unittest  import unittest
18    
19    import mockgeo
20  import support  import support
21  support.initthuban()  support.initthuban()
22    
23  import shapelib  import shapelib
24  import dbflib  import dbflib
25    
26  from Thuban.Model.layer import Layer, SHAPETYPE_POLYGON, SHAPETYPE_ARC, \  from Thuban.Model.session import Session
27       SHAPETYPE_POINT  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, \  from Thuban.Model.messages import LAYER_LEGEND_CHANGED, \
30       LAYER_VISIBILITY_CHANGED       LAYER_VISIBILITY_CHANGED, LAYER_SHAPESTORE_REPLACED, LAYER_CHANGED
31  from Thuban.Model.color import Color  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,  class TestLayer(unittest.TestCase, support.FileTestMixin,
40                  support.FloatComparisonMixin):                  support.FloatComparisonMixin):
41    
42      """Test cases for different layer (shape) types"""      """Test cases for different layer (shape) types"""
43    
44      def assertFloatTuplesEqual(self, test, value):      def setUp(self):
45          """Assert equality of two lists of tuples of float"""          """Create a session self.session and initialize self.layer to None"""
46          for i in range(len(test)):          self.session = Session("Test session for %s" % self.__class__)
47              self.assertFloatSeqEqual(test[i], value[i])          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):      def test_arc_layer(self):
93          """Test Layer with arc shapes"""          """Test Layer with arc shapes"""
94          layer = Layer("Test Layer",          layer = self.layer = Layer("Test Layer",
95                        os.path.join("..", "Data", "iceland", "roads-line.shp"))                                     self.open_shapefile("roads-line.shp"))
96          self.assertEquals(layer.Title(), "Test Layer")          self.failUnless(layer.HasClassification())
97            self.failUnless(layer.HasShapes())
98          self.assertEquals(layer.ShapeType(), SHAPETYPE_ARC)          self.assertEquals(layer.ShapeType(), SHAPETYPE_ARC)
99          self.assertEquals(layer.NumShapes(), 839)          self.assertEquals(layer.NumShapes(), 839)
100          shape = layer.Shape(32)          shape = layer.Shape(32)
101          self.assertFloatTuplesEqual(shape.Points(),          self.assertPointListEquals(shape.Points(),
102                                      [(-15.082174301147461, 66.27738189697265),                                     [[(-15.082174301147461, 66.27738189697265),
103                                       (-15.026350021362305, 66.27339172363281)])                                       (-15.026350021362305, 66.27339172363281)]])
104          self.assertFloatSeqEqual(layer.BoundingBox(),          self.assertFloatSeqEqual(layer.BoundingBox(),
105                                   [-24.450359344482422, 63.426830291748047,                                   [-24.450359344482422, 63.426830291748047,
106                                    -13.55668830871582, 66.520111083984375])                                    -13.55668830871582, 66.520111083984375])
107          self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.75, 64.25)),          shapes = layer.ShapesInRegion((-24.0, 64.0, -23.75, 64.25))
108            self.assertEquals([s.ShapeID() for s in shapes],
109                            [613, 726, 838])                            [613, 726, 838])
110          layer.Destroy()  
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):      def test_polygon_layer(self):
130          """Test Layer with polygon shapes"""          """Test Layer with polygon shapes"""
131          layer = Layer("Test Layer",          layer = self.layer = Layer("Test Layer",
132                        os.path.join("..", "Data", "iceland", "political.shp"))                                     self.open_shapefile("political.shp"))
133          self.assertEquals(layer.Title(), "Test Layer")          self.failUnless(layer.HasClassification())
134            self.failUnless(layer.HasShapes())
135          self.assertEquals(layer.ShapeType(), SHAPETYPE_POLYGON)          self.assertEquals(layer.ShapeType(), SHAPETYPE_POLYGON)
136          self.assertEquals(layer.NumShapes(), 156)          self.assertEquals(layer.NumShapes(), 156)
137          shape = layer.Shape(4)          shape = layer.Shape(4)
138          self.assertFloatTuplesEqual(shape.Points(),          self.assertPointListEquals(shape.Points(),
139                                      [(-22.406391143798828, 64.714111328125),                                     [[(-22.40639114379882, 64.714111328125),
140                                       (-22.41621208190918, 64.71600341796875),                                       (-22.41621208190918, 64.7160034179687),
141                                       (-22.406051635742188, 64.719200134277344),                                       (-22.40605163574218, 64.719200134277),
142                                       (-22.406391143798828, 64.714111328125)])                                       (-22.40639114379882, 64.714111328125)]])
143          self.assertFloatSeqEqual(layer.BoundingBox(),          self.assertFloatSeqEqual(layer.BoundingBox(),
144                                   [-24.546524047851562, 63.286754608154297,                                   [-24.546524047851562, 63.286754608154297,
145                                    -13.495815277099609, 66.563774108886719])                                    -13.495815277099609, 66.563774108886719])
146          self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.9, 64.1)),          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])                            [91, 92, 144, 146, 148, 150, 152, 153])
         layer.Destroy()  
149    
150      def test_point_layer(self):      def test_point_layer(self):
151          """Test Layer with point shapes"""          """Test Layer with point shapes"""
152          layer = Layer("Test Layer",          layer = self.layer = Layer("Test Layer",
153                        os.path.join("..", "Data", "iceland",                             self.open_shapefile("cultural_landmark-point.shp"))
154                                     "cultural_landmark-point.shp"))          self.failUnless(layer.HasClassification())
155          self.assertEquals(layer.Title(), "Test Layer")          self.failUnless(layer.HasShapes())
156          self.assertEquals(layer.ShapeType(), SHAPETYPE_POINT)          self.assertEquals(layer.ShapeType(), SHAPETYPE_POINT)
157          self.assertEquals(layer.NumShapes(), 34)          self.assertEquals(layer.NumShapes(), 34)
158          shape = layer.Shape(0)          shape = layer.Shape(0)
159          self.assertFloatTuplesEqual(shape.Points(),          self.assertPointListEquals(shape.Points(),
160                                      [(-22.711074829101562, 66.36572265625)])                                     [[(-22.711074829101562, 66.36572265625)]])
161          self.assertFloatSeqEqual(layer.BoundingBox(),          self.assertFloatSeqEqual(layer.BoundingBox(),
162                                   [-23.806047439575195, 63.405960083007812,                                   [-23.806047439575195, 63.405960083007812,
163                                    -15.12291431427002, 66.36572265625])                                    -15.12291431427002, 66.36572265625])
164          self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.80, 64.1)),          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])                            [0, 1, 2, 3, 4, 5, 27, 28, 29, 30, 31])
167          layer.Destroy()  
168        def test_point_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_POINT, [[[(10,10)]]], table)
174            layer = self.layer = Layer("Test Layer", store)
175    
176            # Rotation by 45 degrees counter clockwise. This detects a bug
177            # in the ShapesInRegion method which transforms the bounding box
178            # by only transforming two opposite corners because they have
179            # the same x or y coordinates after application of the
180            # projection or its inverse.
181            proj = mockgeo.AffineProjection((1, 1, -1, 1, 0, 0))
182            layer.SetProjection(proj)
183    
184            self.assertEquals(layer.BoundingBox(), (10, 10, 10, 10))
185            self.assertEquals(layer.LatLongBoundingBox(), (10.0, 0.0, 10.0, 0.0))
186            shapes = layer.ShapesInRegion((0, 0, 20, 20))
187            self.assertEquals([s.ShapeID() for s in shapes], [0])
188    
189      def test_empty_layer(self):      def test_empty_layer(self):
190          """Test Layer with empty shape file"""          """Test Layer with empty shape file"""
# Line 107  class TestLayer(unittest.TestCase, suppo Line 199  class TestLayer(unittest.TestCase, suppo
199          dbf.add_field("NAME", dbflib.FTString, 20, 0)          dbf.add_field("NAME", dbflib.FTString, 20, 0)
200    
201          # Now try to open it.          # Now try to open it.
202          layer = Layer("Empty Layer", shapefilename)          layer = self.layer = Layer("Empty Layer",
203                                       self.session.OpenShapefile(shapefilename))
204          self.assertEquals(layer.BoundingBox(), None)          self.assertEquals(layer.BoundingBox(), None)
205          self.assertEquals(layer.LatLongBoundingBox(), None)          self.assertEquals(layer.LatLongBoundingBox(), None)
206          self.assertEquals(layer.NumShapes(), 0)          self.assertEquals(layer.NumShapes(), 0)
         layer.Destroy()  
207    
208        def test_get_field_type(self):
209            """Test Layer.GetFieldType()"""
210            layer = self.layer = Layer("Test Layer",
211                                       self.open_shapefile("roads-line.shp"))
212            self.assertEquals(layer.GetFieldType("LENGTH"), FIELDTYPE_DOUBLE)
213            self.assertEquals(layer.GetFieldType("non existing"), None)
214    
215        def test_raster_layer(self):
216            if not Thuban.Model.resource.has_gdal_support():
217                raise support.SkipTest("No gdal support")
218    
219            filename = self.build_path("island.tif")
220            layer = RasterLayer("Test RasterLayer", filename)
221            self.failIf(layer.HasClassification())
222            self.failIf(layer.HasShapes())
223            self.assertEquals(layer.GetImageFilename(), os.path.abspath(filename))
224            self.assertFloatSeqEqual(layer.BoundingBox(),
225                                     [-24.5500000, 63.2833330,
226                                      -13.4916670, 66.5666670])
227            self.assertFloatSeqEqual(layer.LatLongBoundingBox(),
228                                     [-24.5500000, 63.2833330,
229                                      -13.4916670, 66.5666670])
230    
231        def test_derived_store(self):
232            """Test layer with derived store"""
233            layer = self.layer = Layer("Test Layer",
234                                       self.open_shapefile("roads-line.shp"))
235            try:
236                store = layer.ShapeStore()
237                derived = DerivedShapeStore(store, store.Table())
238                layer.SetShapeStore(derived)
239                self.assert_(layer.ShapeStore() is derived)
240    
241                self.assertEquals(layer.ShapeType(), SHAPETYPE_ARC)
242                self.assertEquals(layer.NumShapes(), 839)
243                shape = layer.Shape(32)
244                self.assertPointListEquals(shape.Points(),
245                                           [[(-15.082174301147, 66.277381896972),
246                                             (-15.026350021362, 66.273391723632)]])
247                self.assertFloatSeqEqual(layer.BoundingBox(),
248                                         [-24.450359344482422, 63.426830291748047,
249                                          -13.55668830871582, 66.520111083984375])
250                shapes = layer.ShapesInRegion((-24.0, 64.0, -23.75, 64.25))
251                self.assertEquals([s.ShapeID() for s in shapes],
252                                  [613, 726, 838])
253    
254                self.assertFloatSeqEqual(layer.ShapesBoundingBox([32]),
255                                         [-15.082174301147461, 66.27339172363281,
256                                          -15.026350021362305, 66.27738189697265])
257    
258            finally:
259                store = derived = None
260    
261  class TestLayerLegend(unittest.TestCase, support.SubscriberMixin):  
262    class SetShapeStoreTests(unittest.TestCase, support.SubscriberMixin):
263    
264        def setUp(self):
265            """Create a layer with a classification as self.layer"""
266            self.clear_messages()
267            self.session = Session("Test session for %s" % self.__class__)
268            self.shapefilename = os.path.join("..", "Data", "iceland",
269                                              "cultural_landmark-point.dbf")
270            self.store = self.session.OpenShapefile(self.shapefilename)
271            self.layer = Layer("test layer", self.store)
272            self.classification = Classification()
273            self.classification.AppendGroup(ClassGroupSingleton("FARM"))
274            self.layer.SetClassificationColumn("CLPTLABEL")
275            self.layer.SetClassification(self.classification)
276            self.layer.UnsetModified()
277            self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,
278                                 self.subscribe_with_params,
279                                 LAYER_SHAPESTORE_REPLACED)
280            self.layer.Subscribe(LAYER_CHANGED,
281                                 self.subscribe_with_params, LAYER_CHANGED)
282    
283        def tearDown(self):
284            self.clear_messages()
285            self.layer.Destroy()
286            self.session.Destroy()
287            self.session = self.layer = self.store = self.classification = None
288    
289        def test_sanity(self):
290            """SetShapeStoreTests sanity check
291    
292            Test the initial state of the test case instances after setUp.
293            """
294            cls = self.layer.GetClassification()
295            self.assert_(cls is self.classification)
296            field = self.layer.GetClassificationColumn()
297            self.assertEquals(field, "CLPTLABEL")
298            self.assertEquals(self.layer.GetFieldType(field), FIELDTYPE_STRING)
299            self.assertEquals(self.layer.GetClassification().GetNumGroups(), 1)
300            self.failIf(self.layer.WasModified())
301    
302        def test_set_shape_store_modified_flag(self):
303            """Test whether Layer.SetShapeStore() sets the modified flag"""
304            memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
305                          [("bla",)] * self.layer.ShapeStore().Table().NumRows())
306            self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
307    
308            self.assert_(self.layer.WasModified())
309    
310        def test_set_shape_store_different_field_name(self):
311            """Test Layer.SetShapeStore() with different column name"""
312            memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
313                          [("bla",)] * self.layer.ShapeStore().Table().NumRows())
314            self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
315            # The classification should contain only the default group now.
316            self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
317            self.check_messages([(self.layer, LAYER_CHANGED),
318                                 (self.layer, LAYER_SHAPESTORE_REPLACED)])
319    
320        def test_set_shape_store_same_field(self):
321            """Test Layer.SetShapeStore() with same column name and type"""
322            memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_STRING)],
323                          [("bla",)] * self.layer.ShapeStore().Table().NumRows())
324            self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
325            # The classification should be the same as before
326            self.assert_(self.layer.GetClassification() is self.classification)
327            self.check_messages([(self.layer, LAYER_SHAPESTORE_REPLACED)])
328    
329        def test_set_shape_store_same_field_different_type(self):
330            """Test Layer.SetShapeStore() with same column name but different type
331            """
332            memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_DOUBLE)],
333                          [(0.0,)] * self.layer.ShapeStore().Table().NumRows())
334            self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
335            # The classification should contain only the default group now.
336            self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
337            self.check_messages([(self.layer, LAYER_CHANGED),
338                                 (self.layer, LAYER_SHAPESTORE_REPLACED)])
339    
340    
341    class TestLayerModification(unittest.TestCase, support.SubscriberMixin):
342    
343      """Test cases for Layer method that modify the layer.      """Test cases for Layer method that modify the layer.
344      """      """
345    
346      def setUp(self):      def setUp(self):
347          """Clear the list of received messages and create a layer          """Clear the list of received messages and create a layer and a session
348    
349          The layer is bound to self.layer.          The layer is bound to self.layer and the session to self.session.
350          """          """
351          self.clear_messages()          self.clear_messages()
352            self.session = Session("Test session for %s" % self.__class__)
353            filename = os.path.join("..", "Data", "iceland", "political.shp")
354          self.layer = Layer("Test Layer",          self.layer = Layer("Test Layer",
355                             os.path.join("..", "Data", "iceland",                             self.session.OpenShapefile(filename))
                                         "political.shp"))  
356          self.layer.Subscribe(LAYER_LEGEND_CHANGED, self.subscribe_with_params,          self.layer.Subscribe(LAYER_LEGEND_CHANGED, self.subscribe_with_params,
357                               LAYER_LEGEND_CHANGED)                               LAYER_LEGEND_CHANGED)
358          self.layer.Subscribe(LAYER_VISIBILITY_CHANGED,          self.layer.Subscribe(LAYER_VISIBILITY_CHANGED,
359                               self.subscribe_with_params,                               self.subscribe_with_params,
360                               LAYER_VISIBILITY_CHANGED)                               LAYER_VISIBILITY_CHANGED)
361            self.layer.Subscribe(LAYER_CHANGED, self.subscribe_with_params,
362                                 LAYER_CHANGED)
363    
364      def tearDown(self):      def tearDown(self):
365          """Clear the list of received messages and explictly destroy self.layer          """Clear the list of received messages and explictly destroy self.layer
366          """          """
367          self.layer.Destroy()          self.layer.Destroy()
368            self.layer = None
369            self.session.Destroy()
370            self.session = None
371          self.clear_messages()          self.clear_messages()
372    
373      def test_initial_settings(self):      def test_sanity(self):
374          """Test Layer's initial legend attributes"""          """TestLayerModification Sanity Checks"""
375          # test default settings          # test default settings
376          self.failIf(self.layer.WasModified())          self.failIf(self.layer.WasModified())
         #self.assertEquals(self.layer.fill, None)  
         #self.assertEquals(self.layer.stroke.hex(), "#000000")  
         #self.assertEquals(self.layer.stroke_width, 1)  
377          self.assertEquals(self.layer.Visible(), 1)          self.assertEquals(self.layer.Visible(), 1)
378          # no messages should have been produced          # no messages should have been produced
379          self.check_messages([])          self.check_messages([])
# Line 161  class TestLayerLegend(unittest.TestCase, Line 388  class TestLayerLegend(unittest.TestCase,
388          # the layer.          # the layer.
389          self.failIf(self.layer.WasModified())          self.failIf(self.layer.WasModified())
390    
391            def test_set_classification(self):
392            """Test Layer.SetClassification"""
393            classification = Classification()
394            classification.AppendGroup(ClassGroupRange((0.0, 0.1)))
395    
396            self.layer.SetClassification(classification)
397            self.layer.SetClassificationColumn("AREA")
398    
399            self.check_messages([(self.layer, LAYER_CHANGED),
400                                 (self.layer, LAYER_CHANGED)])
401            self.failUnless(self.layer.WasModified())
402    
403            self.clear_messages()
404            self.layer.UnsetModified()
405    
406            # change only the classification column. This should issue a
407            # LAYER_CHANGED message as well.
408            self.layer.SetClassificationColumn("PERIMETER")
409    
410            self.check_messages([(self.layer, LAYER_CHANGED)])
411            self.failUnless(self.layer.WasModified())
412    
413    
414  #  #
415  # the tree info now contains Color objects which are difficult to test  # the tree info now contains Color objects which are difficult to test
416  #  #

Legend:
Removed from v.599  
changed lines
  Added in v.1687

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26