/[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 2562 - (show annotations)
Wed Feb 16 21:14:47 2005 UTC (20 years ago) by jonathan
Original Path: trunk/thuban/test/test_baserenderer.py
File MIME type: text/x-python
File size: 20230 byte(s)
Further wxPython 2.5 changes using patches from Daniel Calvelo Aros
so that that wxproj doesn't crash. Added GUI support for selecting
alpha channel (opacity can't be selected yet).

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