/[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 839 by bh, Tue May 6 15:54:18 2003 UTC revision 1587 by bh, Fri Aug 15 10:31:07 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    
# Line 23  import shapelib Line 24  import shapelib
24  import dbflib  import dbflib
25    
26  from Thuban.Model.session import Session  from Thuban.Model.session import Session
27  from Thuban.Model.layer import Layer, SHAPETYPE_POLYGON, SHAPETYPE_ARC, \  from Thuban.Model.layer import BaseLayer, Layer, RasterLayer
28       SHAPETYPE_POINT  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.table import FIELDTYPE_DOUBLE  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    
     def assertFloatTuplesEqual(self, test, value):  
         """Assert equality of two lists of tuples of float"""  
         for i in range(len(test)):  
             self.assertFloatSeqEqual(test[i], value[i])  
   
44      def setUp(self):      def setUp(self):
45          """Create a session"""          """Create a session self.session and initialize self.layer to None"""
46          self.session = Session("Test session for %s" % self.__class__)          self.session = Session("Test session for %s" % self.__class__)
47            self.layer = None
48    
49      def tearDown(self):      def tearDown(self):
50            """Call the layer's Destroy method and set session and layer to None"""
51          self.session = None          self.session = None
52            if self.layer is not None:
53                self.layer.Destroy()
54                self.layer = None
55    
56        def build_path(self, filename):
57            return os.path.join("..", "Data", "iceland", filename)
58    
59      def open_shapefile(self, filename):      def open_shapefile(self, filename):
60          """Open and return a shapestore for filename in the iceland data set"""          """Open and return a shapestore for filename in the iceland data set"""
61          return self.session.OpenShapefile(os.path.join("..", "Data", "iceland",          return self.session.OpenShapefile(self.build_path(filename))
62                                                         filename))  
63        def test_base_layer(self):
64            layer = self.layer = BaseLayer("Test BaseLayer")
65            self.assertEquals(layer.Title(), "Test BaseLayer")
66            self.failUnless(layer.Visible())
67    
68            # toggle visibility
69            layer.SetVisible(False)
70            self.failIf(layer.Visible())
71    
72            layer.SetVisible(True)
73            self.failUnless(layer.Visible())
74    
75            self.failIf(layer.HasClassification())
76            self.failIf(layer.HasShapes())
77    
78            self.assertEquals(layer.GetProjection(), None)
79    
80            # set/get projection
81            proj = Projection(["proj=utm", "zone=26"])
82    
83            layer.SetProjection(proj)
84            self.failUnless(layer.GetProjection() is proj)
85    
86            # __init__ with other arguments
87            layer = BaseLayer("Test BaseLayer", False, proj)
88            self.failIf(layer.Visible())
89            self.failUnless(layer.GetProjection() is proj)
90    
91      def test_arc_layer(self):      def test_arc_layer(self):
92          """Test Layer with arc shapes"""          """Test Layer with arc shapes"""
93          layer = Layer("Test Layer", self.open_shapefile("roads-line.shp"))          layer = self.layer = Layer("Test Layer",
94          self.assertEquals(layer.Title(), "Test Layer")                                     self.open_shapefile("roads-line.shp"))
95            self.failUnless(layer.HasClassification())
96            self.failUnless(layer.HasShapes())
97          self.assertEquals(layer.ShapeType(), SHAPETYPE_ARC)          self.assertEquals(layer.ShapeType(), SHAPETYPE_ARC)
98          self.assertEquals(layer.NumShapes(), 839)          self.assertEquals(layer.NumShapes(), 839)
99          shape = layer.Shape(32)          shape = layer.Shape(32)
100          self.assertFloatTuplesEqual(shape.Points(),          self.assertPointListEquals(shape.Points(),
101                                      [(-15.082174301147461, 66.27738189697265),                                     [[(-15.082174301147461, 66.27738189697265),
102                                       (-15.026350021362305, 66.27339172363281)])                                       (-15.026350021362305, 66.27339172363281)]])
103          self.assertFloatSeqEqual(layer.BoundingBox(),          self.assertFloatSeqEqual(layer.BoundingBox(),
104                                   [-24.450359344482422, 63.426830291748047,                                   [-24.450359344482422, 63.426830291748047,
105                                    -13.55668830871582, 66.520111083984375])                                    -13.55668830871582, 66.520111083984375])
# Line 73  class TestLayer(unittest.TestCase, suppo Line 111  class TestLayer(unittest.TestCase, suppo
111                             -15.026350021362305, 66.27738189697265])                             -15.026350021362305, 66.27738189697265])
112    
113          shape = layer.Shape(33)          shape = layer.Shape(33)
114          self.assertFloatTuplesEqual(shape.Points(),          self.assertPointListEquals(shape.Points(),
115                                      [(-22.248506546020508, 66.30645751953125),                                     [[(-22.24850654602050, 66.30645751953125),
116                                       (-22.232730865478516, 66.294075012207031),                                       (-22.23273086547851, 66.29407501220703),
117                                       (-22.23158073425293,  66.287689208984375),                                       (-22.23158073425293,  66.2876892089843),
118                                       (-22.246318817138672, 66.270065307617188)])                                       (-22.24631881713867, 66.27006530761718)]])
119    
120          self.assertFloatSeqEqual(layer.ShapesBoundingBox([32, 33]),          self.assertFloatSeqEqual(layer.ShapesBoundingBox([32, 33]),
121                                   [-22.248506546020508, 66.270065307617188,                                   [-22.248506546020508, 66.270065307617188,
# Line 86  class TestLayer(unittest.TestCase, suppo Line 124  class TestLayer(unittest.TestCase, suppo
124          self.assertEquals(layer.ShapesBoundingBox([]), None)          self.assertEquals(layer.ShapesBoundingBox([]), None)
125          self.assertEquals(layer.ShapesBoundingBox(None), None)          self.assertEquals(layer.ShapesBoundingBox(None), None)
126    
         layer.Destroy()  
   
127      def test_polygon_layer(self):      def test_polygon_layer(self):
128          """Test Layer with polygon shapes"""          """Test Layer with polygon shapes"""
129          layer = Layer("Test Layer", self.open_shapefile("political.shp"))          layer = self.layer = Layer("Test Layer",
130          self.assertEquals(layer.Title(), "Test Layer")                                     self.open_shapefile("political.shp"))
131            self.failUnless(layer.HasClassification())
132            self.failUnless(layer.HasShapes())
133          self.assertEquals(layer.ShapeType(), SHAPETYPE_POLYGON)          self.assertEquals(layer.ShapeType(), SHAPETYPE_POLYGON)
134          self.assertEquals(layer.NumShapes(), 156)          self.assertEquals(layer.NumShapes(), 156)
135          shape = layer.Shape(4)          shape = layer.Shape(4)
136          self.assertFloatTuplesEqual(shape.Points(),          self.assertPointListEquals(shape.Points(),
137                                      [(-22.406391143798828, 64.714111328125),                                     [[(-22.40639114379882, 64.714111328125),
138                                       (-22.41621208190918, 64.71600341796875),                                       (-22.41621208190918, 64.7160034179687),
139                                       (-22.406051635742188, 64.719200134277344),                                       (-22.40605163574218, 64.719200134277),
140                                       (-22.406391143798828, 64.714111328125)])                                       (-22.40639114379882, 64.714111328125)]])
141          self.assertFloatSeqEqual(layer.BoundingBox(),          self.assertFloatSeqEqual(layer.BoundingBox(),
142                                   [-24.546524047851562, 63.286754608154297,                                   [-24.546524047851562, 63.286754608154297,
143                                    -13.495815277099609, 66.563774108886719])                                    -13.495815277099609, 66.563774108886719])
144          self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.9, 64.1)),          self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.9, 64.1)),
145                            [91, 92, 144, 146, 148, 150, 152, 153])                            [91, 92, 144, 146, 148, 150, 152, 153])
         layer.Destroy()  
