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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1113 by bh, Fri May 30 15:59:49 2003 UTC revision 1895 by frank, Fri Oct 31 10:13:32 2003 UTC
# Line 8  Line 8 
8    
9  __version__ = "$Revision$"  __version__ = "$Revision$"
10    
11    from  math import fabs, cos, pi
12    
13  from Thuban import _  from Thuban import _
14    
15  import resource  import resource
# Line 17  from wxPython.wx import * Line 19  from wxPython.wx import *
19  from Thuban.Model.layer import BaseLayer  from Thuban.Model.layer import BaseLayer
20  from Thuban.Model.map import Map  from Thuban.Model.map import Map
21  from Thuban.Model.classification import ClassGroup  from Thuban.Model.classification import ClassGroup
22    from Thuban.Model.proj import PROJ_UNITS_DEGREES
23    
24  from Thuban.Model.messages import \  from Thuban.Model.messages import \
25      MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\      MAP_STACKING_CHANGED, MAP_LAYERS_ADDED, MAP_LAYERS_REMOVED, LAYER_CHANGED,\
# Line 39  ID_LEGEND_PROPS = 4006 Line 42  ID_LEGEND_PROPS = 4006
42  ID_LEGEND_SHOWLAYER = 4007  ID_LEGEND_SHOWLAYER = 4007
43  ID_LEGEND_HIDELAYER = 4008  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  BMP_SIZE_W = 15
56  BMP_SIZE_H = 15  BMP_SIZE_H = 15
57    
# Line 105  class LegendPanel(DockPanel): Line 118  class LegendPanel(DockPanel):
118          EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)          EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer)
119          EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer)          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)          self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow)
132    
133          panelBox.Add(self.tree, 1, wxGROW, 0)          panelBox.Add(self.tree, 1, wxGROW, 0)
# Line 179  class LegendPanel(DockPanel): Line 202  class LegendPanel(DockPanel):
202          self.tree.DoOnHideLayer()          self.tree.DoOnHideLayer()
203          pass          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):      def __EnableButtons(self, on):
218          self.toolBar.EnableTool(ID_LEGEND_TOP, on)          self.toolBar.EnableTool(ID_LEGEND_TOP, on)
219          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)          self.toolBar.EnableTool(ID_LEGEND_RAISE, on)
# Line 201  class LegendTree(wxTreeCtrl): Line 236  class LegendTree(wxTreeCtrl):
236          self.mainWindow = mainWindow          self.mainWindow = mainWindow
237          self.map = None          self.map = None
238          self.parent = parent          self.parent = parent
         self.layer2id = {}  
239          self.changing_selection = 0          self.changing_selection = 0
240    
241          #          #
# Line 221  class LegendTree(wxTreeCtrl): Line 255  class LegendTree(wxTreeCtrl):
255    
256          self.previewer = ClassDataPreviewer()          self.previewer = ClassDataPreviewer()
257    
258            self.preventExpandCollapse = False
259            self.raiseProperties = False
260    
261          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)          EVT_TREE_ITEM_ACTIVATED(self, ID_LEGEND_TREE, self._OnItemActivated)
262          EVT_TREE_SEL_CHANGED(self, ID_LEGEND_TREE, self._OnSelChanged)          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)          EVT_CLOSE(self, self._OnClose)
268    
269          self.SetMap(map)          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):      def _OnClose(self, event):
320          self.SetMap(None)          self.SetMap(None)
321    
# Line 316  class LegendTree(wxTreeCtrl): Line 404  class LegendTree(wxTreeCtrl):
404          layer, group = self.GetSelectedHierarchy()          layer, group = self.GetSelectedHierarchy()
405          layer.SetVisible(False)          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):      def Sort(self):
416          self.SortChildren(self.GetRootItem())          self.SortChildren(self.GetRootItem())
417    
# Line 372  class LegendTree(wxTreeCtrl): Line 468  class LegendTree(wxTreeCtrl):
468              self.changing_selection = 0              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):      def _OnItemActivated(self, event):
477          self.parent.DoOnProperties()          # 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):      def _OnMsgLayerChanged(self, layer):
493          assert isinstance(layer, BaseLayer)          assert isinstance(layer, BaseLayer)
494    
495          id = self.layer2id[layer]          id = self.find_layer(layer)
496          assert id.IsOk()          assert id is not None
497    
498          self.__FillTreeLayer(id)          self.__FillTreeLayer(id)
499          self.__UpdateSelection()          self.__UpdateSelection()
# Line 395  class LegendTree(wxTreeCtrl): Line 509  class LegendTree(wxTreeCtrl):
509      def _OnMsgMapLayersAdded(self, map):      def _OnMsgMapLayersAdded(self, map):
510          assert map is self.map          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()          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          i = 0
522          for l in map.Layers():          for l in map.Layers():
523              if not self.layer2id.has_key(l):              if not l in layers:
524                  self.__AddLayer(i, l)                  self.__AddLayer(i, l)
525    
526          self.__UpdateSelection()          self.__UpdateSelection()
# Line 407  class LegendTree(wxTreeCtrl): Line 528  class LegendTree(wxTreeCtrl):
528      def _OnMsgMapLayersRemoved(self, map):      def _OnMsgMapLayersRemoved(self, map):
529          assert map is self.map          assert map is self.map
530    
         layer, group = self.GetSelectedHierarchy()  
   
         if layer is None:  
             assert False, "Shouldn't be allowed."  
             return  
   
