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

Annotation of /branches/WIP-pyshapelib-bramz/test/test_baserenderer.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1928 - (hide annotations)
Mon Nov 10 16:57:43 2003 UTC (21 years, 3 months ago) by bh
Original Path: trunk/thuban/test/test_baserenderer.py
File MIME type: text/x-python
File size: 18669 byte(s)
(SimpleRenderer.draw_raster_data): Add
the format parameter and record it
(TestBaseRenderer.test_raster_no_projection): check the format
paramter of the draw_raster_data method
(TestBaseRenderer.test_renderer_extension): New. Test the renderer
extension facility

1 bh 1552 # Copyright (C) 2003 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 the software for details.
7    
8     """Test Thuban.Model.baserenderer"""
9    
10     __version__ = "$Revision$"
11     # $Source$
12     # $Id$
13    
14     import os
15     import binascii
16     import unittest
17    
18 bh 1585 from mockgeo import SimpleShapeStore
19 bh 1552 import support
20     support.initthuban()
21    
22     from Thuban.Model.color import Transparent, Color
23 bh 1557 from Thuban.Model.data import SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
24 bh 1552 from Thuban.Model.map import Map
25 bh 1928 from Thuban.Model.layer import BaseLayer, Layer, RasterLayer
26 bh 1552 from Thuban.Model.table import MemoryTable, \
27     FIELDTYPE_DOUBLE, FIELDTYPE_INT, FIELDTYPE_STRING
28 bh 1585 from Thuban.Model.classification import ClassGroupSingleton
29 bh 1555 import Thuban.Model.resource
30 bh 1552
31 bh 1585
32 bh 1928 from Thuban.UI.baserenderer import BaseRenderer, \
33     add_renderer_extension, init_renderer_extensions
34 bh 1552
35    
36     class MockDC:
37    
38     def __init__(self, size = None):
39     self.calls = []
40     self.size = size
41    
42     def GetSizeTuple(self):
43     return self.size
44    
45     def __getattr__(self, attr):
46     def method(*args):
47     self.calls.append((attr,) + args)
48     return method
49    
50     class P:
51    
52     """A simple point"""
53    
54     def __init__(self, x, y):
55     self.x = x
56     self.y = y
57    
58     def __eq__(self, other):
59     return self.x == other.x and self.y == other.y
60    
61     def __ne__(self, other):
62     return self.x != other.x and self.y != other.y
63    
64     def __repr__(self):
65     return "P(%r, %r)" % (self.x, self.y)
66    
67    
68     class SimpleRenderer(BaseRenderer):
69    
70     TRANSPARENT_PEN = ("pen", Transparent)
71     TRANSPARENT_BRUSH = ("brush", Transparent)
72    
73     def make_point(self, x, y):
74     return P(x, y)
75    
76     def tools_for_property(self, prop):
77     fill = prop.GetFill()
78     brush = ("brush", fill)
79    
80     stroke = prop.GetLineColor()
81     stroke_width = prop.GetLineWidth()
82     if stroke is Transparent:
83     pen = ("pen", Transparent)
84     else:
85     pen = ("pen", stroke, stroke_width)
86    
87     return pen, brush
88    
89     def label_font(self):
90     return "label font"
91    
92 bh 1928 def draw_raster_data(self, data, format='BMP'):
93 bh 1552 self.raster_data = data
94 bh 1928 self.raster_format = format
95 bh 1552
96 bh 1557
97 bh 1552 class MockProjection:
98    
99     """Objects that look like projections but simply apply non-uniform scalings
100     """
101    
102     def __init__(self, xscale, yscale):
103     self.xscale = float(xscale)
104     self.yscale = float(yscale)
105    
106     def Forward(self, x, y):
107     return (x * self.xscale, y * self.yscale)
108    
109     def Inverse(self, x, y):
110     return (x / self.xscale, y / self.yscale)
111    
112    
113     class TestBaseRenderer(unittest.TestCase):
114    
115     def setUp(self):
116     """Set self.to_destroy to an empty list
117    
118     Test should put all objects whose Destroy should be called atunittest.main
119     the end into this list so that they're destroyed in tearDown
120     """
121     self.to_destroy = []
122    
123     def tearDown(self):
124     for obj in self.to_destroy:
125     obj.Destroy()
126    
127     def test_arc_no_projection(self):
128     """Test BaseRenderer with arc layer and no projections"""
129     table = MemoryTable([("type", FIELDTYPE_STRING),
130     ("value", FIELDTYPE_DOUBLE),
131     ("code", FIELDTYPE_INT)],
132     [("UNKNOWN", 0.0, 0)])
133     shapes = [[[(0, 0), (10, 10)]]]
134     store = SimpleShapeStore(SHAPETYPE_ARC, shapes, table)
135    
136     map = Map("TestBaseRenderer")
137     self.to_destroy.append(map)
138     layer = Layer("arc layer", store)
139     map.AddLayer(layer)
140    
141     dc = MockDC()
142 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
143 bh 1552
144 bh 1867 renderer.render_map()
145 bh 1552
146     self.assertEquals(dc.calls,
147     [('BeginDrawing',),
148     ('SetBrush', ('brush', Transparent)),
149     ('SetPen', ('pen', Color(0, 0, 0), 1)),
150     ('DrawLines', [P(10, 10), P(30, -10)]),
151     ('SetFont', "label font"),
152     ('EndDrawing',)])
153    
154     def test_polygon_no_projection(self):
155     """Test BaseRenderer with polygon layer and no projections"""
156     table = MemoryTable([("type", FIELDTYPE_STRING),
157     ("value", FIELDTYPE_DOUBLE),
158     ("code", FIELDTYPE_INT)],
159     [("UNKNOWN", 0.0, 0)])
160     shapes = [[[(0, 0), (10, 10), (10, 0), (0, 0)]]]
161     store = SimpleShapeStore(SHAPETYPE_POLYGON, shapes, table)
162    
163     map = Map("TestBaseRenderer")
164     layer = Layer("polygon layer", store)
165     prop = layer.GetClassification().GetDefaultGroup().GetProperties()
166     prop.SetFill(Color(1, 1, 1))
167    
168     map.AddLayer(layer)
169     self.to_destroy.append(map)
170    
171     dc = MockDC()
172 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
173 bh 1552
174 bh 1867 renderer.render_map()
175 bh 1552
176     self.assertEquals(dc.calls,
177     [('BeginDrawing',),
178     ('SetBrush', ('brush', Color(1, 1, 1))),
179     ('SetPen', ('pen', Transparent)),
180     ('DrawPolygon', [P(10, 10), P(30, -10), P(30, 10),
181     P(10, 10)]),
182     ('SetBrush', ('brush', Transparent)),
183     ('SetPen', ('pen', Color(0, 0, 0), 1)),
184     ('DrawLines', [P(10, 10), P(30, -10), P(30, 10),
185     P(10, 10)]),
186     ('SetFont', "label font"),
187     ('EndDrawing',)])
188    
189     def test_complex_polygon(self):
190     """Test BaseRenderer with complex polygon and no projections"""
191     # A square inside a sqare. This has to be drawn with at least a
192     # draw polygon call and two draw lines calls.
193     shapes = [[[(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)],
194     [(2, 2), (8, 2), (8, 8), (2, 8), (2, 2)]]]
195    
196     table = MemoryTable([("type", FIELDTYPE_STRING),
197     ("value", FIELDTYPE_DOUBLE),
198     ("code", FIELDTYPE_INT)],
199     [("UNKNOWN", 0.0, 0)])
200     store = SimpleShapeStore(SHAPETYPE_POLYGON, shapes, table)
201    
202     map = Map("TestBaseRenderer")
203     layer = Layer("polygon layer", store)
204     prop = layer.GetClassification().GetDefaultGroup().GetProperties()
205     prop.SetFill(Color(1, 1, 1))
206    
207     map.AddLayer(layer)
208     self.to_destroy.append(map)
209    
210     dc = MockDC()
211 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
212 bh 1552
213 bh 1867 renderer.render_map()
214 bh 1552
215     self.assertEquals(dc.calls,
216     [('BeginDrawing',),
217     ('SetBrush', ('brush', Color(1, 1, 1))),
218     ('SetPen', ('pen', Transparent)),
219     ('DrawPolygon',
220     [P(10, 10), P(10, -10), P(30, -10), P(30, 10),
221     P(10, 10),
222     P(14, 6), P(26, 6), P(26, -6), P(14, -6),
223     P(14, 6),
224     P(10, 10)]),
225     ('SetBrush', ('brush', Transparent)),
226     ('SetPen', ('pen', Color(0, 0, 0), 1)),
227     ('DrawLines', [P(10, 10), P(10, -10), P(30, -10),
228     P(30, 10), P(10, 10)]),
229     ('DrawLines', [P(14, 6), P(26, 6), P(26, -6),
230     P(14, -6), P(14, 6)]),
231     ('SetFont', "label font"),
232     ('EndDrawing',)])
233    
234     def test_point_no_projection(self):
235     """Test BaseRenderer with point layer and no projections"""
236     table = MemoryTable([("type", FIELDTYPE_STRING),
237     ("value", FIELDTYPE_DOUBLE),
238     ("code", FIELDTYPE_INT)],
239     [("UNKNOWN", 0.0, 0),
240     ("UNKNOWN", 0.0, 1)])
241     shapes = [[[(0, 0)]], [[(10, 10)]]]
242     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
243    
244     map = Map("TestBaseRenderer")
245     layer = Layer("point layer", store)
246     map.AddLayer(layer)
247     self.to_destroy.append(map)
248    
249     dc = MockDC()
250 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
251 bh 1552
252 bh 1867 renderer.render_map()
253 bh 1552
254     self.assertEquals(dc.calls,
255     [('BeginDrawing',),
256     ('SetBrush', ('brush', Transparent)),
257     ('SetPen', ('pen', Color(0, 0, 0), 1)),
258     ('DrawEllipse', 5, 5, 10, 10),
259     ('SetBrush', ('brush', Transparent)),
260     ('SetPen', ('pen', Color(0, 0, 0), 1)),
261     ('DrawEllipse', 25, -15, 10, 10),
262     ('SetFont', "label font"),
263     ('EndDrawing',)])
264    
265     def test_raster_no_projection(self):
266     """Test BaseRenderer with raster layer and no projections
267    
268     This test is very simple minded and perhaps can easily fail due
269     to round-off errors. It simply compares the complete BMP file
270     returned by gdalwarp.ProjectRasterFile to a BMP file data.
271     """
272 bh 1555 if not Thuban.Model.resource.has_gdal_support():
273     raise support.SkipTest("No gdal support")
274    
275 bh 1552 map = Map("TestBaseRenderer")
276    
277     layer = RasterLayer("raster layer",
278     os.path.join("..", "Data", "iceland",
279     "island.tif"))
280     map.AddLayer(layer)
281     self.to_destroy.append(map)
282    
283     dc = MockDC(size = (20, 20))
284 bh 1867 renderer = SimpleRenderer(dc, map, 34, (800, 2250))
285 bh 1552
286 bh 1867 renderer.render_map()
287 bh 1552
288     # The following commented out code block can be used to generate
289     # the base64 coded reference image data
290     #hexed = binascii.b2a_base64(renderer.raster_data)
291     #while hexed:
292     # print repr(hexed[:65])
293     # hexed = hexed[65:]
294    
295     # The reference data as a base64 coded BMP image
296     raw_data = binascii.a2b_base64(
297     'Qk3GBQAAAAAAADYEAAAoAAAAFAAAABQAAAABAAgAAAAAAJABAAAAAAAAAAAAAAABA'
298     'AAAAAAAApYOAALGAgAGfjoAHmZyACZ2egAujo4AArICAE66GgACngIA5mZSAJqONg'
299     'ACzgIAAoIyABZqZgAO4uYAAtICAAKqAgAScloAAtYCADKepgAS2t4AAooiAALaAgA'
300     'CtgIAHsbOAAp2TgACogIAFtbaACqOigAidnoAAuICADKaogACfjoAAr4CAAKSFgAm'
301     'fnoAAo4eABrS1gAibnoAHsbKAAp6SgACmg4AGs7SACLCxgAqioIAAoYqAAZ6RgACm'
302     'goAKrK6AALmAgAC3gIAApIaABZqagACngYAAo4iAAKmAgAivsYAJoJ6AALCAgACyg'
303     'IAAq4CAAKWEgAOclYALpqeAAK6AgACgjYAEm5eAAKKKgAGekIAHmp6ABpmcgAChi4'
304     'ALpaaACJyegAClhYAEnJeAAZ+QgAqhoIADnZSAB5mdgACiiYAJnp6ACqGegAqrrYA'
305     'GmpuAB5megACkh4ALqqyAA52VgAulpYAAoI6AAZ+PgASbmIALpKWAA7m5gAWbmYAG'
306     'mpyAC6SjgAqioYADnZOAA7q6gAianoALqauABpqagAqgnoAEnJWAAp6RgAWbmIACu'
307     '7uACqGfgAqiooAMqauAAby8gAmusIAMp6qAC6WngAyoqoABvb2AC6SkgAS3uIAJra'
308     '+AB7KzgAynqIALq62ADKirgAC+voAGsrSABLi4gAG8vYADubqAC6qtgAuprIABvb6'
309     'ACLCygAW2t4AKra+AAru8gAS4uYACuruAAry8gAG+voAAEBAAFhkZABAQEAABp6fA'
310     'EBACAAAgPwAAPu/AJE9CgBACAAALj1BAEAICAAGPAAAQAgAAAY8+gBACL8AJTxXAA'
311     'gIQAAAPEAAAAgIAAY8QABACAgAAGQAAABAAAAALpoAAEBAAAAALgAAAEAABkAGAEA'
312     'IQAD2AEAAvwAIAJAu2ABAQEAALmQ5AEBAQAAAnp8AAEAIAAD4+gAAv78An5rDAEBA'
313     'QAAuhAcAQEBAAAb8AABAvwAAAGQKAABAAABpLksAQEAIAC4ACwBAAAAAAPkGAAC/Q'
314     'AD2APoAvwC/AJ0umgBAQEAAAGRkAABAQAAGnp8AQEAIAPcA/AC/AL8A7D0GAEAIQA'
315     'D4hAAAv0AAAAD8QAAAvwgA92T6AL9AvwDsLlcAQEBAAC4AQABAAAgA+EAAAL8IAAA'
316     '8AAAACAAAAJ8uVgBAQEAAAGQ5AABAQAAAnpcAAEBAAPYAQAC/AAgAnQsGAEAAQAAA'
317     'hG0AAEBAAB38PQAIv0AA9mT6AL9AvwAJLmwAZUBAAB0AQAAIAAgAHUAAAAgIAAAAA'
318     'AAAAAAAAACzbAAAQEAA//k5AH+/QAAGb5cAQEBAAACy5AAAQAgAAIpAAABACAAAAA'
319     'AAAAAAAAkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk'
320     'JCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ'
321     'CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC'
322     'QkJCQkJCQkJCQkJCQkJCQkJCQkyEi8aQCEJCQkJCQkJCQkJCQkJCTI7OwgILzsyCg'
323     'kJCQkJCQkJCQkJCzcJFggvADwGEDc3EhYAMgkJCQkJEjcVJDohGj0LGgYAPT0hCT0'
324     'LDyI3CQoBLwAaFgkyEC9AJAE8OgsIMjoABi8kCx4JCQkJCQkeGko8KTcLCxIyNwkJ'
325     'CQkWEjwWNUAQPCEAMwgJCQkJCQkSQBcvEkAPAQkyN0AMCQkJCQhBFyEvNy89JCIkM'
326     'yItGQwJCQo9RxozIgkyCQoPFxAtDBkgIgkJCQkJCQkJMRoQECJQNi9EIAAgCQkJCQ'
327     'kSUA88UAYeBjELICA8HiI=\n')
328     self.assertEquals(renderer.raster_data, raw_data)
329 bh 1928 self.assertEquals(renderer.raster_format, "BMP")
330 bh 1552
331     self.assertEquals(dc.calls,
332     [('BeginDrawing',),
333     ('SetFont', "label font"),
334     ('EndDrawing',)])
335    
336     def test_point_map_projection(self):
337     """Test BaseRenderer with point layer and map projection"""
338     table = MemoryTable([("type", FIELDTYPE_STRING),
339     ("value", FIELDTYPE_DOUBLE),
340     ("code", FIELDTYPE_INT)],
341     [("UNKNOWN", 0.0, 0)])
342     shapes = [[[(10, 10)]]]
343     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
344    
345     map = Map("TestBaseRenderer")
346     map.SetProjection(MockProjection(-3, 3))
347     layer = Layer("point layer", store)
348     map.AddLayer(layer)
349     self.to_destroy.append(map)
350    
351     dc = MockDC()
352 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
353 bh 1552
354 bh 1867 renderer.render_map()
355 bh 1552
356     self.assertEquals(dc.calls,
357     [('BeginDrawing',),
358     ('SetBrush', ('brush', Transparent)),
359     ('SetPen', ('pen', Color(0, 0, 0), 1)),
360     ('DrawEllipse', -55, -55, 10, 10),
361     ('SetFont', "label font"),
362     ('EndDrawing',)])
363    
364     def test_point_layer_projection(self):
365     """Test BaseRenderer with point layer and layer projection"""
366     table = MemoryTable([("type", FIELDTYPE_STRING),
367     ("value", FIELDTYPE_DOUBLE),
368     ("code", FIELDTYPE_INT)],
369     [("UNKNOWN", 0.0, 0)])
370     shapes = [[[(9, 9)]]]
371     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
372    
373     map = Map("TestBaseRenderer")
374     layer = Layer("point layer", store)
375     layer.SetProjection(MockProjection(3, -3))
376     map.AddLayer(layer)
377     self.to_destroy.append(map)
378    
379     dc = MockDC()
380 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
381 bh 1552
382 bh 1867 renderer.render_map()
383 bh 1552
384     self.assertEquals(dc.calls,
385     [('BeginDrawing',),
386     ('SetBrush', ('brush', Transparent)),
387     ('SetPen', ('pen', Color(0, 0, 0), 1)),
388     ('DrawEllipse', 11, 11, 10, 10),
389     ('SetFont', "label font"),
390     ('EndDrawing',)])
391    
392     def test_point_layer_and_map_projection(self):
393     """Test BaseRenderer with point layer and layer and map projection"""
394     table = MemoryTable([("type", FIELDTYPE_STRING),
395     ("value", FIELDTYPE_DOUBLE),
396     ("code", FIELDTYPE_INT)],
397     [("UNKNOWN", 0.0, 0)])
398     shapes = [[[(9, 9)]]]
399     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
400    
401     map = Map("TestBaseRenderer")
402     map.SetProjection(MockProjection(-3, 3))
403     layer = Layer("point layer", store)
404     layer.SetProjection(MockProjection(3, -3))
405     map.AddLayer(layer)
406     self.to_destroy.append(map)
407    
408     dc = MockDC()
409 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
410 bh 1552
411 bh 1867 renderer.render_map()
412 bh 1552
413     self.assertEquals(dc.calls,
414     [('BeginDrawing',),
415     ('SetBrush', ('brush', Transparent)),
416     ('SetPen', ('pen', Color(0, 0, 0), 1)),
417     ('DrawEllipse', -13, 23, 10, 10),
418     ('SetFont', "label font"),
419     ('EndDrawing',)])
420    
421    
422 bh 1591 def test_point_with_classification(self):
423     """Test BaseRenderer with point layer and classification"""
424     table = MemoryTable([("type", FIELDTYPE_STRING),
425     ("value", FIELDTYPE_DOUBLE),
426     ("code", FIELDTYPE_INT)],
427     [("UNKNOWN", 0.0, 0),
428     ("UNKNOWN", 0.0, 1)])
429     shapes = [[[(0, 0)]], [[(10, 10)]]]
430     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
431 bh 1552
432 bh 1591 map = Map("TestBaseRenderer")
433     layer = Layer("point layer", store)
434     group = ClassGroupSingleton(1)
435     group.GetProperties().SetFill(Color(0, 0, 1))
436     layer.GetClassification().AppendGroup(group)
437     layer.SetClassificationColumn("code")
438    
439     map.AddLayer(layer)
440     self.to_destroy.append(map)
441    
442     dc = MockDC()
443 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
444 bh 1591
445 bh 1867 renderer.render_map()
446 bh 1591
447     self.assertEquals(dc.calls,
448     [('BeginDrawing',),
449     ('SetBrush', ('brush', Transparent)),
450     ('SetPen', ('pen', Color(0, 0, 0), 1)),
451     ('DrawEllipse', 5, 5, 10, 10),
452     ('SetBrush', ('brush', Color(0, 0, 1))),
453     ('SetPen', ('pen', Color(0, 0, 0), 1)),
454     ('DrawEllipse', 25, -15, 10, 10),
455     ('SetFont', "label font"),
456     ('EndDrawing',)])
457    
458    
459 bh 1928 def test_renderer_extension(self):
460     """Test renderer with a renderer extension"""
461     class MyLayer(BaseLayer):
462     pass
463    
464     calls = []
465     def my_renderer(renderer, layer):
466     calls.append((renderer, layer))
467     return ()
468    
469     add_renderer_extension(MyLayer, my_renderer)
470    
471     try:
472     map = Map("test_renderer_extension")
473     layer = MyLayer("my layer")
474     map.AddLayer(layer)
475     self.to_destroy.append(map)
476    
477     dc = MockDC()
478     renderer = SimpleRenderer(dc, map, 2, (10, 10))
479     renderer.render_map()
480     finally:
481     init_renderer_extensions()
482    
483     self.assertEquals(calls, [(renderer, layer)])
484    
485    
486 bh 1552 if __name__ == "__main__":
487     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