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

Annotation of /branches/WIP-pyshapelib-bramz/test/test_viewport.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1781 - (hide annotations)
Mon Oct 6 17:31:44 2003 UTC (21 years, 5 months ago) by bh
Original Path: trunk/thuban/test/test_viewport.py
File MIME type: text/x-python
File size: 17048 byte(s)
(ViewPortTest.setUp): Also subscribe to
the TITLE_CHANGED messages
(ViewPortTest.test_forwarding_title_changed): New test to check
whether the viewport forwards the map's TITLE_CHANGED messages
(TestViewportWithPostGIS.tearDown): Call the map's Destroy method
after the port's because the latter may require a still functional
map.

1 jonathan 1440 # Copyright (c) 2003 by Intevation GmbH
2     # Authors:
3     # Jonathan Coles <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     """
9     Test the interaction with the view
10     """
11    
12     __version__ = "$Revision$"
13     # $Source$
14     # $Id$
15    
16     import os
17     import unittest
18    
19 bh 1608 import postgissupport
20 jonathan 1440 import support
21     support.initthuban()
22    
23     from Thuban.UI.viewport import ViewPort, ZoomInTool, ZoomOutTool, \
24     PanTool, IdentifyTool, LabelTool
25    
26     from Thuban.Model.map import Map
27     from Thuban.Model.proj import Projection
28     from Thuban.Model.layer import Layer
29     from Thuban.Model.session import Session
30     from Thuban.Model.color import Color
31 bh 1608 from Thuban.Model.postgisdb import PostGISConnection
32 bh 1464 from Thuban.UI.messages import SCALE_CHANGED, MAP_REPLACED
33 bh 1781 from Thuban.Model.messages import TITLE_CHANGED
34 jonathan 1440
35 bh 1462 class Event:
36     pass
37 jonathan 1440
38 bh 1462
39 bh 1772 class MockView(ViewPort):
40    
41     def GetTextExtent(self, text):
42     """Mock implementation so that the test cases work"""
43     # arbitrary numbers, really just so the tests pass
44     return 40, 20
45    
46    
47    
48 bh 1462 class SimpleViewPortTest(unittest.TestCase):
49    
50 bh 1464 """Simple ViewPort tests"""
51    
52 bh 1462 def test_default_size(self):
53 bh 1464 """Test ViewPort default size and scale"""
54 bh 1462 port = ViewPort()
55     try:
56     self.assertEquals(port.GetPortSizeTuple(), (400, 300))
57     self.assertEquals(port.scale, 1.0)
58     self.assertEquals(port.offset, (0, 0))
59     finally:
60     port.Destroy()
61    
62 bh 1774 def test_init_with_size(self):
63     """Test ViewPort(<size>)"""
64     port = ViewPort((1001, 1001))
65     try:
66     self.assertEquals(port.GetPortSizeTuple(), (1001, 1001))
67     finally:
68     port.Destroy()
69 bh 1464
70 bh 1774
71 jonathan 1440 class ViewPortTest(unittest.TestCase, support.SubscriberMixin,
72 bh 1608 support.FloatComparisonMixin):
73 jonathan 1440
74     def build_path(self, filename):
75     return os.path.join("..", "Data", "iceland", filename)
76 bh 1462
77 jonathan 1440 def open_shapefile(self, filename):
78     """Open and return a shapestore for filename in the iceland data set"""
79     return self.session.OpenShapefile(self.build_path(filename))
80    
81     def setUp(self):
82     self.session = Session("Test session for %s" % self.__class__)
83    
84     # make view port 1001x1001 so we have an exact center
85 bh 1772 self.port = MockView((1001, 1001))
86 jonathan 1440
87     proj = Projection(["proj=latlong",
88     "to_meter=.017453292519943",
89     "ellps=clrk66"])
90    
91 bh 1464 self.map = map = Map("title", proj)
92 jonathan 1440 layer = Layer("Polygon", self.open_shapefile("political.shp"))
93 bh 1462 layer.GetClassification().GetDefaultGroup()\
94     .GetProperties().SetFill(Color(0,0,0))
95 jonathan 1440 map.AddLayer(layer)
96 bh 1462 layer = Layer("Point",
97     self.open_shapefile("cultural_landmark-point.shp"))
98     layer.GetClassification().GetDefaultGroup()\
99     .GetProperties().SetFill(Color(0,0,0))
100 jonathan 1440 map.AddLayer(layer)
101     layer = Layer("Arc", self.open_shapefile("roads-line.shp"))
102 bh 1462 layer.GetClassification().GetDefaultGroup()\
103     .GetProperties().SetFill(Color(0,0,0))
104 jonathan 1440 map.AddLayer(layer)
105     self.session.AddMap(map)
106    
107     self.layer = layer
108    
109 bh 1464 self.port.SetMap(map)
110 bh 1781 for msg in (SCALE_CHANGED, MAP_REPLACED, TITLE_CHANGED):
111     self.port.Subscribe(msg, self.subscribe_with_params, msg)
112 bh 1464 self.clear_messages()
113 jonathan 1440
114     def tearDown(self):
115     self.port.Destroy()
116     self.session.Destroy()
117 bh 1464 self.map = self.session = self.port = self.layer = None
118 jonathan 1440
119 bh 1462 def test_inital_settings(self):
120     self.failIf(self.port.HasSelectedLayer())
121     self.failIf(self.port.HasSelectedShapes())
122 jonathan 1440
123 bh 1462 def test_win_to_proj(self):
124     self.assertFloatSeqEqual(self.port.win_to_proj(0, 0),
125     (-24.546524047851978, 70.450618743897664))
126     self.assertFloatSeqEqual(self.port.win_to_proj(100, 0),
127     (-23.442557137686929, 70.450618743897664))
128     self.assertFloatSeqEqual(self.port.win_to_proj(0, 100),
129     (-24.546524047851978, 69.346651833732622))
130 jonathan 1440
131 bh 1462 def test_proj_to_win(self):
132     self.assertFloatSeqEqual(self.port.proj_to_win(-24.546524047851978,
133     70.450618743897664),
134     (0, 0))
135     self.assertFloatSeqEqual(self.port.proj_to_win(-23.442557137686929,
136     70.450618743897664),
137     (100, 0))
138     self.assertFloatSeqEqual(self.port.proj_to_win(-24.546524047851978,
139     69.346651833732622),
140     (0, 100))
141    
142 bh 1464 def test_set_map(self):
143     """Test ViewPort.SetMap()"""
144     # The port already has a map. So we set it to None before we set
145     # it to self.map again.
146    
147     # Setting the map to None does not change the scale, but it will
148     # issue a MAP_REPLACED message.
149     self.port.SetMap(None)
150     self.check_messages([(MAP_REPLACED,)])
151    
152     self.clear_messages()
153    
154     self.port.SetMap(self.map)
155     self.check_messages([(90.582425142660739, SCALE_CHANGED),
156     (MAP_REPLACED,)])
157    
158 jonathan 1440 def testFitRectToWindow(self):
159     rect = self.port.win_to_proj(9, 990) + self.port.win_to_proj(990, 9)
160     self.port.FitRectToWindow(rect)
161 bh 1462 self.assertFloatSeqEqual(rect, self.port.win_to_proj(0, 1000)
162     + self.port.win_to_proj(1000, 0), 1e-1)
163 jonathan 1440
164     def testZoomFactor(self):
165     self.port.FitMapToWindow()
166     rect = self.port.win_to_proj(9, 990) + self.port.win_to_proj(990, 9)
167 bh 1462 proj_rect = self.port.win_to_proj(0,1000)+self.port.win_to_proj(1000,0)
168 jonathan 1440 self.port.ZoomFactor(2)
169     self.port.ZoomFactor(.5)
170 bh 1462 self.assertFloatSeqEqual(rect,
171     self.port.win_to_proj(0, 1000)
172     + self.port.win_to_proj(1000, 0), 1)
173 jonathan 1440
174     point = self.port.win_to_proj(600, 600)
175     self.port.ZoomFactor(2, (600, 600))
176 bh 1462 self.assertFloatSeqEqual(point, self.port.win_to_proj(500, 500), 1e-3)
177     self.port.FitMapToWindow()
178 jonathan 1440
179 bh 1462 proj_rect = self.port.win_to_proj(-499, 1499)\
180     + self.port.win_to_proj(1499, -499)
181 jonathan 1440 self.port.ZoomFactor(.5)
182 bh 1462 self.assertFloatSeqEqual(proj_rect,
183     self.port.win_to_proj(0, 1000)
184     + self.port.win_to_proj(1000, 0), 1)
185 jonathan 1440
186     def testZoomOutToRect(self):
187     self.port.FitMapToWindow()
188     rect = self.port.win_to_proj(9, 990) + self.port.win_to_proj(990, 9)
189 bh 1462 rectTo = self.port.win_to_proj(0, 1000) + self.port.win_to_proj(1000,
190     0)
191 jonathan 1440 self.port.ZoomOutToRect(rect)
192     self.assertFloatSeqEqual(rect, rectTo, 1)
193    
194     def testTranslate(self):
195     self.port.FitMapToWindow()
196 bh 1462 orig_rect = self.port.win_to_proj(0,1000)+self.port.win_to_proj(1000,0)
197 jonathan 1440 for delta in [(0, 0), (5, 0), (0, 5), (5,5),
198     (-5, 0), (0, -5), (-5, -5)]:
199     rect = self.port.win_to_proj(0 + delta[0], 1000 + delta[1]) \
200     + self.port.win_to_proj(1000 + delta[0], 0 + delta[1])
201     self.port.Translate(delta[0], delta[1])
202 bh 1462 self.assertFloatSeqEqual(rect,
203     self.port.win_to_proj(0, 1000)
204     + self.port.win_to_proj(1000, 0), 1)
205 jonathan 1440 self.port.Translate(-delta[0], -delta[1])
206     self.assertFloatSeqEqual(rect, orig_rect, 1)
207    
208     def test_unprojected_rect_around_point(self):
209     rect = self.port.unprojected_rect_around_point(500, 500, 5)
210 bh 1462 self.assertFloatSeqEqual(rect,
211     (-19.063379161960469, 64.924498140752377,
212     -18.95455127948528, 65.033326023227573),
213     1e-1)
214 jonathan 1440
215     def test_find_shape_at(self):
216     eq = self.assertEquals
217     x, y = self.port.proj_to_win(-18, 64.81418571)
218 bh 1462 eq(self.port.find_shape_at(x, y, searched_layer=self.layer),
219     (None, None))
220 jonathan 1440
221     x, y = self.port.proj_to_win(-18.18776318, 64.81418571)
222 bh 1462 eq(self.port.find_shape_at(x, y, searched_layer=self.layer),
223     (self.layer, 610))
224 jonathan 1440
225     def testLabelShapeAt(self):
226     eq = self.assertEquals
227    
228     # select a road
229     x, y = self.port.proj_to_win(-18.18776318, 64.81418571)
230     eq(self.port.LabelShapeAt(x, y), False) # nothing to do
231     eq(self.port.LabelShapeAt(x, y, "Hello world"), True) # add
232     eq(self.port.LabelShapeAt(x, y), True) # remove
233    
234     # select a point
235     x, y = self.port.proj_to_win(-19.140, 63.4055717)
236     eq(self.port.LabelShapeAt(x, y), False) # nothing to do
237     eq(self.port.LabelShapeAt(x, y, "Hello world"), True) # add
238     eq(self.port.LabelShapeAt(x, y), True) # remove
239    
240     # select a polygon
241     x, y = self.port.proj_to_win(-16.75286628, 64.67807745)
242     eq(self.port.LabelShapeAt(x, y), False) # nothing to do
243     eq(self.port.LabelShapeAt(x, y, "Hello world"), True) # add
244     # for polygons the coordinates will be different, so
245     # these numbers were copied
246     x, y = self.port.proj_to_win(-18.5939850348, 64.990607973)
247     eq(self.port.LabelShapeAt(x, y), True) # remove
248    
249    
250     def test_set_pos(self):
251     eq = self.assertEquals
252     # set_current_position / CurrentPosition
253     event = Event()
254     event.m_x, event.m_y = 5, 5
255     self.port.set_current_position(event)
256     eq(self.port.current_position, (5, 5))
257     eq(self.port.CurrentPosition(), self.port.win_to_proj(5, 5))
258     self.port.set_current_position(None)
259     eq(self.port.current_position, None)
260     eq(self.port.CurrentPosition(), None)
261    
262     event.m_x, event.m_y = 15, 15
263     self.port.MouseMove(event)
264     eq(self.port.current_position, (15, 15))
265     event.m_x, event.m_y = 25, 15
266     self.port.MouseLeftDown(event)
267     eq(self.port.current_position, (25, 15))
268     event.m_x, event.m_y = 15, 25
269     self.port.MouseLeftUp(event)
270     eq(self.port.current_position, (15, 25))
271    
272     def testTools(self):
273     eq = self.assertEquals
274     event = Event()
275     def test_tools(tool, shortcut):
276     self.port.SelectTool(tool)
277     eq(self.port.CurrentTool(), tool.Name())
278     self.port.SelectTool(None)
279     eq(self.port.CurrentTool(), None)
280     shortcut()
281     eq(self.port.CurrentTool(), tool.Name())
282    
283     test_tools(ZoomInTool(self.port), self.port.ZoomInTool)
284    
285     point = self.port.win_to_proj(600, 600)
286    
287     # one click zoom
288     event.m_x, event.m_y = 600, 600
289     self.port.MouseMove(event)
290     self.port.MouseLeftDown(event)
291     self.port.MouseLeftUp(event)
292 bh 1462 self.assertFloatSeqEqual(point, self.port.win_to_proj(500, 500), 1e-3)
293     self.port.FitMapToWindow()
294 jonathan 1440
295     # zoom rectangle
296     rect = self.port.win_to_proj(29, 970) + self.port.win_to_proj(970, 29)
297     event.m_x, event.m_y = 29, 29
298     self.port.MouseMove(event)
299     self.port.MouseLeftDown(event)
300     event.m_x, event.m_y = 970, 970
301     self.port.MouseMove(event)
302     self.port.MouseLeftUp(event)
303 bh 1462 self.assertFloatSeqEqual(rect,
304     self.port.win_to_proj(0, 1000)
305     + self.port.win_to_proj(1000, 0), 1e-1)
306     self.port.FitMapToWindow()
307 jonathan 1440
308     test_tools(ZoomOutTool(self.port), self.port.ZoomOutTool)
309    
310     # one click zoom out
311 bh 1462 proj_rect = self.port.win_to_proj(-499, 1499) \
312     + self.port.win_to_proj(1499, -499)
313 jonathan 1440 event.m_x, event.m_y = 500, 500
314     self.port.MouseMove(event)
315     self.port.MouseLeftDown(event)
316     self.port.MouseLeftUp(event)
317 bh 1462 self.assertFloatSeqEqual(proj_rect,
318     self.port.win_to_proj(0, 1000)
319     + self.port.win_to_proj(1000, 0),1e-1)
320     self.port.FitMapToWindow()
321 jonathan 1440
322     # zoom out rectangle
323     rect = self.port.win_to_proj(0, 1000) + self.port.win_to_proj(1000, 0)
324     event.m_x, event.m_y = 29, 29
325     self.port.MouseMove(event)
326     self.port.MouseLeftDown(event)
327     event.m_x, event.m_y = 970, 970
328     self.port.MouseMove(event)
329     self.port.MouseLeftUp(event)
330 bh 1462 self.assertFloatSeqEqual(rect,
331     self.port.win_to_proj(29, 970)
332     + self.port.win_to_proj(970, 29))
333     self.port.FitMapToWindow()
334 jonathan 1440
335     test_tools(PanTool(self.port), self.port.PanTool)
336    
337 bh 1462 rect = self.port.win_to_proj(-25, 975) + self.port.win_to_proj(975,-25)
338 jonathan 1440 event.m_x, event.m_y = 50, 50
339     self.port.MouseMove(event)
340     self.port.MouseLeftDown(event)
341     event.m_x, event.m_y = 75, 75
342     self.port.MouseMove(event)
343     self.port.MouseLeftUp(event)
344 bh 1462 self.assertFloatSeqEqual(rect,
345     self.port.win_to_proj(0, 1000)
346     + self.port.win_to_proj(1000, 0))
347 jonathan 1440
348     test_tools(IdentifyTool(self.port), self.port.IdentifyTool)
349    
350     event.m_x, event.m_y = self.port.proj_to_win(-18.18776318, 64.81418571)
351     self.port.MouseMove(event)
352     self.port.MouseLeftDown(event)
353     self.port.MouseLeftUp(event)
354     eq(self.port.SelectedShapes(), [610])
355 bh 1462
356 jonathan 1440 test_tools(LabelTool(self.port), self.port.LabelTool)
357    
358     # since adding a label requires use interaction with a dialog
359     # we will insert a label and then only test whether clicking
360     # removes the label
361    
362     x, y = self.port.proj_to_win(-19.140, 63.4055717)
363     self.port.LabelShapeAt(x, y, "Hello world")
364     event.m_x, event.m_y = x, y
365     self.port.MouseMove(event)
366     self.port.MouseLeftDown(event)
367     self.port.MouseLeftUp(event)
368     eq(self.port.LabelShapeAt(x, y), False) # should have done nothing
369    
370 bh 1781 def test_forwarding_title_changed(self):
371     """Test whether ViewPort forwards the TITLE_CHANGED message of the map
372     """
373     self.map.SetTitle(self.map.Title() + " something to make it different")
374     self.check_messages([(self.map, TITLE_CHANGED)])
375 jonathan 1440
376 bh 1781
377 bh 1608 class TestViewportWithPostGIS(unittest.TestCase):
378    
379     def setUp(self):
380     """Start the server and create a database.
381    
382     The database name will be stored in self.dbname, the server
383     object in self.server and the db object in self.db.
384     """
385     postgissupport.skip_if_no_postgis()
386     self.server = postgissupport.get_test_server()
387     self.dbref = self.server.get_default_static_data_db()
388     self.dbname = self.dbref.dbname
389     self.session = Session("PostGIS Session")
390     self.db = PostGISConnection(dbname = self.dbname,
391 bh 1634 **self.server.connection_params("user"))
392 bh 1608
393     proj = Projection(["proj=latlong",
394     "to_meter=.017453292519943",
395     "ellps=clrk66"])
396     self.map = Map("title", proj)
397    
398     self.port = ViewPort((1001, 1001))
399    
400     def tearDown(self):
401     self.session.Destroy()
402 bh 1781 self.port.Destroy()
403 bh 1608 self.map.Destroy()
404     self.map = self.port = None
405    
406     def test_find_shape_at_point(self):
407     """Test ViewPort.find_shape_at() with postgis point layer"""
408     layer = Layer("Point",
409     self.session.OpenDBShapeStore(self.db, "landmarks"))
410     prop = layer.GetClassification().GetDefaultGroup().GetProperties()
411     prop.SetFill(Color(0,0,0))
412     self.map.AddLayer(layer)
413    
414     self.port.SetMap(self.map)
415    
416     x, y = self.port.proj_to_win(-22.54335021, 66.30889129)
417 bh 1662 self.assertEquals(self.port.find_shape_at(x, y), (layer, 1001))
418 bh 1608
419     def test_find_shape_at_arc(self):
420     """Test ViewPort.find_shape_at() with postgis arc layer"""
421     layer = Layer("Arc", self.session.OpenDBShapeStore(self.db, "roads"))
422     self.map.AddLayer(layer)
423    
424     self.port.SetMap(self.map)
425    
426     x, y = self.port.proj_to_win(-18.18776318, 64.81418571)
427     self.assertEquals(self.port.find_shape_at(x, y), (layer, 610))
428    
429     def test_find_shape_at_polygon(self):
430     """Test ViewPort.find_shape_at() with postgis polygon layer"""
431     layer = Layer("Poly",
432     self.session.OpenDBShapeStore(self.db, "political"))
433     prop = layer.GetClassification().GetDefaultGroup().GetProperties()
434     prop.SetFill(Color(0,0,0))
435     self.map.AddLayer(layer)
436    
437     self.port.SetMap(self.map)
438    
439     x, y = self.port.proj_to_win(-19.78369, 65.1649143)
440     self.assertEquals(self.port.find_shape_at(x, y), (layer, 144))
441    
442    
443 jonathan 1440 if __name__ == "__main__":
444     unittest.main()
445    

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26