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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1928 - (show 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 # 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 from mockgeo import SimpleShapeStore
19 import support
20 support.initthuban()
21
22 from Thuban.Model.color import Transparent, Color
23 from Thuban.Model.data import SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
24 from Thuban.Model.map import Map
25 from Thuban.Model.layer import BaseLayer, Layer, RasterLayer
26 from Thuban.Model.table import MemoryTable, \
27 FIELDTYPE_DOUBLE, FIELDTYPE_INT, FIELDTYPE_STRING
28 from Thuban.Model.classification import ClassGroupSingleton
29 import Thuban.Model.resource
30
31
32 from Thuban.UI.baserenderer import BaseRenderer, \
33 add_renderer_extension, init_renderer_extensions
34
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 def draw_raster_data(self, data, format='BMP'):
93 self.raster_data = data
94 self.raster_format = format
95
96
97 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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
143
144 renderer.render_map()
145
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
173
174 renderer.render_map()
175
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
212
213 renderer.render_map()
214
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
251
252 renderer.render_map()
253
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 if not Thuban.Model.resource.has_gdal_support():
273 raise support.SkipTest("No gdal support")
274
275 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 renderer = SimpleRenderer(dc, map, 34, (800, 2250))
285
286 renderer.render_map()
287
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 self.assertEquals(renderer.raster_format, "BMP")
330
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
353
354 renderer.render_map()
355
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
381
382 renderer.render_map()
383
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
410
411 renderer.render_map()
412
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 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
432 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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
444
445 renderer.render_map()
446
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 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 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