531          layers = map.Layers()          layers = map.Layers()
532    
533          for layer, id in self.layer2id.items():          root = self.GetRootItem()
534              if layer not in layers:          id, cookie = self.GetFirstChild(root, 0)
535                  if id.IsOk():          while id.IsOk():
536                      self.__RemoveLayer(id)              if self.GetPyData(id) not in layers:
537                    self.__RemoveLayer(id)
538                id, cookie = self.GetNextChild(root, cookie)
539    
540    
541          self.__UpdateSelection()          self.__UpdateSelection()
542    
# Line 430  class LegendTree(wxTreeCtrl): Line 548  class LegendTree(wxTreeCtrl):
548    
549      def _OnMsgLayerTitleChanged(self, layer):      def _OnMsgLayerTitleChanged(self, layer):
550    
551          id = self.layer2id[layer]          id = self.find_layer(layer)
552          if id.IsOk():          if id.IsOk():
553              self.SetItemText(id, layer.Title())              self.SetItemText(id, layer.Title())
554          self.__UpdateSelection()          self.__UpdateSelection()
# Line 522  class LegendTree(wxTreeCtrl): Line 640  class LegendTree(wxTreeCtrl):
640          self.SetPyData(id, l)          self.SetPyData(id, l)
641          self.__SetVisibilityStyle(l.Visible(), id)          self.__SetVisibilityStyle(l.Visible(), id)
642    
         self.layer2id[l] = id  
   
643          self.__FillTreeLayer(id)          self.__FillTreeLayer(id)
644          self.Expand(id)          self.Expand(id)
645    
# Line 543  class LegendTree(wxTreeCtrl): Line 659  class LegendTree(wxTreeCtrl):
659          layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)          layer.Unsubscribe(TITLE_CHANGED, self._OnMsgLayerTitleChanged)
660    
661          self.Delete(id)          self.Delete(id)
         del self.layer2id[layer]  
662    
663      def DeleteChildren(self, pid):      def DeleteChildren(self, pid):
664          id, cookie = self.GetFirstChild(pid, 123)          id, cookie = self.GetFirstChild(pid, 123)
# Line 557  class LegendTree(wxTreeCtrl): Line 672  class LegendTree(wxTreeCtrl):
672    
673          if not root.IsOk():          if not root.IsOk():
674              self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)              self.image_list = wxImageList(BMP_SIZE_W, BMP_SIZE_H, False, 0)
675                                                                                    
676              bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)              bmp = wxEmptyBitmap(BMP_SIZE_W, BMP_SIZE_H)
677              dc = wxMemoryDC()              dc = wxMemoryDC()
678              dc.SelectObject(bmp)              dc.SelectObject(bmp)
679              dc.SetBrush(wxBLACK_BRUSH)              dc.SetBrush(wxBLACK_BRUSH)
680              dc.Clear()              dc.Clear()
681              dc.SelectObject(wxNullBitmap)              dc.SelectObject(wxNullBitmap)
682                                                                                    
683              self.emptyImageIndex = \              self.emptyImageIndex = \
684                  self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))                  self.image_list.AddWithColourMask(bmp, wxColour(0, 0, 0))
685                                                                                    
686              bmp = resource.GetBitmapResource("legend_icon_layer",              bmp = resource.GetBitmapResource("legend_icon_layer",
687                                                wxBITMAP_TYPE_XPM)                                                wxBITMAP_TYPE_XPM)
688              self.mapImageIndex = \              self.mapImageIndex = \
689                  self.image_list.Add(bmp)                  self.image_list.Add(bmp)
690    
691              self.AssignImageList(self.image_list)              self.AssignImageList(self.image_list)
692                self.availImgListIndices = []
693    
694              root = self.AddRoot("")              root = self.AddRoot("")
695    
# Line 594  class LegendTree(wxTreeCtrl): Line 710  class LegendTree(wxTreeCtrl):
710          self.SetItemFont(id, font)          self.SetItemFont(id, font)
711                    
712      def __ShowHideLayer(self, layer):      def __ShowHideLayer(self, layer):
713          parent = self.layer2id[layer]          parent = self.find_layer(layer)
714          assert parent.IsOk()          assert parent.IsOk()
715    
716          visible = layer.Visible()          visible = layer.Visible()
# Line 648  class ScaleBarBitmap(wxBoxSizer): Line 764  class ScaleBarBitmap(wxBoxSizer):
764          dc.SelectObject(bmp)          dc.SelectObject(bmp)
765          dc.Clear()          dc.Clear()
766    
767          self.scalebar.DrawScaleBar(scale, dc, (0,0), dc.GetSizeTuple())          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)          self.scalebarBitmap.SetBitmap(bmp)
797    

Legend:
Removed from v.1113  
changed lines
  Added in v.1895

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26