146    
147      def test_point_layer(self):      def test_point_layer(self):
148          """Test Layer with point shapes"""          """Test Layer with point shapes"""
149          layer = Layer("Test Layer",          layer = self.layer = Layer("Test Layer",
150                        self.open_shapefile("cultural_landmark-point.shp"))                             self.open_shapefile("cultural_landmark-point.shp"))
151          self.assertEquals(layer.Title(), "Test Layer")          self.failUnless(layer.HasClassification())
152            self.failUnless(layer.HasShapes())
153          self.assertEquals(layer.ShapeType(), SHAPETYPE_POINT)          self.assertEquals(layer.ShapeType(), SHAPETYPE_POINT)
154          self.assertEquals(layer.NumShapes(), 34)          self.assertEquals(layer.NumShapes(), 34)
155          shape = layer.Shape(0)          shape = layer.Shape(0)
156          self.assertFloatTuplesEqual(shape.Points(),          self.assertPointListEquals(shape.Points(),
157                                      [(-22.711074829101562, 66.36572265625)])                                     [[(-22.711074829101562, 66.36572265625)]])
158          self.assertFloatSeqEqual(layer.BoundingBox(),          self.assertFloatSeqEqual(layer.BoundingBox(),
159                                   [-23.806047439575195, 63.405960083007812,                                   [-23.806047439575195, 63.405960083007812,
160                                    -15.12291431427002, 66.36572265625])                                    -15.12291431427002, 66.36572265625])
161          self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.80, 64.1)),          self.assertEquals(layer.ShapesInRegion((-24.0, 64.0, -23.80, 64.1)),
162                            [0, 1, 2, 3, 4, 5, 27, 28, 29, 30, 31])                            [0, 1, 2, 3, 4, 5, 27, 28, 29, 30, 31])
163          layer.Destroy()  
164        def test_point_layer_with_projection(self):
165            """Test Layer with point shapes and a projection"""
166            # We use mock data here so that we have precise control over the
167            # values
168            table = MemoryTable([("FOO", FIELDTYPE_STRING)], [("bla",)])
169            store = mockgeo.SimpleShapeStore(SHAPETYPE_POINT, [[[(10,10)]]], table)
170            layer = self.layer = Layer("Test Layer", store)
171    
172            # Rotation by 45 degrees counter clockwise. This detects a bug
173            # in the ShapesInRegion method which transforms the bounding box
174            # by only transforming two opposite corners because they have
175            # the same x or y coordinates after application of the
176            # projection or its inverse.
177            proj = mockgeo.AffineProjection((1, 1, -1, 1, 0, 0))
178            layer.SetProjection(proj)
179    
180            self.assertEquals(layer.BoundingBox(), (10, 10, 10, 10))
181            self.assertEquals(layer.LatLongBoundingBox(), (10.0, 0.0, 10.0, 0.0))
182            self.assertEquals(layer.ShapesInRegion((0, 0, 20, 20)), [0])
183    
184      def test_empty_layer(self):      def test_empty_layer(self):
185          """Test Layer with empty shape file"""          """Test Layer with empty shape file"""
# Line 137  class TestLayer(unittest.TestCase, suppo Line 194  class TestLayer(unittest.TestCase, suppo
194          dbf.add_field("NAME", dbflib.FTString, 20, 0)          dbf.add_field("NAME", dbflib.FTString, 20, 0)
195    
196          # Now try to open it.          # Now try to open it.
197          layer = Layer("Empty Layer",          layer = self.layer = Layer("Empty Layer",
198                        self.session.OpenShapefile(shapefilename))                                     self.session.OpenShapefile(shapefilename))
199          self.assertEquals(layer.BoundingBox(), None)          self.assertEquals(layer.BoundingBox(), None)
200          self.assertEquals(layer.LatLongBoundingBox(), None)          self.assertEquals(layer.LatLongBoundingBox(), None)
201          self.assertEquals(layer.NumShapes(), 0)          self.assertEquals(layer.NumShapes(), 0)
         layer.Destroy()  
