/[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 2537 - (hide annotations)
Fri Jan 21 14:01:25 2005 UTC (20 years, 1 month ago) by jonathan
Original Path: trunk/thuban/test/test_baserenderer.py
File MIME type: text/x-python
File size: 18237 byte(s)
Improved rendering raster layers by changing the return format of
the ProjectRasterFile function.

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 jonathan 2537 def draw_raster_data(self, x, y, data, format='BMP', mask = None):
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 jonathan 2537 #hexed = binascii.b2a_base64(renderer.raster_data[2])
291 bh 1552 #while hexed:
292 jonathan 2537 #print repr(hexed[:65])
293     #hexed = hexed[65:]
294 bh 1552
295     # The reference data as a base64 coded BMP image
296     raw_data = binascii.a2b_base64(
297 jonathan 2537 'UmbmUmbmUmbmUmbmUmbmAtYCJooCAtICAq4CJooCArICAuICArICAuYCAs4COn4CO'
298     'n4CAq4CAuICFpICUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmAuYCAqICAqoCAqoCFp'
299     'ICJooCIo4CCpoCQnoGOn4CDpYCOn4CUmbmUmbmNo6aEpYCLoYCAqICGpICFpICUmb'
300     'mAt4CUmbmNo6aAtICArYCAqoCKoYCMoICTnYKOn4CFpICUmbmUmbmUmbmUmbmAp4C'
301     'NoICArYCAr4CCpoCAqYCCpoCEpYCHo4CFpICHo4CGpICFpICKoYCTnYKMoICAp4CU'
302     'mbmUmbmUmbmUmbmUmbmUmbmAtYCAroCArYCCpoCAtYCAroCAtICAsYCUmbmAt4CAq'
303     'YCAroCMoICAs4CAs4CAtYCAt4CAqYCUmbmUmbmUmbmUmbmAtoCAtYCAq4CAtoCBp4'
304     'CAroCAqoCAq4CAr4CDpYCGpICAt4CAsICDpYCArICCpoCHo4CAs4CAuICUmbmUmbm'
305     'UmbmUmbmUmbmUmbmAuICAqICFpYCAq4CDpoCAqYCFpICAqYCUmbmNo6aAsYCCpoCD'
306     'pYCAqICAtoCUmbmAt4CAqoCCpoCAroCHo4CAsYCAq4CAsICAs4CAp4CUmbmAtYCAq'
307     'YCIooCHo4CAsICAr4CAqICEpYCAs4CAqICArICDpYCEpYCEpYCAr4CUmbmEpYCAs4'
308     'CAtICAs4CAqYCUmbmAtoCAp4CCpoCDpYCAq4CArICAqoCAqYCAqYCAtYCAtoCDpYC'
309     'At4CUmbmUmbmUmbmUmbmAt4CAsoCAsoCAp4CAp4CCpoCAsoCAt4CNo6aUmbmUmbmU'
310     'mbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmAt4CAtYCCpoCAqICAroCAr4CUmbmUm'
311     'bmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmb'
312     'mUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbm'
313     'UmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmU'
314     'mbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUm'
315     'bmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmb'
316     'mUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbm'
317     'UmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmU'
318     'mbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUm'
319     'bmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmb'
320     'mUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbm'
321     'UmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbmUmbm\n')
322     self.assertEquals(renderer.raster_data, [20,20,raw_data])
323     self.assertEquals(renderer.raster_format, "RAW")
324 bh 1552
325     self.assertEquals(dc.calls,
326     [('BeginDrawing',),
327     ('SetFont', "label font"),
328     ('EndDrawing',)])
329    
330     def test_point_map_projection(self):
331     """Test BaseRenderer with point layer and map projection"""
332     table = MemoryTable([("type", FIELDTYPE_STRING),
333     ("value", FIELDTYPE_DOUBLE),
334     ("code", FIELDTYPE_INT)],
335     [("UNKNOWN", 0.0, 0)])
336     shapes = [[[(10, 10)]]]
337     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
338    
339     map = Map("TestBaseRenderer")
340     map.SetProjection(MockProjection(-3, 3))
341     layer = Layer("point layer", store)
342     map.AddLayer(layer)
343     self.to_destroy.append(map)
344    
345     dc = MockDC()
346 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
347 bh 1552
348 bh 1867 renderer.render_map()
349 bh 1552
350     self.assertEquals(dc.calls,
351     [('BeginDrawing',),
352     ('SetBrush', ('brush', Transparent)),
353     ('SetPen', ('pen', Color(0, 0, 0), 1)),
354     ('DrawEllipse', -55, -55, 10, 10),
355     ('SetFont', "label font"),
356     ('EndDrawing',)])
357    
358     def test_point_layer_projection(self):
359     """Test BaseRenderer with point layer and layer projection"""
360     table = MemoryTable([("type", FIELDTYPE_STRING),
361     ("value", FIELDTYPE_DOUBLE),
362     ("code", FIELDTYPE_INT)],
363     [("UNKNOWN", 0.0, 0)])
364     shapes = [[[(9, 9)]]]
365     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
366    
367     map = Map("TestBaseRenderer")
368     layer = Layer("point layer", store)
369     layer.SetProjection(MockProjection(3, -3))
370     map.AddLayer(layer)
371     self.to_destroy.append(map)
372    
373     dc = MockDC()
374 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
375 bh 1552
376 bh 1867 renderer.render_map()
377 bh 1552
378     self.assertEquals(dc.calls,
379     [('BeginDrawing',),
380     ('SetBrush', ('brush', Transparent)),
381     ('SetPen', ('pen', Color(0, 0, 0), 1)),
382     ('DrawEllipse', 11, 11, 10, 10),
383     ('SetFont', "label font"),
384     ('EndDrawing',)])
385    
386     def test_point_layer_and_map_projection(self):
387     """Test BaseRenderer with point layer and layer and map projection"""
388     table = MemoryTable([("type", FIELDTYPE_STRING),
389     ("value", FIELDTYPE_DOUBLE),
390     ("code", FIELDTYPE_INT)],
391     [("UNKNOWN", 0.0, 0)])
392     shapes = [[[(9, 9)]]]
393     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
394    
395     map = Map("TestBaseRenderer")
396     map.SetProjection(MockProjection(-3, 3))
397     layer = Layer("point layer", store)
398     layer.SetProjection(MockProjection(3, -3))
399     map.AddLayer(layer)
400     self.to_destroy.append(map)
401    
402     dc = MockDC()
403 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
404 bh 1552
405 bh 1867 renderer.render_map()
406 bh 1552
407     self.assertEquals(dc.calls,
408     [('BeginDrawing',),
409     ('SetBrush', ('brush', Transparent)),
410     ('SetPen', ('pen', Color(0, 0, 0), 1)),
411     ('DrawEllipse', -13, 23, 10, 10),
412     ('SetFont', "label font"),
413     ('EndDrawing',)])
414    
415    
416 bh 1591 def test_point_with_classification(self):
417     """Test BaseRenderer with point layer and classification"""
418     table = MemoryTable([("type", FIELDTYPE_STRING),
419     ("value", FIELDTYPE_DOUBLE),
420     ("code", FIELDTYPE_INT)],
421     [("UNKNOWN", 0.0, 0),
422     ("UNKNOWN", 0.0, 1)])
423     shapes = [[[(0, 0)]], [[(10, 10)]]]
424     store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
425 bh 1552
426 bh 1591 map = Map("TestBaseRenderer")
427     layer = Layer("point layer", store)
428     group = ClassGroupSingleton(1)
429     group.GetProperties().SetFill(Color(0, 0, 1))
430     layer.GetClassification().AppendGroup(group)
431     layer.SetClassificationColumn("code")
432    
433     map.AddLayer(layer)
434     self.to_destroy.append(map)
435    
436     dc = MockDC()
437 bh 1867 renderer = SimpleRenderer(dc, map, 2, (10, 10))
438 bh 1591
439 bh 1867 renderer.render_map()
440 bh 1591
441     self.assertEquals(dc.calls,
442     [('BeginDrawing',),
443     ('SetBrush', ('brush', Transparent)),
444     ('SetPen', ('pen', Color(0, 0, 0), 1)),
445     ('DrawEllipse', 5, 5, 10, 10),
446     ('SetBrush', ('brush', Color(0, 0, 1))),
447     ('SetPen', ('pen', Color(0, 0, 0), 1)),
448     ('DrawEllipse', 25, -15, 10, 10),
449     ('SetFont', "label font"),
450     ('EndDrawing',)])
451    
452    
453 bh 1928 def test_renderer_extension(self):
454     """Test renderer with a renderer extension"""
455     class MyLayer(BaseLayer):
456     pass
457    
458     calls = []
459     def my_renderer(renderer, layer):
460     calls.append((renderer, layer))
461     return ()
462    
463     add_renderer_extension(MyLayer, my_renderer)
464    
465     try:
466     map = Map("test_renderer_extension")
467     layer = MyLayer("my layer")
468     map.AddLayer(layer)
469     self.to_destroy.append(map)
470    
471     dc = MockDC()
472     renderer = SimpleRenderer(dc, map, 2, (10, 10))
473     renderer.render_map()
474     finally:
475     init_renderer_extensions()
476    
477     self.assertEquals(calls, [(renderer, layer)])
478    
479    
480 bh 1552 if __name__ == "__main__":
481     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