/[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 2551 - (show annotations)
Thu Jan 27 14:19:41 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: 18232 byte(s)
Add a new dialog box for raster layers. The dialog box allows
the user to toggle a mask that is generated by ProjectRasterFile
and is used to only draw the real parts of the projected image.

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])
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 '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, None)))
323 self.assertEquals(renderer.raster_format, "RAW")
324
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
347
348 renderer.render_map()
349
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
375
376 renderer.render_map()
377
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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
404
405 renderer.render_map()
406
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 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
426 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 renderer = SimpleRenderer(dc, map, 2, (10, 10))
438
439 renderer.render_map()
440
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 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 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