202    
203      def test_get_field_type(self):      def test_get_field_type(self):
204          """Test Layer.GetFieldType()"""          """Test Layer.GetFieldType()"""
205          layer = Layer("Test Layer", self.open_shapefile("roads-line.shp"))          layer = self.layer = Layer("Test Layer",
206                                       self.open_shapefile("roads-line.shp"))
207          self.assertEquals(layer.GetFieldType("LENGTH"), FIELDTYPE_DOUBLE)          self.assertEquals(layer.GetFieldType("LENGTH"), FIELDTYPE_DOUBLE)
208          self.assertEquals(layer.GetFieldType("non existing"), None)          self.assertEquals(layer.GetFieldType("non existing"), None)
         layer.Destroy()  
209    
210        def test_raster_layer(self):
211            if not Thuban.Model.resource.has_gdal_support():
212                raise support.SkipTest("No gdal support")
213    
214            filename = self.build_path("island.tif")
215            layer = RasterLayer("Test RasterLayer", filename)
216            self.failIf(layer.HasClassification())
217            self.failIf(layer.HasShapes())
218            self.assertEquals(layer.GetImageFilename(), filename)
219            self.assertFloatSeqEqual(layer.BoundingBox(),
220                                     [-24.5500000, 63.2833330,
221                                      -13.4916670, 66.5666670])
222            self.assertFloatSeqEqual(layer.LatLongBoundingBox(),
223                                     [-24.5500000, 63.2833330,
224                                      -13.4916670, 66.5666670])
225    
226        def test_derived_store(self):
227            """Test layer with derived store"""
228            layer = self.layer = Layer("Test Layer",
229                                       self.open_shapefile("roads-line.shp"))
230            try:
231                store = layer.ShapeStore()
232                derived = DerivedShapeStore(store, store.Table())
233                layer.SetShapeStore(derived)
234                self.assert_(layer.ShapeStore() is derived)
235    
236                self.assertEquals(layer.ShapeType(), SHAPETYPE_ARC)
237                self.assertEquals(layer.NumShapes(), 839)
238                shape = layer.Shape(32)
239                self.assertPointListEquals(shape.Points(),
240                                           [[(-15.082174301147, 66.277381896972),
241                                             (-15.026350021362, 66.273391723632)]])
242                self.assertFloatSeqEqual(layer.BoundingBox(),
243                                         [-24.450359344482422, 63.426830291748047,
244                                          -13.55668830871582, 66.520111083984375])
245                self.assertEquals(layer.ShapesInRegion((-24.0, 64.0,
246                                                        -23.75, 64.25)),
247                                  [613, 726, 838])
248    
249                self.assertFloatSeqEqual(layer.ShapesBoundingBox([32]),
250                                         [-15.082174301147461, 66.27339172363281,
251                                          -15.026350021362305, 66.27738189697265])
252    
253            finally:
254                store = derived = None
255    
256    
257    class SetShapeStoreTests(unittest.TestCase, support.SubscriberMixin):
258    
259        def setUp(self):
260            """Create a layer with a classification as self.layer"""
261            self.clear_messages()
262            self.session = Session("Test session for %s" % self.__class__)
263            self.shapefilename = os.path.join("..", "Data", "iceland",
264                                              "cultural_landmark-point.dbf")
265            self.store = self.session.OpenShapefile(self.shapefilename)
266            self.layer = Layer("test layer", self.store)
267            self.classification = Classification()
268            self.classification.AppendGroup(ClassGroupSingleton("FARM"))
269            self.layer.SetClassificationColumn("CLPTLABEL")
270            self.layer.SetClassification(self.classification)
271            self.layer.UnsetModified()
272            self.layer.Subscribe(LAYER_SHAPESTORE_REPLACED,
273                                 self.subscribe_with_params,
274                                 LAYER_SHAPESTORE_REPLACED)
275            self.layer.Subscribe(LAYER_CHANGED,
276                                 self.subscribe_with_params, LAYER_CHANGED)
277    
278        def tearDown(self):
279            self.clear_messages()
280            self.layer.Destroy()
281            self.session.Destroy()
282            self.session = self.layer = self.store = self.classification = None
283    
284        def test_sanity(self):
285            """SetShapeStoreTests sanity check
286    
287            Test the initial state of the test case instances after setUp.
288            """
289            cls = self.layer.GetClassification()
290            self.assert_(cls is self.classification)
291            field = self.layer.GetClassificationColumn()
292            self.assertEquals(field, "CLPTLABEL")
293            self.assertEquals(self.layer.GetFieldType(field), FIELDTYPE_STRING)
294            self.assertEquals(self.layer.GetClassification().GetNumGroups(), 1)
295            self.failIf(self.layer.WasModified())
296    
297  class TestLayerLegend(unittest.TestCase, support.SubscriberMixin):      def test_set_shape_store_modified_flag(self):
298            """Test whether Layer.SetShapeStore() sets the modified flag"""
299            memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
300                          [("bla",)] * self.layer.ShapeStore().Table().NumRows())
301            self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
302    
303            self.assert_(self.layer.WasModified())
304    
305        def test_set_shape_store_different_field_name(self):
306            """Test Layer.SetShapeStore() with different column name"""
307            memtable = MemoryTable([("FOO", FIELDTYPE_STRING)],
308                          [("bla",)] * self.layer.ShapeStore().Table().NumRows())
309            self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
310            # The classification should contain only the default group now.
311            self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
312            self.check_messages([(self.layer, LAYER_CHANGED),
313                                 (self.layer, LAYER_SHAPESTORE_REPLACED)])
314    
315        def test_set_shape_store_same_field(self):
316            """Test Layer.SetShapeStore() with same column name and type"""
317            memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_STRING)],
318                          [("bla",)] * self.layer.ShapeStore().Table().NumRows())
319            self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
320            # The classification should be the same as before
321            self.assert_(self.layer.GetClassification() is self.classification)
322            self.check_messages([(self.layer, LAYER_SHAPESTORE_REPLACED)])
323    
324        def test_set_shape_store_same_field_different_type(self):
325            """Test Layer.SetShapeStore() with same column name but different type
326            """
327            memtable = MemoryTable([("CLPTLABEL", FIELDTYPE_DOUBLE)],
328                          [(0.0,)] * self.layer.ShapeStore().Table().NumRows())
329            self.layer.SetShapeStore(DerivedShapeStore(self.store, memtable))
330            # The classification should contain only the default group now.
331            self.assertEquals(self.layer.GetClassification().GetNumGroups(), 0)
332            self.check_messages([(self.layer, LAYER_CHANGED),
333                                 (self.layer, LAYER_SHAPESTORE_REPLACED)])
334    
335    
336    class TestLayerModification(unittest.TestCase, support.SubscriberMixin):
337    
338      """Test cases for Layer method that modify the layer.      """Test cases for Layer method that modify the layer.
339      """      """
# Line 172  class TestLayerLegend(unittest.TestCase, Line 353  class TestLayerLegend(unittest.TestCase,
353          self.layer.Subscribe(LAYER_VISIBILITY_CHANGED,          self.layer.Subscribe(LAYER_VISIBILITY_CHANGED,
354                               self.subscribe_with_params,                               self.subscribe_with_params,
355                               LAYER_VISIBILITY_CHANGED)                               LAYER_VISIBILITY_CHANGED)
356            self.layer.Subscribe(LAYER_CHANGED, self.subscribe_with_params,
357                                 LAYER_CHANGED)
358    
359      def tearDown(self):      def tearDown(self):
360          """Clear the list of received messages and explictly destroy self.layer          """Clear the list of received messages and explictly destroy self.layer
# Line 182  class TestLayerLegend(unittest.TestCase, Line 365  class TestLayerLegend(unittest.TestCase,
365          self.session = None          self.session = None
366          self.clear_messages()          self.clear_messages()
367    
368      def test_initial_settings(self):      def test_sanity(self):
369          """Test Layer's initial legend attributes"""          """TestLayerModification Sanity Checks"""
370          # test default settings          # test default settings
371          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)  
372          self.assertEquals(self.layer.Visible(), 1)          self.assertEquals(self.layer.Visible(), 1)
373          # no messages should have been produced          # no messages should have been produced
374          self.check_messages([])          self.check_messages([])
# Line 203  class TestLayerLegend(unittest.TestCase, Line 383  class TestLayerLegend(unittest.TestCase,
383          # the layer.          # the layer.
384          self.failIf(self.layer.WasModified())          self.failIf(self.layer.WasModified())
385    
386            def test_set_classification(self):
387            """Test Layer.SetClassification"""
388            classification = Classification()
389            classification.AppendGroup(ClassGroupRange((0.0, 0.1)))
390    
391            self.layer.SetClassification(classification)
392            self.layer.SetClassificationColumn("AREA")
393    
394            self.check_messages([(self.layer, LAYER_CHANGED),
395                                 (self.layer, LAYER_CHANGED)])
396            self.failUnless(self.layer.WasModified())
397    
398            self.clear_messages()
399            self.layer.UnsetModified()
400    
401            # change only the classification column. This should issue a
402            # LAYER_CHANGED message as well.
403            self.layer.SetClassificationColumn("PERIMETER")
404    
405            self.check_messages([(self.layer, LAYER_CHANGED)])
406            self.failUnless(self.layer.WasModified())
407    
408    
409  #  #
410  # the tree info now contains Color objects which are difficult to test  # the tree info now contains Color objects which are difficult to test
411  #  #

Legend:
Removed from v.839  
changed lines
  Added in v.1587

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26