/[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 2552 - (show annotations)
Fri Jan 28 15:54:00 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: 18393 byte(s)
Make layer's use_mask flag default to true. Support a bit array describing
the mask to use. Improve error handling in ProjectRasterFile (also addresses
RT #2947).

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