/[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 1557 - (show annotations)
Thu Aug 7 17:29:46 2003 UTC (21 years, 7 months ago) by bh
Original Path: trunk/thuban/test/test_baserenderer.py
File MIME type: text/x-python
File size: 16716 byte(s)
(SimpleShape): Shape class for the
tests.
(SimpleShapeStore.Shape): Use SimpleShape instead of
Thuban.Model.data.Shape to make the tests independed of the coming
changes.

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 import support
19 support.initthuban()
20
21 from Thuban.Model.color import Transparent, Color
22 from Thuban.Model.data import SHAPETYPE_ARC, SHAPETYPE_POLYGON, SHAPETYPE_POINT
23 from Thuban.Model.map import Map
24 from Thuban.Model.layer import Layer, RasterLayer
25 from Thuban.Model.table import MemoryTable, \
26 FIELDTYPE_DOUBLE, FIELDTYPE_INT, FIELDTYPE_STRING
27 import Thuban.Model.resource
28
29 from Thuban.UI.baserenderer import BaseRenderer
30
31
32 class MockDC:
33
34 def __init__(self, size = None):
35 self.calls = []
36 self.size = size
37
38 def GetSizeTuple(self):
39 return self.size
40
41 def __getattr__(self, attr):
42 def method(*args):
43 self.calls.append((attr,) + args)
44 return method
45
46 class P:
47
48 """A simple point"""
49
50 def __init__(self, x, y):
51 self.x = x
52 self.y = y
53
54 def __eq__(self, other):
55 return self.x == other.x and self.y == other.y
56
57 def __ne__(self, other):
58 return self.x != other.x and self.y != other.y
59
60 def __repr__(self):
61 return "P(%r, %r)" % (self.x, self.y)
62
63
64 class SimpleRenderer(BaseRenderer):
65
66 TRANSPARENT_PEN = ("pen", Transparent)
67 TRANSPARENT_BRUSH = ("brush", Transparent)
68
69 def make_point(self, x, y):
70 return P(x, y)
71
72 def tools_for_property(self, prop):
73 fill = prop.GetFill()
74 brush = ("brush", fill)
75
76 stroke = prop.GetLineColor()
77 stroke_width = prop.GetLineWidth()
78 if stroke is Transparent:
79 pen = ("pen", Transparent)
80 else:
81 pen = ("pen", stroke, stroke_width)
82
83 return pen, brush
84
85 def label_font(self):
86 return "label font"
87
88 def draw_raster_data(self, data):
89 self.raster_data = data
90
91
92 class SimpleShape:
93
94 def __init__(self, points):
95 self.points = points
96
97 def Points(self):
98 return self.points
99
100 class SimpleShapeStore:
101
102 def __init__(self, shapetype, shapes, table):
103 self.shapetype = shapetype
104 self.shapes = shapes
105 self.table = table
106 assert table.NumRows() == len(shapes)
107
108 def ShapeType(self):
109 return self.shapetype
110
111 def Table(self):
112 return self.table
113
114 def NumShapes(self):
115 return len(self.shapes)
116
117 def Shape(self, index):
118 return SimpleShape(self.shapes[index])
119
120
121 class MockProjection:
122
123 """Objects that look like projections but simply apply non-uniform scalings
124 """
125
126 def __init__(self, xscale, yscale):
127 self.xscale = float(xscale)
128 self.yscale = float(yscale)
129
130 def Forward(self, x, y):
131 return (x * self.xscale, y * self.yscale)
132
133 def Inverse(self, x, y):
134 return (x / self.xscale, y / self.yscale)
135
136
137 class TestBaseRenderer(unittest.TestCase):
138
139 def setUp(self):
140 """Set self.to_destroy to an empty list
141
142 Test should put all objects whose Destroy should be called atunittest.main
143 the end into this list so that they're destroyed in tearDown
144 """
145 self.to_destroy = []
146
147 def tearDown(self):
148 for obj in self.to_destroy:
149 obj.Destroy()
150
151 def test_arc_no_projection(self):
152 """Test BaseRenderer with arc layer and no projections"""
153 table = MemoryTable([("type", FIELDTYPE_STRING),
154 ("value", FIELDTYPE_DOUBLE),
155 ("code", FIELDTYPE_INT)],
156 [("UNKNOWN", 0.0, 0)])
157 shapes = [[[(0, 0), (10, 10)]]]
158 store = SimpleShapeStore(SHAPETYPE_ARC, shapes, table)
159
160 map = Map("TestBaseRenderer")
161 self.to_destroy.append(map)
162 layer = Layer("arc layer", store)
163 map.AddLayer(layer)
164
165 dc = MockDC()
166 renderer = SimpleRenderer(dc, 2, (10, 10))
167
168 renderer.render_map(map)
169
170 self.assertEquals(dc.calls,
171 [('BeginDrawing',),
172 ('SetBrush', ('brush', Transparent)),
173 ('SetPen', ('pen', Color(0, 0, 0), 1)),
174 ('DrawLines', [P(10, 10), P(30, -10)]),
175 ('SetFont', "label font"),
176 ('EndDrawing',)])
177
178 def test_polygon_no_projection(self):
179 """Test BaseRenderer with polygon layer and no projections"""
180 table = MemoryTable([("type", FIELDTYPE_STRING),
181 ("value", FIELDTYPE_DOUBLE),
182 ("code", FIELDTYPE_INT)],
183 [("UNKNOWN", 0.0, 0)])
184 shapes = [[[(0, 0), (10, 10), (10, 0), (0, 0)]]]
185 store = SimpleShapeStore(SHAPETYPE_POLYGON, shapes, table)
186
187 map = Map("TestBaseRenderer")
188 layer = Layer("polygon layer", store)
189 prop = layer.GetClassification().GetDefaultGroup().GetProperties()
190 prop.SetFill(Color(1, 1, 1))
191
192 map.AddLayer(layer)
193 self.to_destroy.append(map)
194
195 dc = MockDC()
196 renderer = SimpleRenderer(dc, 2, (10, 10))
197
198 renderer.render_map(map)
199
200 self.assertEquals(dc.calls,
201 [('BeginDrawing',),
202 ('SetBrush', ('brush', Color(1, 1, 1))),
203 ('SetPen', ('pen', Transparent)),
204 ('DrawPolygon', [P(10, 10), P(30, -10), P(30, 10),
205 P(10, 10)]),
206 ('SetBrush', ('brush', Transparent)),
207 ('SetPen', ('pen', Color(0, 0, 0), 1)),
208 ('DrawLines', [P(10, 10), P(30, -10), P(30, 10),
209 P(10, 10)]),
210 ('SetFont', "label font"),
211 ('EndDrawing',)])
212
213 def test_complex_polygon(self):
214 """Test BaseRenderer with complex polygon and no projections"""
215 # A square inside a sqare. This has to be drawn with at least a
216 # draw polygon call and two draw lines calls.
217 shapes = [[[(0, 0), (0, 10), (10, 10), (10, 0), (0, 0)],
218 [(2, 2), (8, 2), (8, 8), (2, 8), (2, 2)]]]
219
220 table = MemoryTable([("type", FIELDTYPE_STRING),
221 ("value", FIELDTYPE_DOUBLE),
222 ("code", FIELDTYPE_INT)],
223 [("UNKNOWN", 0.0, 0)])
224 store = SimpleShapeStore(SHAPETYPE_POLYGON, shapes, table)
225
226 map = Map("TestBaseRenderer")
227 layer = Layer("polygon layer", store)
228 prop = layer.GetClassification().GetDefaultGroup().GetProperties()
229 prop.SetFill(Color(1, 1, 1))
230
231 map.AddLayer(layer)
232 self.to_destroy.append(map)
233
234 dc = MockDC()
235 renderer = SimpleRenderer(dc, 2, (10, 10))
236
237 renderer.render_map(map)
238
239 self.assertEquals(dc.calls,
240 [('BeginDrawing',),
241 ('SetBrush', ('brush', Color(1, 1, 1))),
242 ('SetPen', ('pen', Transparent)),
243 ('DrawPolygon',
244 [P(10, 10), P(10, -10), P(30, -10), P(30, 10),
245 P(10, 10),
246 P(14, 6), P(26, 6), P(26, -6), P(14, -6),
247 P(14, 6),
248 P(10, 10)]),
249 ('SetBrush', ('brush', Transparent)),
250 ('SetPen', ('pen', Color(0, 0, 0), 1)),
251 ('DrawLines', [P(10, 10), P(10, -10), P(30, -10),
252 P(30, 10), P(10, 10)]),
253 ('DrawLines', [P(14, 6), P(26, 6), P(26, -6),
254 P(14, -6), P(14, 6)]),
255 ('SetFont', "label font"),
256 ('EndDrawing',)])
257
258 def test_point_no_projection(self):
259 """Test BaseRenderer with point layer and no projections"""
260 table = MemoryTable([("type", FIELDTYPE_STRING),
261 ("value", FIELDTYPE_DOUBLE),
262 ("code", FIELDTYPE_INT)],
263 [("UNKNOWN", 0.0, 0),
264 ("UNKNOWN", 0.0, 1)])
265 shapes = [[[(0, 0)]], [[(10, 10)]]]
266 store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
267
268 map = Map("TestBaseRenderer")
269 layer = Layer("point layer", store)
270 map.AddLayer(layer)
271 self.to_destroy.append(map)
272
273 dc = MockDC()
274 renderer = SimpleRenderer(dc, 2, (10, 10))
275
276 renderer.render_map(map)
277
278 self.assertEquals(dc.calls,
279 [('BeginDrawing',),
280 ('SetBrush', ('brush', Transparent)),
281 ('SetPen', ('pen', Color(0, 0, 0), 1)),
282 ('DrawEllipse', 5, 5, 10, 10),
283 ('SetBrush', ('brush', Transparent)),
284 ('SetPen', ('pen', Color(0, 0, 0), 1)),
285 ('DrawEllipse', 25, -15, 10, 10),
286 ('SetFont', "label font"),
287 ('EndDrawing',)])
288
289 def test_raster_no_projection(self):
290 """Test BaseRenderer with raster layer and no projections
291
292 This test is very simple minded and perhaps can easily fail due
293 to round-off errors. It simply compares the complete BMP file
294 returned by gdalwarp.ProjectRasterFile to a BMP file data.
295 """
296 if not Thuban.Model.resource.has_gdal_support():
297 raise support.SkipTest("No gdal support")
298
299 map = Map("TestBaseRenderer")
300
301 layer = RasterLayer("raster layer",
302 os.path.join("..", "Data", "iceland",
303 "island.tif"))
304 map.AddLayer(layer)
305 self.to_destroy.append(map)
306
307 dc = MockDC(size = (20, 20))
308 renderer = SimpleRenderer(dc, 34, (800, 2250))
309
310 renderer.render_map(map)
311
312 # The following commented out code block can be used to generate
313 # the base64 coded reference image data
314 #hexed = binascii.b2a_base64(renderer.raster_data)
315 #while hexed:
316 # print repr(hexed[:65])
317 # hexed = hexed[65:]
318
319 # The reference data as a base64 coded BMP image
320 raw_data = binascii.a2b_base64(
321 'Qk3GBQAAAAAAADYEAAAoAAAAFAAAABQAAAABAAgAAAAAAJABAAAAAAAAAAAAAAABA'
322 'AAAAAAAApYOAALGAgAGfjoAHmZyACZ2egAujo4AArICAE66GgACngIA5mZSAJqONg'
323 'ACzgIAAoIyABZqZgAO4uYAAtICAAKqAgAScloAAtYCADKepgAS2t4AAooiAALaAgA'
324 'CtgIAHsbOAAp2TgACogIAFtbaACqOigAidnoAAuICADKaogACfjoAAr4CAAKSFgAm'
325 'fnoAAo4eABrS1gAibnoAHsbKAAp6SgACmg4AGs7SACLCxgAqioIAAoYqAAZ6RgACm'
326 'goAKrK6AALmAgAC3gIAApIaABZqagACngYAAo4iAAKmAgAivsYAJoJ6AALCAgACyg'
327 'IAAq4CAAKWEgAOclYALpqeAAK6AgACgjYAEm5eAAKKKgAGekIAHmp6ABpmcgAChi4'
328 'ALpaaACJyegAClhYAEnJeAAZ+QgAqhoIADnZSAB5mdgACiiYAJnp6ACqGegAqrrYA'
329 'GmpuAB5megACkh4ALqqyAA52VgAulpYAAoI6AAZ+PgASbmIALpKWAA7m5gAWbmYAG'
330 'mpyAC6SjgAqioYADnZOAA7q6gAianoALqauABpqagAqgnoAEnJWAAp6RgAWbmIACu'
331 '7uACqGfgAqiooAMqauAAby8gAmusIAMp6qAC6WngAyoqoABvb2AC6SkgAS3uIAJra'
332 '+AB7KzgAynqIALq62ADKirgAC+voAGsrSABLi4gAG8vYADubqAC6qtgAuprIABvb6'
333 'ACLCygAW2t4AKra+AAru8gAS4uYACuruAAry8gAG+voAAEBAAFhkZABAQEAABp6fA'
334 'EBACAAAgPwAAPu/AJE9CgBACAAALj1BAEAICAAGPAAAQAgAAAY8+gBACL8AJTxXAA'
335 'gIQAAAPEAAAAgIAAY8QABACAgAAGQAAABAAAAALpoAAEBAAAAALgAAAEAABkAGAEA'
336 'IQAD2AEAAvwAIAJAu2ABAQEAALmQ5AEBAQAAAnp8AAEAIAAD4+gAAv78An5rDAEBA'
337 'QAAuhAcAQEBAAAb8AABAvwAAAGQKAABAAABpLksAQEAIAC4ACwBAAAAAAPkGAAC/Q'
338 'AD2APoAvwC/AJ0umgBAQEAAAGRkAABAQAAGnp8AQEAIAPcA/AC/AL8A7D0GAEAIQA'
339 'D4hAAAv0AAAAD8QAAAvwgA92T6AL9AvwDsLlcAQEBAAC4AQABAAAgA+EAAAL8IAAA'
340 '8AAAACAAAAJ8uVgBAQEAAAGQ5AABAQAAAnpcAAEBAAPYAQAC/AAgAnQsGAEAAQAAA'
341 'hG0AAEBAAB38PQAIv0AA9mT6AL9AvwAJLmwAZUBAAB0AQAAIAAgAHUAAAAgIAAAAA'
342 'AAAAAAAAACzbAAAQEAA//k5AH+/QAAGb5cAQEBAAACy5AAAQAgAAIpAAABACAAAAA'
343 'AAAAAAAAkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQk'
344 'JCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJ'
345 'CQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJCQkJC'
346 'QkJCQkJCQkJCQkJCQkJCQkJCQkyEi8aQCEJCQkJCQkJCQkJCQkJCTI7OwgILzsyCg'
347 'kJCQkJCQkJCQkJCzcJFggvADwGEDc3EhYAMgkJCQkJEjcVJDohGj0LGgYAPT0hCT0'
348 'LDyI3CQoBLwAaFgkyEC9AJAE8OgsIMjoABi8kCx4JCQkJCQkeGko8KTcLCxIyNwkJ'
349 'CQkWEjwWNUAQPCEAMwgJCQkJCQkSQBcvEkAPAQkyN0AMCQkJCQhBFyEvNy89JCIkM'
350 'yItGQwJCQo9RxozIgkyCQoPFxAtDBkgIgkJCQkJCQkJMRoQECJQNi9EIAAgCQkJCQ'
351 'kSUA88UAYeBjELICA8HiI=\n')
352 self.assertEquals(renderer.raster_data, raw_data)
353
354 self.assertEquals(dc.calls,
355 [('BeginDrawing',),
356 ('SetFont', "label font"),
357 ('EndDrawing',)])
358
359 def test_point_map_projection(self):
360 """Test BaseRenderer with point layer and map projection"""
361 table = MemoryTable([("type", FIELDTYPE_STRING),
362 ("value", FIELDTYPE_DOUBLE),
363 ("code", FIELDTYPE_INT)],
364 [("UNKNOWN", 0.0, 0)])
365 shapes = [[[(10, 10)]]]
366 store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
367
368 map = Map("TestBaseRenderer")
369 map.SetProjection(MockProjection(-3, 3))
370 layer = Layer("point layer", store)
371 map.AddLayer(layer)
372 self.to_destroy.append(map)
373
374 dc = MockDC()
375 renderer = SimpleRenderer(dc, 2, (10, 10))
376
377 renderer.render_map(map)
378
379 self.assertEquals(dc.calls,
380 [('BeginDrawing',),
381 ('SetBrush', ('brush', Transparent)),
382 ('SetPen', ('pen', Color(0, 0, 0), 1)),
383 ('DrawEllipse', -55, -55, 10, 10),
384 ('SetFont', "label font"),
385 ('EndDrawing',)])
386
387 def test_point_layer_projection(self):
388 """Test BaseRenderer with point layer and layer projection"""
389 table = MemoryTable([("type", FIELDTYPE_STRING),
390 ("value", FIELDTYPE_DOUBLE),
391 ("code", FIELDTYPE_INT)],
392 [("UNKNOWN", 0.0, 0)])
393 shapes = [[[(9, 9)]]]
394 store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
395
396 map = Map("TestBaseRenderer")
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, 2, (10, 10))
404
405 renderer.render_map(map)
406
407 self.assertEquals(dc.calls,
408 [('BeginDrawing',),
409 ('SetBrush', ('brush', Transparent)),
410 ('SetPen', ('pen', Color(0, 0, 0), 1)),
411 ('DrawEllipse', 11, 11, 10, 10),
412 ('SetFont', "label font"),
413 ('EndDrawing',)])
414
415 def test_point_layer_and_map_projection(self):
416 """Test BaseRenderer with point layer and layer and map projection"""
417 table = MemoryTable([("type", FIELDTYPE_STRING),
418 ("value", FIELDTYPE_DOUBLE),
419 ("code", FIELDTYPE_INT)],
420 [("UNKNOWN", 0.0, 0)])
421 shapes = [[[(9, 9)]]]
422 store = SimpleShapeStore(SHAPETYPE_POINT, shapes, table)
423
424 map = Map("TestBaseRenderer")
425 map.SetProjection(MockProjection(-3, 3))
426 layer = Layer("point layer", store)
427 layer.SetProjection(MockProjection(3, -3))
428 map.AddLayer(layer)
429 self.to_destroy.append(map)
430
431 dc = MockDC()
432 renderer = SimpleRenderer(dc, 2, (10, 10))
433
434 renderer.render_map(map)
435
436 self.assertEquals(dc.calls,
437 [('BeginDrawing',),
438 ('SetBrush', ('brush', Transparent)),
439 ('SetPen', ('pen', Color(0, 0, 0), 1)),
440 ('DrawEllipse', -13, 23, 10, 10),
441 ('SetFont', "label font"),
442 ('EndDrawing',)])
443
444
445
446 if __name__ == "__main__":
447 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