/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/UI/legend.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/UI/legend.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1895 - (show annotations)
Fri Oct 31 10:13:32 2003 UTC (21 years, 4 months ago) by frank
Original Path: trunk/thuban/Thuban/UI/legend.py
File MIME type: text/x-python
File size: 25094 byte(s)
Added two items to legend popup menu: Remove Layer and Show Layer Table

* Thuban/UI/legend.py
	(LegendPanel._OnRemoveLayer, LegendPanel._OnShowTable):
	New event handlers, call the corresponding mainwindow methods.
	(LegendTree._OnRightClick): Added items to popup menu.

1 # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Jonathan Coles <[email protected]>
4 # Frank Koormann <[email protected]>
5 #
6 # This program is free software under the GPL (>=v2)
7 # Read the file COPYING coming with Thuban for details.
8
9 __version__ = "$Revision$"
10
11 from math import fabs, cos, pi
12
13 from Thuban import _
14
15 import resource
16
17 from wxPython.wx import *
18
19 from Thuban.Model.layer import BaseLayer
20 from Thuban.Model.map import Map
21 from Thuban.Model.classification import ClassGroup
22 from Thuban.Model.proj import PROJ_UNITS_DEGREES
23
24 from Thuban.Model.messages import \
25 MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
26 LAYER_VISIBILITY_CHANGED, TITLE_CHANGED
27
28 from Thuban.UI.messages import SCALE_CHANGED
29
30 from Thuban.UI.classifier import ClassDataPreviewer
31 from Thuban.UI.dock import DockPanel
32 from Thuban.UI.scalebar import ScaleBar
33
34 from Thuban.Lib.connector import ConnectorError
35
36 ID_LEGEND_TOP = 4001
37 ID_LEGEND_RAISE = 4002
38 ID_LEGEND_LOWER = 4003
39 ID_LEGEND_BOTTOM = 4004
40 ID_LEGEND_TREE = 4005
41 ID_LEGEND_PROPS = 4006
42 ID_LEGEND_SHOWLAYER = 4007
43 ID_LEGEND_HIDELAYER = 4008
44
45 ID_POPUP_TOP = 4501
46 ID_POPUP_UP = 4502
47 ID_POPUP_DOWN = 4503
48 ID_POPUP_BOTTOM = 4504
49 ID_POPUP_PROPS = 4506
50 ID_POPUP_VISIBLE = 4507
51 ID_POPUP_PROJ = 4509
52 ID_POPUP_REMOVE = 4510
53 ID_POPUP_SHOWTABLE = 4511
54
55 BMP_SIZE_W = 15
56 BMP_SIZE_H = 15
57
58 TOP_BMP = "top_layer"
59 RAISE_BMP = "raise_layer"
60 LOWER_BMP = "lower_layer"
61 BOTTOM_BMP = "bottom_layer"
62 SHOW_BMP = "show_layer"
63 HIDE_BMP = "hide_layer"
64 PROPS_BMP = "layer_properties"
65
66
67 class LegendPanel(DockPanel):
68
69 def __init__(self, parent, map, mainWindow):
70 DockPanel.__init__(self, parent, -1)
71
72 self.mainWindow = mainWindow
73 self.parent = parent
74
75 self.buttons = []
76
77 panelBox = wxBoxSizer(wxVERTICAL)
78
79 self.toolBar = wxToolBar(self, -1)
80 self.toolBar.SetToolBitmapSize(wxSize(24, 24))
81
82 bmp = resource.GetBitmapResource(TOP_BMP, wxBITMAP_TYPE_XPM)
83 self.toolBar.AddTool(ID_LEGEND_TOP, bmp,
84 shortHelpString=_("Top Layer"))
85
86 bmp = resource.GetBitmapResource(RAISE_BMP, wxBITMAP_TYPE_XPM)
87 self.toolBar.AddTool(ID_LEGEND_RAISE, bmp,
88 shortHelpString=_("Raise Layer"))
89
90 bmp = resource.GetBitmapResource(LOWER_BMP, wxBITMAP_TYPE_XPM)
91 self.toolBar.AddTool(ID_LEGEND_LOWER, bmp,
92 shortHelpString=_("Lower Layer"))
93
94 bmp = resource.GetBitmapResource(BOTTOM_BMP, wxBITMAP_TYPE_XPM)
95 self.toolBar.AddTool(ID_LEGEND_BOTTOM, bmp,
96 shortHelpString=_("Bottom Layer"))
97
98 bmp = resource.GetBitmapResource(SHOW_BMP, wxBITMAP_TYPE_XPM)
99 self.toolBar.AddTool(ID_LEGEND_SHOWLAYER, bmp,
100 shortHelpString=_("Show Layer"))
101
102 bmp = resource.GetBitmapResource(HIDE_BMP, wxBITMAP_TYPE_XPM)
103 self.toolBar.AddTool(ID_LEGEND_HIDELAYER, bmp,
104 shortHelpString=_("Hide Layer"))
105
106 bmp = resource.GetBitmapResource(PROPS_BMP, wxBITMAP_TYPE_XPM)
107 self.toolBar.AddTool(ID_LEGEND_PROPS, bmp,
108 shortHelpString=_("Edit Layer Properties"))
109
110 self.toolBar.Realize()
111 panelBox.Add(self.toolBar, 0, wxGROW, 0)
112
113 EVT_TOOL(self, ID_LEGEND_TOP, self._OnMoveTop)
114 EVT_TOOL(self, ID_LEGEND_RAISE, self._OnMoveUp)
115 EVT_TOOL(self, ID_LEGEND_LOWER, self._OnMoveDown)
116 EVT_TOOL(self, ID_LEGEND_BOTTOM, self._OnMoveBottom)
117 EVT_TOOL(self, ID_LEGEND_PROPS, self._OnProperties)
118 EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
119 EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)
120
121 EVT_MENU(self, ID_POPUP_PROPS, self._OnProperties)
122 EVT_MENU(self, ID_POPUP_TOP, self._OnMoveTop)
123 EVT_MENU(self, ID_POPUP_UP, self._OnMoveUp)
124 EVT_MENU(self, ID_POPUP_DOWN, self._OnMoveDown)
125 EVT_MENU(self, ID_POPUP_BOTTOM, self._OnMoveBottom)
126 EVT_MENU(self, ID_POPUP_VISIBLE, self._OnToggleVisibility)
127 EVT_MENU(self, ID_POPUP_PROJ, self._OnProjection)
128 EVT_MENU(self, ID_POPUP_REMOVE, self._OnRemoveLayer)
129 EVT_MENU(self, ID_POPUP_SHOWTABLE, self._OnShowTable)
130
131 self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
132
133 panelBox.Add(self.tree, 1, wxGROW, 0)
134
135 self.scalebarbitmap = ScaleBarBitmap(self, map, mainWindow)
136 panelBox.Add(self.scalebarbitmap, 0, wxGROW, 0)
137
138 self.SetAutoLayout(True)
139 self.SetSizer(panelBox)
140 panelBox.SetSizeHints(self)
141
142
143 self.panelBox = panelBox
144
145 self.__EnableButtons(False)
146
147 self.Create()
148
149 EVT_CLOSE(self, self._OnClose)
150
151
152 def GetMap(self):
153 return self.tree.GetMap()
154
155 def SetMap(self, map):
156 self.tree.SetMap(map)
157 self.scalebarbitmap.SetCanvas(self.mainWindow.canvas)
158
159 def DoOnSelChanged(self, layer, group):
160
161 ok = isinstance(layer, BaseLayer)
162 self.__EnableButtons(ok)
163
164 self.mainWindow.SelectLayer(layer)
165
166 def DoOnProperties(self):
167 list = self.tree.GetSelectedHierarchy()
168
169 ok = isinstance(list[0], BaseLayer)
170 if ok:
171 self.mainWindow.OpenLayerProperties(list[0], list[1])
172
173 def Destroy(self):
174 self.__Close()
175
176 def _OnProperties(self, event):
177 self.DoOnProperties()
178
179 def _OnMoveTop(self, event):
180 self.tree.MoveCurrentItemTop()
181
182 def _OnMoveUp(self, event):
183 self.tree.MoveCurrentItemUp()
184
185 def _OnMoveDown(self, event):
186 self.tree.MoveCurrentItemDown()
187
188 def _OnMoveBottom(self, event):
189 self.tree.MoveCurrentItemBottom()
190
191 def _OnShowLayer(self, event):
192 self.tree.DoOnShowLayer()
193 pass
194
195 #def Close(self, force = False):
196 #DockPanel.Close(self, force)
197
198 def _OnClose(self, event):
199 self.__Close()
200
201 def _OnHideLayer(self, event):
202 self.tree.DoOnHideLayer()
203 pass
204
205 def _OnToggleVisibility(self, event):
206 self.tree.ToggleVisibility()
207
208 def _OnProjection(self, event):
209 self.tree.LayerProjection()
210
211 def _OnRemoveLayer(self, event):
212 self.mainWindow.RemoveLayer()
213
214 def _OnShowTable(self, event):
215 self.mainWindow.LayerShowTable()
216
217 def __EnableButtons(self, on):
218 self.toolBar.EnableTool(ID_LEGEND_TOP, on)
219 self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
220 self.toolBar.EnableTool(ID_LEGEND_LOWER, on)
221 self.toolBar.EnableTool(ID_LEGEND_BOTTOM, on)
222 self.toolBar.EnableTool(ID_LEGEND_SHOWLAYER, on)
223 self.toolBar.EnableTool(ID_LEGEND_HIDELAYER, on)
224 self.toolBar.EnableTool(ID_LEGEND_PROPS, on)
225
226 def __Close(self):
227 self.tree.Close()
228
229 class LegendTree(wxTreeCtrl):
230
231 def __init__(self, parent, id, map, mainWindow):
232 wxTreeCtrl.__init__(self, parent, id,
233 style = wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT,
234 size = (200, 200))
235
236 self.mainWindow = mainWindow
237 self.map = None
238 self.parent = parent
239 self.changing_selection = 0
240
241 #
242 # The image list used by the wxTreeCtrl causes problems when
243 # we remove layers and/or change a classification because it
244 # changes the image indices if you remove images from the list.
245 # Rather than removing unused images we use this list to keep
246 # track of which indices are available in the image list
247 # (because of a previous removal) and then replace those indices
248 # with new images rather than appending to the end of the image
249 # list (assuming there are any that are available).
250 #
251 self.availImgListIndices = []
252
253 self.image_list = None
254 self.emptyImageIndex = 0
255
256 self.previewer = ClassDataPreviewer()
257
258 self.preventExpandCollapse = False
259 self.raiseProperties = False
260
261 EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
262 EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)
263 EVT_TREE_ITEM_EXPANDING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
264 EVT_TREE_ITEM_COLLAPSING(self, ID_LEGEND_TREE, self.OnItemExpandCollapse)
265 EVT_TREE_ITEM_RIGHT_CLICK(self, ID_LEGEND_TREE, self._OnRightClick)
266
267 EVT_CLOSE(self, self._OnClose)
268
269 self.SetMap(map)
270
271 def _OnRightClick(self, event):
272 """Select item and pop up a context menu"""
273
274 # The pop up menu is related to the legend tree, so we have direct
275 # access on the tree items. The events issued by the menu are handled
276 # by the legend panel, since most of the handlers are already
277 # implemented there.
278
279 # Update item selection to the right click
280 item = event.GetItem()
281 self.SelectItem(item)
282
283 # Create the menu
284 menu = wxMenu("", 0)
285
286 # The "Visible" item is a special ...
287 menuitem = wxMenuItem(menu, ID_POPUP_VISIBLE, _("Visible"),
288 "", wxITEM_CHECK)
289 menu.AppendItem(menuitem)
290 layer, group = self.GetSelectedHierarchy()
291 menuitem.Check(layer.Visible())
292
293 menu.AppendSeparator()
294 menu.Append(ID_POPUP_PROPS, _("&Properties..."))
295 menu.Append(ID_POPUP_PROJ, _("Pro&jection..."))
296 menu.Append(ID_POPUP_REMOVE, _("&Remove Layer"))
297 menu.Append(ID_POPUP_SHOWTABLE, _("Show Ta&ble"))
298 menu.AppendSeparator()
299 menu.Append(ID_POPUP_TOP, _("Top Layer"))
300 menu.Append(ID_POPUP_UP, _("Raise Layer"))
301 menu.Append(ID_POPUP_DOWN, _("Lower Layer"))
302 menu.Append(ID_POPUP_BOTTOM, _("Bottom Layer"))
303
304 # Display the menu
305 pos = event.GetPoint()
306 shift = self.ClientToScreen((0,0))
307 self.PopupMenu(menu, pos)
308
309 def find_layer(self, layer):
310 """Return the tree item for the layer"""
311 root = self.GetRootItem()
312 id, cookie = self.GetFirstChild(root, 0)
313 while id.IsOk():
314 if self.GetPyData(id) is layer:
315 return id
316 id, cookie = self.GetNextChild(root, cookie)
317 return None
318
319 def _OnClose(self, event):
320 self.SetMap(None)
321
322 def GetMap(self):
323 return self.map
324
325 def SetMap(self, map):
326
327 sub_list = [(MAP_STACKING_CHANGED, self._OnMsgMapStackingChanged),
328 (MAP_LAYERS_ADDED, self._OnMsgMapLayersAdded),
329 (MAP_LAYERS_REMOVED, self._OnMsgMapLayersRemoved)]
330
331 if self.map is not None:
332 for msg, func in sub_list: self.map.Unsubscribe(msg, func)
333 #self.mainWindow.application.Unsubscribe(SESSION_REPLACED,
334 #self._OnMsgMapsChanged)
335 #try:
336 #self.mainWindow.application.session.Unsubscribe(MAPS_CHANGED,
337 #self._OnMsgMapsChanged)
338 #except ConnectorError:
339 #pass
340 self.DeleteAllItems()
341
342 self.map = map
343
344 if self.map is not None:
345 for msg, func in sub_list: self.map.Subscribe(msg, func)
346 #self.mainWindow.application.session.Subscribe(MAPS_CHANGED,
347 #self._OnMsgMapsChanged)
348 #self.mainWindow.application.Subscribe(SESSION_REPLACED,
349 #self._OnMsgMapsChanged)
350 self.__FillTree(self.map)
351
352 def MoveCurrentItemTop(self):
353 layer, group = self.GetSelectedHierarchy()
354
355 if layer is not None:
356 self.map.MoveLayerToTop(layer)
357 else:
358 assert False, "Shouldn't be allowed."
359 pass
360
361 def MoveCurrentItemUp(self):
362 layer, group = self.GetSelectedHierarchy()
363
364 if layer is not None:
365 self.map.RaiseLayer(layer)
366 else:
367 assert False, "Shouldn't be allowed."
368 pass
369
370 def MoveCurrentItemDown(self):
371 layer, group = self.GetSelectedHierarchy()
372
373 if layer is not None:
374 self.map.LowerLayer(layer)
375 else:
376 assert False, "Shouldn't be allowed."
377 pass
378
379 def MoveCurrentItemBottom(self):
380 layer, group = self.GetSelectedHierarchy()
381
382 if layer is not None:
383 self.map.MoveLayerToBottom(layer)
384 else:
385 assert False, "Shouldn't be allowed."
386 pass
387
388 def OnCompareItems(self, item1, item2):
389
390 data1 = self.GetPyData(item1)
391 data2 = self.GetPyData(item2)
392
393 if isinstance(data1, BaseLayer):
394 layers = self.map.Layers()
395 return layers.index(data2) - layers.index(data1)
396 else:
397 return wxTreeCtrl.OnCompareItems(self, item1, item2)
398
399 def DoOnShowLayer(self):
400 layer, group = self.GetSelectedHierarchy()
401 layer.SetVisible(True)
402
403 def DoOnHideLayer(self):
404 layer, group = self.GetSelectedHierarchy()
405 layer.SetVisible(False)
406
407 def ToggleVisibility(self):
408 layer, group = self.GetSelectedHierarchy()
409
410 layer.SetVisible(not layer.Visible())
411
412 def LayerProjection(self):
413 self.parent.mainWindow.LayerProjection()
414
415 def Sort(self):
416 self.SortChildren(self.GetRootItem())
417
418 def GetSelectedHierarchy(self):
419 id = self.GetSelection()
420
421 if not id.IsOk():
422 return (None, None)
423
424 layer = self.GetPyData(id)
425 group = None
426
427 if isinstance(layer, ClassGroup):
428 id = self.GetItemParent(id)
429 assert id.IsOk()
430 group = layer
431 layer = self.GetPyData(id)
432
433 return (layer, group)
434
435 def _OnMsgMapsChanged(self):
436 #print self.map is self.mainWindow.Map()
437 self.SetMap(self.mainWindow.Map())
438
439 def _OnSelChanged(self, event):
440 # If we change the selection from normalize_selection do nothing.
441 if self.changing_selection:
442 return
443
444 self.normalize_selection()
445 self.__UpdateSelection()
446
447 def normalize_selection(self):
448 """Select the layer containing currently selected item"""
449 # This is really a workaround for a bug in wx where deleting a
450 # subtree with DeleteChildren does not update the selection
451 # properly and can lead to segfaults later because the return
452 # value of GetSelection points to invalid data.
453 item = self.GetSelection()
454 while item.IsOk():
455 object = self.GetPyData(item)
456 if isinstance(object, BaseLayer):
457 break
458 item = self.GetItemParent(item)
459 else:
460 # No layer was found in the chain of parents, so there's
461 # nothing we can do.
462 return
463
464 self.changing_selection = 1
465 try:
466 self.SelectItem(item)
467 finally:
468 self.changing_selection = 0
469
470
471 def OnItemExpandCollapse(self, event):
472 if self.preventExpandCollapse:
473 event.Veto()
474 self.preventExpandCollapse = False
475
476 def _OnItemActivated(self, event):
477 # The following looks strange but is need under Windows to
478 # raise the Properties on double-click: The tree control
479 # always gets an Expanded / Collapsed event after the ItemActivated
480 # on double click, which raises the main window again. We add a second
481 # ItemActivated event to the queue, which simply raises the already
482 # displayed window.
483 if self.raiseProperties:
484 self.parent.DoOnProperties()
485 self.raiseProperties = False
486 else:
487 self.raiseProperties = True
488 self.preventExpandCollapse = True
489 self.parent.DoOnProperties()
490 self.AddPendingEvent(event)
491
492 def _OnMsgLayerChanged(self, layer):
493 assert isinstance(layer, BaseLayer)
494
495 id = self.find_layer(layer)
496 assert id is not None
497
498 self.__FillTreeLayer(id)
499 self.__UpdateSelection()
500
501 def _OnMsgMapStackingChanged(self, *args):
502 self.Sort()
503 id = self.GetSelection()
504
505 if id.IsOk():
506 self.EnsureVisible(id)
507 self.__UpdateSelection()
508
509 def _OnMsgMapLayersAdded(self, map):
510 assert map is self.map
511
512 # Build a dict with all layers known by the the tree as keys
513 layers = {}
514 root = self.GetRootItem()
515 id, cookie = self.GetFirstChild(root, 0)
516 while id.IsOk():
517 layers[self.GetPyData(id)] = 1
518 id, cookie = self.GetNextChild(root, cookie)
519
520 # Add layers in the map but not in the dict
521 i = 0
522 for l in map.Layers():
523 if not l in layers:
524 self.__AddLayer(i, l)
525
526 self.__UpdateSelection()
527
528 def _OnMsgMapLayersRemoved(self, map):
529 assert map is self.map
530
531 layers = map.Layers()
532
533 root = self.GetRootItem()
534 id, cookie = self.GetFirstChild(root, 0)
535 while id.IsOk():
536 if self.GetPyData(id) not in layers:
537 self.__RemoveLayer(id)
538 id, cookie = self.GetNextChild(root, cookie)
539
540
541 self.__UpdateSelection()
542
543 def _OnMsgLayerVisibilityChanged(self, layer):
544 assert isinstance(layer, BaseLayer)
545
546 self.__ShowHideLayer(layer)
547 self.__UpdateSelection()
548
549 def _OnMsgLayerTitleChanged(self, layer):
550
551 id = self.find_layer(layer)
552 if id.IsOk():
553 self.SetItemText(id, layer.Title())
554 self.__UpdateSelection()
555
556 def __UpdateSelection(self):
557 layer, group = self.GetSelectedHierarchy()
558 self.parent.DoOnSelChanged(layer, group)
559
560 def __FillTree(self, map):
561
562 self.Freeze()
563
564 self.DeleteAllItems()
565
566 if map.HasLayers():
567 root = self.GetRootItem()
568 for l in map.Layers():
569 self.__AddLayer(0, l)
570
571 self.Thaw()
572
573 def __FillTreeLayer(self, pid):
574 layer = self.GetPyData(pid)
575
576 self.Freeze()
577
578 self.DeleteChildren(pid)
579
580 if layer.HasClassification():
581
582 clazz = layer.GetClassification()
583
584 shapeType = layer.ShapeType()
585
586 show = layer.Visible()
587 for g in clazz:
588 if g.IsVisible():
589 id = self.AppendItem(pid, g.GetDisplayText())
590 self.SetPyData(id, g)
591 self.__SetVisibilityStyle(show, id)
592
593 bmp = self.__BuildGroupImage(g, shapeType)
594
595 if bmp is None:
596 self.SetItemImage(id, -1)
597 self.SetItemSelectedImage(id, -1)
598 else:
599 if self.availImgListIndices:
600 i = self.availImgListIndices.pop(0)
601 self.image_list.Replace(i, bmp)
602 else:
603 i = self.image_list.Add(bmp)
604
605 self.SetItemImage(id, i)
606 self.SetItemSelectedImage(id, i)
607
608 self.Thaw()
609
610 def __BuildGroupImage(self, group, shapeType):
611
612 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
613 #brush = wxBrush(Color2wxColour(item[1]), wxSOLID)
614 dc = wxMemoryDC()
615 dc.SelectObject(bmp)
616 dc.Clear()
617
618 self.previewer.Draw(dc, None, group.GetProperties(), shapeType)
619
620 return bmp
621
622 def DeleteAllItems(self):
623
624 pid = self.GetRootItem()
625
626 id, cookie = self.GetFirstChild(pid, 123)
627 while id.IsOk():
628 self.__RemoveLayer(id)
629 id, cookie = self.GetNextChild(pid, cookie)
630
631 wxTreeCtrl.DeleteAllItems(self)
632
633 def __AddLayer(self, before, l):
634 root = self.GetRootItem()
635 id = self.InsertItemBefore(root, before,
636 l.Title(),
637 self.mapImageIndex,
638 self.mapImageIndex)
639
640 self.SetPyData(id, l)
641 self.__SetVisibilityStyle(l.Visible(), id)
642
643 self.__FillTreeLayer(id)
644 self.Expand(id)
645
646 l.Subscribe(LAYER_CHANGED, self._OnMsgLayerChanged)
647 l.Subscribe(LAYER_VISIBILITY_CHANGED,
648 self._OnMsgLayerVisibilityChanged)
649 l.Subscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
650
651 def __RemoveLayer(self, id):
652 self.DeleteChildren(id)
653
654 layer = self.GetPyData(id)
655 layer.Unsubscribe(LAYER_CHANGED,
656 self._OnMsgLayerChanged)
657 layer.Unsubscribe(LAYER_VISIBILITY_CHANGED,
658 self._OnMsgLayerVisibilityChanged)
659 layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
660
661 self.Delete(id)
662
663 def DeleteChildren(self, pid):
664 id, cookie = self.GetFirstChild(pid, 123)
665 while id.IsOk():
666 self.availImgListIndices.append(self.GetItemImage(id))
667 id, cookie = self.GetNextChild(pid, cookie)
668 wxTreeCtrl.DeleteChildren(self, pid)
669
670 def GetRootItem(self):
671 root = wxTreeCtrl.GetRootItem(self)
672
673 if not root.IsOk():
674 self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
675
676 bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
677 dc = wxMemoryDC()
678 dc.SelectObject(bmp)
679 dc.SetBrush(wxBLACK_BRUSH)
680 dc.Clear()
681 dc.SelectObject(wxNullBitmap)
682
683 self.emptyImageIndex = \
684 self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
685
686 bmp = resource.GetBitmapResource("legend_icon_layer",
687 wxBITMAP_TYPE_XPM)
688 self.mapImageIndex = \
689 self.image_list.Add(bmp)
690
691 self.AssignImageList(self.image_list)
692 self.availImgListIndices = []
693
694 root = self.AddRoot("")
695
696 return root
697
698 def __SetVisibilityStyle(self, visible, id):
699 font = self.GetItemFont(id)
700
701 if visible:
702 font.SetStyle(wxNORMAL)
703 color = wxBLACK
704 else:
705 #font.SetStyle(wxITALIC)
706 font.SetStyle(wxNORMAL)
707 color = wxLIGHT_GREY
708
709 self.SetItemTextColour(id, color)
710 self.SetItemFont(id, font)
711
712 def __ShowHideLayer(self, layer):
713 parent = self.find_layer(layer)
714 assert parent.IsOk()
715
716 visible = layer.Visible()
717
718 self.__SetVisibilityStyle(visible, parent)
719
720 id, cookie = self.GetFirstChild(parent, 123)
721
722 while id.IsOk():
723 self.__SetVisibilityStyle(visible, id)
724 id, cookie = self.GetNextChild(parent, cookie)
725
726 class ScaleBarBitmap(wxBoxSizer):
727
728 def __init__(self, parent, map, mainWindow):
729 # While the width is fixed, get the height _now_.
730 dc = wxMemoryDC()
731 textwidth, textheight = dc.GetTextExtent("%d"%0)
732 self.width = 210
733 self.height = textheight + 3*2 + 8
734
735 wxBoxSizer.__init__(self, wxVERTICAL)
736 bmp=wxEmptyBitmap(self.width, self.height)
737 self.scalebarBitmap = wxStaticBitmap(parent, -1, bmp)
738 self.Add(self.scalebarBitmap, 0, wxALIGN_CENTER|wxLEFT|wxTOP|wxRIGHT, 1)
739
740 self.mainWindow = mainWindow
741 self.parent = parent
742 self.canvas = None
743 self.SetCanvas(self.mainWindow.canvas)
744
745 def SetCanvas(self, canvas):
746 sub_list = [(SCALE_CHANGED, self._OnMsgScaleChanged)]
747
748 if self.canvas is not None:
749 for msg, func in sub_list: self.canvas.Unsubscribe(msg, func)
750
751 self.canvas = canvas
752 self.scalebar = ScaleBar(canvas.map)
753
754 if self.canvas is not None:
755 for msg, func in sub_list: self.canvas.Subscribe(msg, func)
756 self.__SetScale(self.canvas.scale)
757
758 def _OnMsgScaleChanged(self, scale):
759 self.__SetScale(scale)
760
761 def __SetScale(self, scale):
762 bmp = wxEmptyBitmap(self.width, self.height)
763 dc = wxMemoryDC()
764 dc.SelectObject(bmp)
765 dc.Clear()
766
767 if self.canvas.map is not None \
768 and self.canvas.map.projection is not None:
769
770 # if we are using a projection with geographics coordinates
771 # we need to change the scale value based on where we are
772 # on the globe.
773 if self.canvas.map.projection.GetProjectedUnits() \
774 == PROJ_UNITS_DEGREES:
775
776 width, height = self.canvas.GetSizeTuple()
777 long, lat = self.canvas.win_to_proj(width/2, height/2)
778
779 # slightly inaccurate, but if we are looking at
780 # the north/south pole we could end up dividing by zero
781 #
782 # it shouldn't matter for our purposes that we ignore
783 # the original sign of lat.
784 if fabs(lat) > 89.9: lat = 89.9
785
786 #
787 # one degree is about 111,133m at the equator
788 # we need to adjust that for latitude as
789 # we move north/south. use the center of the map
790 # as the point to scale the length to.
791 #
792 scale = scale / (111133.0 * fabs(cos(lat * pi/180)))
793
794 self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())
795
796 self.scalebarBitmap.SetBitmap(bmp)
797

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26